Keepalived本質就是爲ipvs服務的,它也不須要共享存儲。IPVS其實就是一些規則,Keepalived主要的任務就是去調用ipvsadm命令,來生成規則,並自動實現將用戶須要訪問的地址轉移到可用LVS節點實現。因此keepalive的高可用是屬於具備很強針對性的高可用,它和corosync這種通用性HA方案不一樣。html
Keepalived的主要目的就是它自身啓動爲一個服務,它工做在多個LVS主機節點上,當前活動的節點叫作Master備用節點叫作Backup,Master會不停的向Backup節點通告本身的心跳,這種通告是基於VRRP協議的。Backup節點一旦接收不到Master的通告信息,它就會把LVS的VIP拿過來,而且把ipvs的規則也拿過來,在本身身上生效,從而替代Master節點。linux
Keepalived除了能夠監控和轉移LVS資源以外,它還能夠直接配置LVS而不須要直接使用ipvsadm命令,由於它能夠調用,也就是說在LVS+KEEPALIVED模型中,你全部的工做在Keepalived中配置就能夠了,並且它還有對後端應用服務器健康檢查的功能。算法
直接一句話Keepalived就是VRRP協議的實現,該協議是虛擬冗餘路由協議。後端
那麼這個VRRP協議是幹嗎用呢?傳統上來講咱們經過一個路由器上網,若是故障那就不能用了,若是使用2個路由器,有一個故障你就須要手動的設置客戶端切換到另外的路由器上,或者使用ARP客戶端也能夠實現,但總之部署比較麻煩不利於管理,就像下圖:緩存
有沒有一種辦法能夠自動轉移而省去手動配置呢?咱們就能夠經過VRRP協議來實現路由器的故障轉移。以下圖:bash
這裏有個問題,VRRP提供一個VIP,它能夠來設定那個路由器是活動節點,而後出現故障進行切換,VIP也隨之對應到新的路由器上,可是內網是用過MAC地址來尋址的,雖然VIP對應到了新的路由器上,但是MAC變了,客戶端的ARP表也沒有更新,因此仍是用不了,爲了解決這個問題VRRP不但提供VIP還提供VMAC地址,這個VMAC地址是VRRP單獨申請的,你們均可以正常使用。服務器
故障切換的時候雖然改變了後端路由器,可是因爲客戶端使用的是VIP和VMAC地址,這樣就不會有任何影響了。curl
因此Keepalived就是在Linux系統上提供了VRRP功能,固然還提供了服務監控功能,好比監控後端服務器的健康檢查、LVS服務可用性檢查。jsp
VRRP的工做過程是這樣的:tcp
VRRP還支持認證,就是爲了防止隨意一個VRRP設備加入到當前的虛擬路由組離來,它提供無認證、簡單8位字符串認證和MD5認證(該認證方式Keepalive不支持)。
Keepalived啓動後之後會有一個主進程Master,它會生成還有2個子進程,一個是VRRP Stack負責VRRP(也就是VRRP協議的實現)、一個是Checkers負責IPVS的後端的應用服務器的健康檢查,當檢測失敗就會調用IPVS規則刪除後端服務器的IP地址,檢測成功了再加回來。當檢測後端有失敗的狀況可使用SMTP通知管理員。另外VRRP若是檢測到另一個Keepalive失敗也能夠經過SMTP通知管理員。
Control Plane:這個就是主進程,主進程的功能是分析配置文件,讀取、配置和生效配置文件,指揮那2個子進程工做。
WatchDog:看門狗,這個是Linux系統內核的一個模塊,它的做用是幫助主進程盯着那2個子進程,由於主進程並不負責具體工做,具體工做都是子進程完成的。若是子進程掛了,那Keepalived就不完整了,因此那2個子進程會按期的向主進程打開的一個內部Unix Socket文件寫心跳信息。若是有某個子進程不寫信息了,它就會重啓子進程,主進程就是讓WatchDog來監控子進程的。下面咱們就使用Keepalive來作LVS的高可用講解。關於後端服務器上的設置我這裏就不說了請看另一篇博文。
服務器 | IP地址 | 角色 |
---|---|---|
Srv01 | 172.16.42.100 VIP: 172.16.42.111 |
LVS+Keepalive |
Srv02 | 172.16.42.101 VIP: 192.168.100.1 |
LVS+Keepalive |
Srv03 | 172.16.42.102 VIP: 172.16.42.111 |
Nginx |
Srv04 | 172.16.42.103 VIP: 172.16.42.111 |
Nginx |
禁用SElinux、清除iptables規則、關閉防火牆。就算因某種緣由不能清除iptables規則,那麼你須要增長一條規則放行多播
各個節點時間同步,啓用時間同步服務systemctl start chronyd
確保Keepalive使用的網卡開啓了多播,以下圖:
若是沒有開啓,可使用該命令打開ip link set multicast on dev ens33
,ens33是網卡名稱。
之間經過yum安裝便可yum install -y keepalived
。我這裏使用的是阿里雲的源,它默認就在裏面,以下圖:
在2個節點都安裝。
文件 | 說明 |
---|---|
/usr/sbin/keepalived | 二進制程序 |
/etc/keepalived/keepalived.conf | 配置文件 |
/usr/lib/systemd/system/keepalived.service | 服務文件 |
# 全局配置 global_defs { # 郵件通知信息 notification_email { # 定義收件人 acassen@firewall.loc } # 定義發件人 notification_email_from Alexandre.Cassen@firewall.loc # SMTP服務器地址 smtp_server 192.168.200.1 smtp_connect_timeout 30 # 路由器標識,通常不用改,也能夠寫成每一個主機本身的主機名 router_id LVS_DEVEL # VRRP的ipv4和ipv6的廣播地址,配置了VIP的網卡向這個地址廣播來宣告本身的配置信息,下面是默認值 vrrp_mcast_group4 224.0.0.18 vrrp_mcast_group6 ff02::12 } # 定義用於實例執行的腳本內容,好比能夠在線下降優先級,用於強制切換 vrrp_script SCRIPT_NAME { } # 一個vrrp_instance就是定義一個虛擬路由器的,實例名稱 vrrp_instance VI_1 { # 定義初始狀態,能夠是MASTER或者BACKUP state MASTER # 工做接口,通告選舉使用哪一個接口進行 interface ens33 # 虛擬路由ID,若是是一組虛擬路由就定義一個ID,若是是多組就要定義多個,並且這個虛擬 # ID仍是虛擬MAC最後一段地址的信息,取值範圍0-255 virtual_router_id 51 # 使用哪一個虛擬MAC地址 use_vmac XX:XX:XX:XX:XX # 監控本機上的哪一個網卡,網卡一旦故障則須要把VIP轉移出去 track_interface { eth0 ens33 } # 若是你上面定義了MASTER,這裏的優先級就須要定義的比其餘的高 priority 100 # 通告頻率,單位爲秒 advert_int 1 # 通訊認證機制,這裏是明文認證還有一種是加密認證 authentication { auth_type PASS auth_pass 1111 } # 設置虛擬VIP地址,通常就設置一個,在LVS中這個就是爲LVS主機設置VIP的,這樣你就不用本身手動設置了 virtual_ipaddress { # IP/掩碼 dev 配置在哪一個網卡 192.168.200.16/24 dev eth1 # IP/掩碼 dev 配置在哪一個網卡的哪一個別名上 192.168.200.17/24 dev label eth1:1 } # 虛擬路由,在須要的狀況下能夠設置lvs主機 數據包在哪一個網卡進來從哪一個網卡出去 virtual_routes { 192.168.110.0/24 dev eth2 } # 工做模式,nopreempt表示工做在非搶佔模式,默認是搶佔模式 preempt nopreempt|preempt # 若是是搶佔默認則能夠設置等多久再搶佔,默認5分鐘 preempt delay 300 # 追蹤腳本,一般用於去執行上面的vrrp_script定義的腳本內容 track_script { } # 三個指令,若是主機狀態變成Master|Backup|Fault以後會去執行的通知腳本,腳本要本身寫 notify_master "" notify_backup "" notify_fault "" } # 定義LVS集羣服務,能夠是IP+PORT;也能夠是fwmark 數字,也就是防火牆規則 # 因此經過這裏就能夠看出來keepalive天生就是爲ipvs而設計的 virtual_server 10.10.10.2 1358 { delay_loop 6 # 算法 lb_algo rr|wrr|lc|wlc|lblc|sh|dh # LVS的模式 lb_kind NAT|DR|TUN # 子網掩碼,這個掩碼是VIP的掩碼 nat_mask 255.255.255.0 # 持久鏈接超時時間 persistence_timeout 50 # 定義協議 protocol TCP # 若是後端應用服務器都不可用,就會定向到那個服務器上 sorry_server 192.168.200.200 1358 # 後端應用服務器 IP PORT real_server 192.168.200.2 1358 { # 權重 weight 1 # MSIC_CHECK|SMTP_CHEKC|TCP_CHECK|SSL_GET|HTTP_GET這些都是 # 針對應用服務器作健康檢查的方法 MISC_CHECK {} # 用於檢查SMTP服務器的 SMTP_CHEKC {} # 若是應用服務器不是WEB服務器,就用TCP_CHECK檢查 TCP_CHECK { # 向哪個端口檢查,若是不指定默認使用上面定義的端口 connect_port <PORT> # 向哪個IP檢測,若是不指定默認使用上面定義的IP地址 bindto <IP> # 鏈接超時時間 connect_timeout 3 } # 若是對方是HTTPS服務器就用SSL_GET方法去檢查,裏面配置的內容和HTTP_GET同樣 SSL_GET {} # 應用服務器UP或者DOWN,就執行那個腳本 notify_up "這裏寫的是路徑,若是腳本後有參數,總體路徑+參數引發來" notify_down "/PATH/SCRIPTS.sh 參數" # 使用HTTP_GET方法去檢查 HTTP_GET { # 檢測URL url { # 具體檢測哪個URL path /testurl/test.jsp # 檢測內容的哈希值 digest 640205b7b0fc66c1ea91c463fac6334d # 除了檢測哈希值還能夠檢測狀態碼,好比HTTP的200 表示正常,兩種方法二選一便可 status_code 200 } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } # 向哪個端口檢查,若是不指定默認使用上面定義的端口 connect_port <PORT> # 向哪個IP檢測,若是不指定默認使用上面定義的IP地址 bindto <IP> # 鏈接超時時間 connect_timeout 3 # 嘗試次數 nb_get_retry 3 # 每次嘗試之間間隔幾秒 delay_before_retry 3 } } real_server 192.168.200.3 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }
Srv01上的keepalived.conf
global_defs { notification_email { acassen@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id srv01 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.42.111/24 brd 172.16.42.111 dev ens33 label ens33:0 } preempt delay 60 }
Srv02上的keepalived.conf,惟一不一樣的就是state、priority以及router_id。
global_defs { notification_email { acassen@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id srv02 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.42.111/24 brd 172.16.42.111 dev ens33 label ens33:0 } preempt delay 60 }
啓動2個節點,啓動後會自動配置ens33:0這個子接口的虛擬IP
在主節點上你經過systemctl status keepalived
看不到它究竟是什麼角色,不過在BACKUP節點上你能夠看到,可是你在主節點日誌中cat /var/log/message
裏能夠看到Srv01進入到MASTER狀態,以下圖:
查看Srv02的狀態
那麼你經過中止Srv01上的keepalived服務就看到MASTER會被轉移到Srv02上。
使用該命令查看VRRP通告tcpdum -i ens33 -nn host 224.0.0.18
,你在2臺主機都會看到相同的信息。
Srv01使用真實物理IP對該地址進行發送通告,那麼Srv02也會收到,若是Srv01宕機,那麼Srv02就會使用本身的物理IP向該地址發送通告,因爲Srv01已經宕機那麼此時Srv02的優先級就是最高的,因此Srv02就變成了MASTER。
這裏只是用了LVS來講明如何配置Keepalived,若是要看完整內容請移步使用Keepalived構建LVS高可用集羣
在keepalived.conf文件中增長下面的內容,2臺服務器增長的內容一致,因此這裏就寫一份。
virtual_server 172.16.42.111 80 { delay_loop 6 lb_algo rr lb_kind DR nat_mask 255.255.255.0 persistence_timeout 0 protocol TCP sorry_server 192.168.200.200 1358 # 後端應用服務器 IP PORT real_server 172.16.42.102 80 { weight 1 # 應用服務器UP或者DOWN,就執行那個腳本 notify_up "/usr/local/notify.sh up" notify_down "/usr/local/notify.sh down" HTTP_GET { # 檢測URL url { path /index.html # 除了檢測哈希值還能夠檢測狀態碼,好比HTTP的200 表示正常,兩種方法二選一便可 status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 172.16.42.103 80 { weight 1 # 應用服務器UP或者DOWN,就執行那個腳本 notify_up "/usr/local/notify.sh up" notify_down "/usr/local/notify.sh down" HTTP_GET { # 檢測URL url { path /index.html # 除了檢測哈希值還能夠檢測狀態碼,好比HTTP的200 表示正常,兩種方法二選一便可 status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }
這裏的notify_up|down腳本我寫的很簡單就是爲了使用一下這個功能,內容以下:
#!/bin/bash # 不一樣的是2個主機上的echo部分不同,由於主機名不一樣。 if [ $1 == "up" ]; then echo "Srv02 is UP" > /tmp/notify.txt elif [ $1 == "down" ]; then echo "Srv02 is DOWN" > /tmp/notify.txt fi
重啓Keepalived服務以後你就能夠經過ipvsadm -Ln
查看ipvs規則了,這些規則在2臺服務器上都會有,以下圖:
測試訪問
使用下面的命令快速訪問for i in {1..20}; do curl http://172.16.42.111/ | grep "Srv0" --color ; done
能夠看到2臺服務器交替,由於咱們使用的rr調度算法。
連續訪問VIP,而後中止Srv01上面的keepalived服務,這就意味着Srv01也就是失去了VIP,而後觀察請求狀況以及是否觸發以前設定的腳本。
在Srv01上查看腳本執行狀況
查看Srv02上面的日誌