12.7.3 切换失败与脑裂处理
3. 切换失败与脑裂处理#
切换失败与脑裂是Keepalived运维中最具风险的问题之一,常见于网络抖动、心跳链路异常、配置不一致或健康检查误判。本节从现象识别、快速定位、恢复与预防四个维度展开,并给出可执行示例与演练练习。
3.1 典型现象与影响#
- VIP未漂移或重复漂移:主故障后备机未接管,或主备同时持有VIP。
- 业务访问间歇性失败:ARP表频繁变动,客户端连通性不稳定。
- 日志中频繁出现状态切换:MASTER/BACKUP状态反复切换。
- 双主脑裂:两台节点均宣称MASTER,导致流量被分流或冲突。
3.2 原理草图与判定思路#
判定原则:
- 只有一台应持有VIP;
- VRRP心跳必须双向可达;
- 健康检查结果必须稳定一致。
3.3 快速定位与诊断流程(含命令与解释)#
- 确认VRRP状态与VIP归属
# 查看本机是否持有VIP
ip a show dev eth0 | grep -w "192.168.10.100"
# 查看Keepalived状态
systemctl status keepalived -l
# 关键日志(不同发行版路径可能不同)
tail -n 200 /var/log/messages | egrep "VRRP|STATE|Keepalived"
解释:ip a确认VIP,status与日志确认状态切换频率与原因。
- 检查VRRP心跳链路
# 需要安装tcpdump(如未安装)
yum -y install tcpdump || apt -y install tcpdump
# 抓取VRRP包(协议号112)
tcpdump -i eth0 -nn proto 112
预期:可看到来自对端的VRRP广告包;若无包,排查防火墙、交换机多播策略或单播配置。
- 验证健康检查脚本
# 手动执行vrrp_script
bash -x /etc/keepalived/check_nginx.sh; echo $?
解释:返回码为0表示健康;非0则触发降权或切换。
- 检查优先级与抢占
grep -nE "priority|nopreempt|advert_int|virtual_router_id" /etc/keepalived/keepalived.conf
解释:主备virtual_router_id与advert_int必须一致;优先级高者为主,nopreempt禁抢占。
- 确认ARP与路由
# 查看VIP的ARP解析是否频繁变化
ip neigh show | grep 192.168.10.100
# 内核ARP参数检查
sysctl net.ipv4.conf.all.arp_ignore
sysctl net.ipv4.conf.all.arp_announce
解释:ARP抖动会导致客户端访问不稳定,需要按最佳实践设置ARP参数。
3.4 切换失败的常见原因与处理(含完整示例)#
- VRRP心跳被阻断
- 处理:放通协议112或改用单播
# firewalld放行VRRP(多播场景)
firewall-cmd --permanent --add-rich-rule='rule protocol value="vrrp" accept'
firewall-cmd --reload
- 健康检查误判
- 处理:优化脚本、设置合理超时
# /etc/keepalived/check_nginx.sh
#!/bin/bash
timeout 2 curl -sf http://127.0.0.1:8080/health >/dev/null
exit $?
# 授权与测试
chmod +x /etc/keepalived/check_nginx.sh
bash /etc/keepalived/check_nginx.sh; echo $?
- 优先级配置错误
# /etc/keepalived/keepalived.conf(主)
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 120
advert_int 1
nopreempt
virtual_ipaddress { 192.168.10.100/24 dev eth0 }
track_script { chk_nginx }
}
解释:主节点优先级应高;若使用nopreempt,主恢复后不抢占。
- VRRP参数不一致
# 快速比对两端配置关键字段
diff -u <(ssh master "grep -nE 'virtual_router_id|advert_int|priority' /etc/keepalived/keepalived.conf") \
<(ssh backup "grep -nE 'virtual_router_id|advert_int|priority' /etc/keepalived/keepalived.conf")
3.5 脑裂(双主)处理步骤(含命令)#
- 立即隔离异常节点
# 临时停止Keepalived(隔离节点)
systemctl stop keepalived
# 或临时下线网卡
ip link set eth0 down
-
确认业务主节点
- 以业务层主从状态为准(如数据库主、应用主)。
- 保证数据一致性优先。 -
清理残留VIP与ARP
# 移除错误节点VIP
ip addr del 192.168.10.100/24 dev eth0
# 刷新ARP(广播更新)
arping -U -I eth0 192.168.10.100 -c 3
- 恢复VRRP正常运行
# 修正配置后重启
systemctl restart keepalived
# 观察状态稳定
watch -n 1 'ip a show dev eth0 | grep 192.168.10.100'
3.6 预防策略与最佳实践(含配置示例)#
- 使用单播VRRP避免多播被限制:
vrrp_instance VI_1 {
unicast_src_ip 192.168.10.11
unicast_peer { 192.168.10.12 }
}
- 设置合理的
advert_int与脚本超时; - 关键链路监控与告警,结合Prometheus监控VIP与状态;
- 配置一致性管理:模板化、配置校验、自动化发布;
- 通过
track_interface与track_script增强状态判断; - 防脑裂机制:STONITH或外部仲裁(如kafka/etcd锁)参与仲裁。
3.7 现场处理清单(Checklist)#
- [ ] VIP是否存在于正确节点
- [ ] VRRP包是否收发正常
- [ ] 健康检查脚本返回是否正确
- [ ] 主备优先级与抢占策略是否一致
- [ ] 日志是否出现频繁切换
- [ ] ARP是否频繁变动
3.8 练习与演练(建议在测试环境)#
- 模拟VRRP阻断
# 临时丢弃VRRP(协议112)
iptables -I INPUT -p vrrp -j DROP
# 观察切换行为,再恢复
iptables -D INPUT -p vrrp -j DROP
- 模拟健康检查误判
# 临时让健康检查失败
mv /etc/keepalived/check_nginx.sh /etc/keepalived/check_nginx.sh.bak
# 观察状态变化后恢复
mv /etc/keepalived/check_nginx.sh.bak /etc/keepalived/check_nginx.sh
- 验证脑裂处理流程
- 人为让两台都持有VIP(停止一端VRRP后手动加VIP),再按“脑裂处理步骤”恢复。