盛乐标 周庆林
摘要 随着云计算的发展,各行各业的业务也开始云化。随着云端业务的增长,以虚拟机为基础搭建的虚拟机集群也迅速增多。但是,某些软件在虚拟机上的行为与在裸机上的行为却存在差异。本文研究的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.