盛樂標 周慶林

摘要??? 隨著云計算的發展,各行各業的業務也開始云化。隨著云端業務的增長,以虛擬機為基礎搭建的虛擬機集群也迅速增多。但是,某些軟件在虛擬機上的行為與在裸機上的行為卻存在差異。本文研究的Keepalived在虛擬機環境中的某些場景,會因為虛擬IP不能正常漂移而導致故障轉移失效。本文將詳細分析Keepalived虛擬IP漂移異常的原因,并提出一套可行的解決方案。
【關鍵詞】虛擬機 集群 高可用 Keepalived
在生產環境和對集群運行穩定性要求較高的環境里,一般都需要進行集群的高可用和負載均衡配置。實現負載均衡既有硬件方案也有軟件方案。硬件方案的成本較高,很多集群都采用了軟件方案。在軟件方案中,很多人選擇使用Keepalived與負載均衡軟件配合使用以達到集群的高可用和負載均衡。隨著虛擬化技術和云計算的發展,集群的構成也發生了變化,以前的集群一般是以服務器裸機來構建,但現在隨著業務的云化,很多集群實際上構建于虛擬機之上,也稱虛擬機集群。由于虛擬機不像裸機直接運行于服務器硬件之上,它的工作必須依賴hypervisor,因此在虛擬機環境中,某些軟件的行為也發生了變化。本文將主要研究Keepalived在部分虛擬機環境中虛擬IP不能自動漂移的問題。
1 研究虛擬機環境中Keepalived虛擬IP自動漂移的背景
在采用軟件方案建設高可用負載均衡集群時,我們一般會考慮Keepalived或Heartbeat與LVS、HAProxy、NGNIX等負載均衡軟件配合使用,以實現集群的高可用和負載均衡。以Keepalived為例,Keepalived負責負載均衡服務器的高可用,而負載均衡服務器上的負載均衡軟件則根據具體的負載均衡算法將訪問流量轉發至后端服務器。可以看出,Keepalived是訪問數據鏈中非常關鍵的一環,一旦Keepalived不能正常工作,即使負載均衡服務器和后端服務器工作正常,整個集群也無法正常提供服務。我們研究發現,在部分虛擬機集群中,Keepalived的虛擬IP自動漂移功能在某些情況下并不能正常工作。如今公有云得到了大力發展,很多在公有云平臺上建立的集群實際上都是基于虛擬機的虛擬機集群。該功能的失常,給虛擬機集群的正常運行帶來了很大的隱患。本文將分析該功能失常的原因,并給出具體的解決方案。
2 虛擬機環境中Keepalived虛擬IP漂移的行為分析
2.1 Keepalived工作原理
Keepalived是以虛擬路由冗余協議(Virtual Router Redundancy Protocol,VRRP)為基礎實現集群或多臺服務器高可用的軟件。Keepalived將一組服務器組成一個服務器組,在這組服務器里有一個Master節點,其它均為Backup節點。Master節點會獲得一個虛擬IP(VirtualIP,VIP),Backup節點沒有虛擬IP。Master節點正常工作時,會周期性地在同網段內發送VRRP組播(心跳包)。當Backup節點接收不到VRRP心跳包時,則認為Master節點發生故障,此時故障轉移機制開始工作。所有的Backup節點根據它們的優先級選出一個新的Master節點,原Master節點的虛擬IP漂移至新的Master節點繼續對外提供服務。Keepalived服務器上如果安裝了負載均衡軟件,還可以將來訪的流量分流至各個后端服務器。Keepalived的工作原理圖詳見圖1。
2.2 Keepalived節點環境
在我們的測試環境中,所有虛擬機的hypervisor均為VMwareESXi6.5。虛擬機中安裝的操作系統為CentOS7.4。Master節點的IP地址為192.168.2.6,Backup節點的IP地址為192.168.2.7,虛擬IP地址為192.168.2.5。Keepalived使用的網絡接口名稱為ens192。兩臺Keepalived節點的Keepalived軟件版本均為v1.3.5,另外還安裝了負載均衡軟件HAProxy,軟件版本均為1.5.18。Keepalived安裝完以后,進行相關配置,步驟如下:
(1)關閉CentOS的SELinux功能。
(2)將系統參數net.ipv4.ip_forward設置為1,以允許數據包轉發。
(3)由于Keepalived需要發送目的地為224.0.0.18的VRRP組播信息,因此在Keepalived節點添加相應的防火墻規則:
firewall-cmd --direct --permanent --add- rule ipv4 filter INPUT 0 --in-interface ens192 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add- rule ipv4 filter OUTPUT 0 --out-interface ens192 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload
(4)進行Keepalived的配置,配置文件如下:
! Configuration File for keepalived global_defs {
router_id main_router vrrp_lower_prio_no_advert true }vrrp_script check_haproxy {
script "/etc/keepalived/check_haproxy.sh" interval 3weight -2fall 10
rise 2
}vrrp_instance VI_1 { state MASTER interface ens192 virtual_router_id 51 advert_int 2 priority 101 authentication {
auth_type PASSauth_pass 6be37dc3b2c96197d1600c58 3e10ad1f
}
virtual_ipaddress { 192.168.2.5
}
track_script { check_haproxy
}
}
上述配置文件主要需要注意兩點,vrrp_instanceVI_1的state參數主節點設置為MASTER,備份節點設置為BACKUP,優先級參數priority主節點要高于備份節點,本文中主節點優先級為101,備份節點優先級為100。除了上述參數和router_id各自命名外,兩臺Keepalived節點其它參數的設置均一致。check_haproxy.sh是Keepalived的健康檢查腳本,主要用于檢測節點上HAProxy工作是否正常。
(5)啟動Keepalived服務。
2.3 虛擬IP不能自動漂移的故障特征
在兩臺Keepalived節點部署完成以后,我們進行了四組測試,測試結果如下:
(1)停止、啟動、重啟Keepalived服務,Keepalived故障轉移成功。
(2)重啟Network服務,Keepalived故障轉移成功。
(3)關閉或重啟其中一臺節點,Keepalived故障轉移成功。
(4)通過ifdown、ifup命令關閉和打開網絡接口(ifdownens192和ifupens192),Keepalived故障轉移失敗。
四組測試中,前三組Keepalived均成功地進行了故障轉移,將原Master節點的虛擬IP轉移至Backup節點,但是在第四組測試中,我們相繼使用ifdown和ifup命令關閉和打開網絡接口,Keepalived均不能進行故障轉移。
因為Keepalived通過VRRP協議實現故障轉移,我們通過在BACKUP節點運行tcpdump–iens192–nvrrp命令來查看成功進行故障轉移時VRRP心跳包的變化。下面是運行systemctlstopkeepalived.service命令前后tcpdump命令輸出的三條VRRP心跳包內容:
11:51:11.137727 IP 192.168.2.6 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 101, authtype simple, intvl 2s, length 20
11:51:12.023422 IP 192.168.2.6 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 0, authtype simple, intvl 2s, length 20
11:51:12.633406 IP 192.168.2.7 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 100, authtype simple, intvl 2s, length 20
我們發現在Keepalived服務被停止時,Master節點會發送一條含有信息prio0的VRRP心跳包,Backup節點收到該心跳包后隨即進行故障轉移。我們又嘗試了servicenetworkrestart命令,也可以正常收到包含prio0的VRRP心跳包。但是當我們使用ifdownens192命令關閉網絡接口時,異常情況發生了:ens192接口被禁用后,在Backup節點仍然可以正常、持續收到Master節點發送的VRRP心跳包(prio值非0),但此時Master節點的IP地址已經不可用(ens192上的兩條IP192.168.2.5、192.168.2.6均已丟失),而Master節點的Keepalived服務也因為獲取不到IP信息進入inactive(dead)狀態。由于Backup節點仍能持續收到Master節點發來的VRRP心跳包,因此Backup節點此時仍認為Master節點工作正常,導致虛擬IP不能漂移至Backup節點,故障轉移失效。
3 恢復虛擬IP自動漂移的解決方案
經過四組不同行為的測試,我們找到了虛擬機環境中虛擬IP不能完成自動漂移的根源,即Master節點的網絡接口被禁用后,該節點仍然持續向外廣播正常的VRRP心跳包。要解決這個問題,我們首先必須找出讓Master節點在網口被禁用后停止發送VRRP心跳包的方法。經過測試,發現如果在此時重啟Keepalived服務,Keepalived在幾秒鐘后會從active(running)狀態進入inactive(dead)狀態,但是在此間隙,它會向外廣播一條含有prio0的VRRP心跳包,Backup節點接收到該心跳包后成功獲取了Keepalived虛擬IP,故障轉移成功。
有了上面的發現,我們就比較容易通過Shell腳本自動化地恢復虛擬IP的漂移,完成故障轉移。其基本思路為:編寫一個周期性執行的Shell腳本放入cron定時任務,持續監控網絡接口ens192的狀態,如果發現該接口不可用,則重啟一次Keepalived服務;如果該接口恢復正常,再重啟一次Keepalived服務。該腳本的主要內容如下:
#!/bin/bash
source /root/.bashrc IP=192.168.2.6
step=2
for (( i = 0; i < 60; i=(i+step) )); do
date="`date '+%Y-%m-%d %H:%M:%S'`"
lost2=`ping -c 1 -w 1 $IP 2>&1` networkstate=`cat /etc/keepalived/
networkstate`
if [[ $lost2 == "connect: Network is
unreachable" ]]; thenif [[ $networkstate == "0" ]]; then
systemctl restart keepalived > / dev/null 2>&1
echo "1" > /etc/keepalived/ networkstate
fi
else
if [[ $networkstate == "1" ]]; then
systemctl restart keepalived > / dev/null 2>&1
echo "0" > /etc/keepalived/ networkstate
fi
fi
sleep $step done
exit 0
在該腳本按計劃(每兩秒執行一次)運行以后,我們再次測試了虛擬IP的漂移行為,發現虛擬IP的自動漂移恢復正常,Master節點與Backup節點間的故障轉移得到了完美解決。
4 結束語
很多集群采用了Keepalived的高可用方案。然而,在虛擬機集群環境中,在某些場景Keepalived的虛擬IP并不能正常漂移,從而導致了集群的高可用特性失效。本文通過研究虛擬機環境中Keepalived虛擬IP漂移異常的行為,找出了具體的解決方案,可以為高可用虛擬機集群的建設提供參考。
參考文獻
[1]祁偉.云計算:從基礎架構到最佳時間[M].清華大學出版社,2013.
[2]王理,姜新超.云計算環境下的基礎架構融合[J].信息系統工程,2013(11):32-35.
[3]ScottCarey.云計算2018年發展趨勢:無服務器計算、Kubernetes和供應商壟斷[N].計算機世界,2018-01-22(010).
[4]Hwang, Kai, Geoffrey C Fox, J. J Dongarra. Distributed and Cloud Computing: From Parallel Processing to the Internet of Things. Amsterdam: Morgan Kaufmann, 2012.
[5]汪海洋,凌永興,包麗紅,姚萌萌.基于keepalived的高可用性應用研究[J].電子技術,2014,43(07):21-24.