1…脑裂模拟
1)开启防火墙(两台lb开启防火墙,都出现vip10.0.0.3)
[root@lb01 ~]# systemctl start firewalld.service
[root@lb01 ~]# ip addr | grep 10.0.0.3
inet 10.0.0.3/32 scope global eth0
[root@lb02 ~]# systemctl start firewalld
[root@lb02 ~]# ip addr | grep 10.0.0.3
inet 10.0.0.3/32 scope global eth0
2)做免密交互
[root@lb02 ~]# ssh-keygen
[root@lb02 ~]# ssh-copy-id 172.16.1.4
[root@lb02 ~]# ssh 172.16.1.4 'ip addr |grep 10.0.0.3'
inet 10.0.0.3/32 scope global eth0
[root@lb02 ~]# echo $?
0
[root@lb02 ~]# ssh 172.16.1.4 'ip addr |grep 10.0.0.3'
[root@lb02 ~]# echo $?
1
2.脑裂解决的办法
#如果发生闹裂,则随机kill掉一台即可
#在备上编写检测脚本, 测试如果能ping通主并且备节点还有VIP的话则认为产生了脑裂
[root@lb02 ~]# vim check_keepalive.sh
#!/bin/sh
vip=10.0.0.3
lb01_ip=172.16.1.4
while true;do
ssh $lb01_ip 'ip addr | grep 10.0.0.3' &>/dev/null
if [ $? -eq 0 -a `ip add|grep "$vip"|wc -l` -eq 1 ];then
echo "ha is split brain.warning."
else
echo "ha is ok"
fi
sleep 3
done
如下
[root@lb01 ~]# systemctl stop keepalived.service
重点:在备上执行脚本,两台lb显示脑列。如果关闭主的keepalived,则会显示OK。
[root@lb02 ~]# sh check_keepalivded.sh
ha is split brain.warning.
ha is split brain.warning.
ha is split brain.warning.
ha is ok
ha is ok
ha is ok
如果关闭lb01的eth0网卡,ifdown eth0,vip也就起不来。因为VIP绑定在eth0网卡上。这样就不会出现脑列了。
二、高可用keepalived
Nginx默认监听在所有的IP地址上,VIP会飘到一台节点上,相当于那台nginx多了VIP这么一个网卡,所以可以访问到nginx所在机器
但是…如果nginx宕机,会导致用户请求失败,但是keepalived没有挂掉不会进行切换,所以需要编写一个脚本检测Nginx的存活状态,如果不存活则kill掉keepalived
1.nginx故障切换脚本
[root@lb01 ~]# vim check_web.sh
#!/bin/sh
nginxpid=$(ps -ef | grep [n]ginx | wc -l)
#1.判断Nginx是否存活,如果不存活则尝试启动Nginx
if [ $nginxpid -eq 0 ];then
systemctl start nginx &>/dev/null
sleep 3
#2.等待3秒后再次获取一次Nginx状态
nginxpid=$(ps -ef | grep [n]ginx | wc -l)
#3.再次进行判断, 如Nginx还不存活则停止Keepalived,让地址进行漂移,并退出脚本
if [ $nginxpid -eq 0 ];then
systemctl stop keepalived
fi
fi
#给脚本增加执行权限
[root@lb01 ~]# chmod +x /root/check_web.sh
2.使用keepalived配置文件调用nginx切换脚本
1)配置抢占式时
#只需要在备节点配置
[root@lb02 ~]# vim /etc/keepalived/keepalived.conf
global_defs {
router_id lb02
}
#每5秒执行一次脚本,脚本执行内容不能超过5秒,否则会中断再次重新执行脚本
vrrp_script check_web {
script "/root/check_web.sh"
interval 5
}
vrrp_instance VI_1 {
state BACKUP
nopreempt
interface eth0
virtual_router_id 50
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
#调用计划的脚本
track_script {
check_web
}
}
补充
如果开启防火墙的情况下,怎么保证不脑列。
[root@lb01 ~]# systemctl start firewalld.service
[root@lb01 ~]# firewall-cmd --add-protocol=vrrp
2)配置非抢占式时
#配置非抢占式时,两边都要配置脚本
[root@lb02 ~]# scp check_web.sh 172.16.1.4:/root
#主节点也要配置
[root@lb01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id lb01
}
vrrp_script check_web {
script "/root/check_web.sh"
interval 5
}
vrrp_instance VI_1 {
state BACKUP
nopreempt
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
track_script {
check_web
}
}
.测试
将VIP所在机器nginx的配置文件修改错误
停止nginx
查看VIP是否切换