docker下用keepalived+Haproxy實現高可用負載均衡叢集
先記錄下遇到的坑,避免之後忘了;
花時間最多去解決的一個題是:在docker下啟動haproxy服務後在這個docker服務內安裝keepalived無法ping通的問題,雖然最後也是莫名其妙就好了,但是加強了不少對docker的理解和還需深入學習的地方。
為什麼要用keepalived+haproxy實現docker下的高可用負載均衡?在不同環境下有哪些方式可以實現高可用負載均衡?
首先第一點,實現負載均衡並不是只有haproxy一箇中間件,網上還有很多方案是用keepalived+LVS等等,所以對於docker下的高可用負載均衡不一定只有keepalived+haproxy。只是本次我是基於之前搭建的pxc叢集進行繼續搭建的,所以用的是haproxy。
為什麼這裡強調的是docker、keepalived?
首先我們執行環境是docker,keepalived的作用是搶佔虛擬ip,docker環境下,映象內的網段外網是無法訪問的,所以我們需要一個外網在宿主機上對映到docker內的ip上,keepalived一方面可以對映ip到docker服務內,二可以在docker服務內強佔虛擬ip。所以在docker搭建負載均衡的多種方案中都常見會出現keepalived。
為什麼要搶佔虛擬ip?為什麼要用keepalived呢?
負載均衡中介軟體(haproxy,lvs)等等在實際中不可能只是單節點存在(單節點不需要keepalived),都要有冗餘設計,即叢集設計,和資料庫叢集不一樣的是,docker中實現負載均衡中介軟體的叢集是通過搶佔一個ip地址實現的,有主備和主主方式,雖然方式不一樣,但都有一個心跳檢測的共同點,在主節點搶佔虛擬ip時,主從節點上會有心跳檢測線,如果發現主節點心跳檢測連不上,則從節點會主動搶佔ip實現資料不中斷的冗餘機制;
總結描述:由於是在docker環境下,我們要搭建負載均衡叢集需要通過keepalived搶佔虛擬ip實現,二負載均衡功能需要haproxy中介軟體實現,所以本次我搭建的是一個在docker環境下高可用的負載均衡方案是:keepalived+haproxy。
haproxy具體方法:
下載docker映象; Docker pull haproxy 重新命名 docker tag docker.io/haproxy haproxy 刪除多餘映象 docker rmi docker.io/haproxy ftp上傳docker配置檔案,目錄自行定義,目錄對映根據定義目錄名對映 檢視配置檔案(需要編輯可編輯) cat haproxy.cfg 啟動建立docker-haproxy服務 docker run -it -d -p 4001:8888 -p 4002:3306 -v /data/haproxy/config:/usr/local/etc/haproxy --name haproxy01 --privileged --net=net1 --ip 172.20.0.07 haproxy 埠8888是監控頁面埠,3006是MySQL服務埠,引數都可以在配置檔案中調整 進入docker-haproxy服務 docker exec -it haproxy01 /bin/bash 啟用配置檔案(啟用完配置檔案才算是真的啟動了haproxy服務) haproxy -f /usr/local/etc/haproxy/haproxy.cfg 退出haproxy互動,回到宿主機 ctrl+D
haproxy配置資訊:
global
#工作目錄
chroot /usr/local/etc/haproxy
#日誌檔案,使用rsyslog服務中local5日誌裝置(/var/log/local5),等級info
log 127.0.0.1 local5 info
#守護程序執行
daemon
defaults
log global
mode http
#日誌格式
option httplog
#日誌中不記錄負載均衡的心跳檢測記錄
option dontlognull
#連線超時(毫秒)
timeout connect 5000
#客戶端超時(毫秒)
timeout client 50000
#伺服器超時(毫秒)
timeout server 50000
#監控介面
listen admin_stats
#監控介面的訪問的IP和埠
bind 0.0.0.0:8888
#訪問協議
mode http
#URI相對地址
stats uri /dbs
#統計報告格式
stats realm Global\ statistics
#登陸帳戶資訊
stats auth admin:abc123456
#資料庫負載均衡
listen proxy-mysql
#訪問的IP和埠(前面ip=0代表任何ip都可訪問)
bind 0.0.0.0:3306
#網路協議
mode tcp
#負載均衡演算法(輪詢演算法)
#輪詢演算法:roundrobin
#權重演算法:static-rr
#最少連線演算法:leastconn
#請求源IP演算法:source
balance roundrobin
#日誌格式
option tcplog
#在MySQL中建立一個沒有許可權的haproxy使用者,密碼為空。Haproxy使用這個賬戶對MySQL資料庫心跳檢測
option mysql-check user haproxy
server NODE1 172.20.0.2:3306 check weight 1 maxconn 2000
server NODE2 172.20.0.3:3306 check weight 1 maxconn 2000
server NODE3 172.20.0.4:3306 check weight 1 maxconn 2000
server NODE4 172.20.0.5:3306 check weight 1 maxconn 2000
server NODE5 172.18.0.6:3306 check weight 1 maxconn 2000
#使用keepalive檢測死鏈
option tcpka
要解釋配置檔案真的可以寫個單獨的說明,我這裡只說下連結資料庫的幾點,即option引數後面的;
NODE1+ip這個是指的PXC叢集的docker映象名和所制定的ip地址,這個要和資料庫叢集一致,後面的權重,最大連結數可以執行設定,也可以直接套用我的,其他的說明配置檔案中都有;可直接使用;最後在網頁上輸入宿主機IP+監控埠+/dbs即可進入監控頁面。
keepalived搭建:
keepalived的實現是要在docker服務內建立,最後宿主機中也要建立實現docker內外的連線;
docker服務內建立,我們需要進入到該服務並安裝keepalived
進入docker-haproxy服務
docker exec -it haproxy01 /bin/bash
更新update,安裝keepalived
apt-get update
apt-get install keepalived
安裝vim 安裝ifconfig命令 安裝ping
apt-get install net-tools
apt-get install iputils-ping
新建並寫入一個keepalived的配置檔案
vim /etc/keepalived/keepalived.conf
配置檔案資訊:
#取名為K1,可自定義
vrrp_instance VI_1 {
#定義節點屬性
state MASTER
#定義虛擬網絡卡
interface eth0
#定義組vriid
virtual_router_id 100
#定義權重
priority 100
#定義心跳檢測時間1秒
advert_int 1
#定義組使用者密碼
authentication {
auth_type PASS
auth_pass 123456
}
#定義docker內ip地址,必須要在和haproxy同一個網段
virtual_ipaddress {
172.20.0.100
}
}
啟動
service keepalived start
到這一步理論上就完事了,只需要在新建一個haproxy+keepalived組成叢集即可,在這裡我遇到一個坑是:
啟動keepalived後宿主機無法ping通用keepalived,報錯:
[[email protected] ~]# ping 172.20.0.8
PING 172.20.0.8 (172.20.0.8) 56(84) bytes of data.
From 172.20.0.1 icmp_seq=1 Destination Host Unreachable
From 172.20.0.1 icmp_seq=2 Destination Host Unreachable
解決方案:
大多數都是我把配置檔案沒寫對,重寫配置檔案,重啟服務;
這裡檢查能否ping通,需要看服務內你的配置檔案寫入的ip有沒有出現在docker的網絡卡上,具體方法是:
進入到docker服務內,不是在宿主機上哦,檢視配置檔案
[email protected]:/etc/keepalived# cat keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 100
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
172.20.0.100
}
}
如果配置檔案資訊都是正確的,通過ip a命令會顯示如當前docker服務有的網絡卡
[email protected]:/etc/keepalived# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
73: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:14:00:07 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.20.0.7/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe14:7/64 scope link
valid_lft forever preferred_lft forever
很明顯沒有我配置檔案中的172.20.0.100ip地址,代表配置檔案未生效,大多數配置檔案錯誤
停掉keepalived服務重新修改編輯後重啟
[email protected]:/etc/keepalived# service keepalived stop
[ ok ] Stopping keepalived: keepalived.
重啟服務
[email protected]:/etc/keepalived# service keepalived start
[ ok ] Starting keepalived: keepalived.
再次檢視docker服務的ip
[email protected]:/etc/keepalived# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
73: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:14:00:07 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.20.0.7/24 scope global eth0
valid_lft forever preferred_lft forever
這裡出現了我的配置檔案ip地址
inet 172.20.0.100/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe14:7/64 scope link
valid_lft forever preferred_lft forever
在服務內直接ping這個ip,發現能ping通,切換宿主機,也能ping通,解決問題
[email protected]:/etc/keepalived# ping 172.20.0.100
PING 172.20.0.100 (172.20.0.100) 56(84) bytes of data.
64 bytes from 172.20.0.100: icmp_seq=1 ttl=64 time=0.042 ms
64 bytes from 172.20.0.100: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 172.20.0.100: icmp_seq=3 ttl=64 time=0.060 ms
^C
最後,再新建一個haproxy再新增slave的keepalive,加入到master中,即完成負載均衡叢集的搭建。