最近配置完Keepalived后,发现Keepalived是有可能存在脑裂问题的,于是查看学习一番。
先了解一下什么是脑裂(split-brain)。指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏。在笔者配置的数据库服务器上,详情请参考文章-Mariadb基于GTID的双主复制配置,因为自增ID配置配置不一样,使用在复制过程中不会有数据冲突,但是脑裂时就会有两份一样的数据。
那脑裂是什么原因产生的呢?最终的原因就是心跳消息传输故障。两台keepalived服务器之间的心跳信息是VRRP协议,使用组播地址224.0.0.18来传输,可以通过wireshark来捕捉,如下图。VRRP协议目前配置的是每两秒传输一次,这个参数可以在配置文件advert_int 2来控制。

总结下来有几个原因可能会导致心跳消息VRRP协议传输失败。
1、心跳线断开或连接心跳线的中间故障(交换机等);
2、设备故障,网卡及相关驱动存在问题;
3、 iptables防火墙阻挡IP或阻挡VRRP协议传输;
4、 virtual_router_id两端参数配置不一致;
但是发现检查脚本如出一辙,都是部署在备用节点上,然后检查ping vip和本机ip addr是否都存在VIP,如果都存在就是发生了脑裂。但是如果备机正常接管了vip,那么这个脚本就是失效了。而且在非抢占式、backup的节点上部署脚本那就不可用了。
先看看脚本内容,网上好几个文章都是一样的。
#!/bin/bash
# 检查脑裂的脚本,在备节点上进行部署
LB01_VIP=*
LB01_IP=*
LB02_IP=*
whiletrue
do
ping -c 2 -W 3$LB01_VIP&>/dev/null
if[ $?-eq0 -a `ip add|grep"$LB01_VIP"|wc -l`-eq1 ];then
echo "ha is brain."
else
echo "ha is ok"
fi
sleep 5
done
脚本中有两个命令ping 和ip add。 -a 代表and,条件与判断。那如果需要改写呢,主备节点我都要部署,都要监控,在主备节点切换时都能正常监控。那就需要用到我以前的文章-Linux怎么远程执行指令呢-SSH秘钥来完成。先上脚本。
#!/bin/bash
# 检查keepalived脑裂的脚本
LB_VIP=192.168.31.100
LB01_IP=192.168.31.76
#local host IP
LB02_IP=192.168.31.82
while true
do
ipstatus=`ssh $LB01_IP "ip addr|grep 192.168.31.100|wc -l"`
ping -c 2 -W 3 $LB_VIP &>/dev/null
if [ $? -eq 0 -a `ip add|grep "$LB01_VIP"|wc -l` -eq 1 -a $ipstatus -eq 1 ];then #echo "ha is brain."
sudo service keepalived stop
if [ $? -ne 0 ] ;then
echo $(date +'%Y-%m-%d %H:%M:%S')". split-brain error.but ACTION keepalived-stop failed." >>/etc/keepalived/action.log
else
echo $(date +'%Y-%m-%d %H:%M:%S')". split-brain error.ACTION keepalived-stop success." >>/etc/keepalived/action.log
fi
else
#echo "ha is ok"
keepalivedcheck=`ps -C keepalived --no-header | wc -l`
if [ $keepalivedcheck -eq 0 ] ;then
sudo service keepalived start
if [ $? -ne 0 ] ;then
echo $(date +'%Y-%m-%d %H:%M:%S')". split-brain normal,keepalived already stopped.but ACTION keepalived-start failed" >>/etc/keepalived/action.log
else
echo $(date +'%Y-%m-%d %H:%M:%S')". split-brain normal,keepalived already stopped.ACTION keepalived-start success" >>/etc/keepalived/action.log
fi
fi
sleep 5
done
细心的读者可能已经发现了,多了一个判断参数 ipstatus=`ssh $LB01_IP "ip addr|grep 192.168.31.100|wc -l"` ,即远程到另一台机器执行ip addr指令,检查是否托管了VIP。这个指令的前提就是需要配置SSH秘钥,这样这个脚本就不需要输入密码,直接执行了。接下来就是条件判断,两台机都托管VIP,能能够ping通vip,那么就得到脑裂的结果。
在职场情况下,需要判断keepalived进程是否存在, keepalivedcheck=`ps -C keepalived --no-header | wc -l` ,如果没有发生脑裂那么就要启动keepalived。当然在实际运用中,折磨来判断就有可能不断重启keepalived进程,需要根据具体情况修改脚本。
网友评论