12.7.3 切换失败与脑裂处理

3. 切换失败与脑裂处理#

切换失败与脑裂是Keepalived运维中最具风险的问题之一,常见于网络抖动、心跳链路异常、配置不一致或健康检查误判。本节从现象识别、快速定位、恢复与预防四个维度展开,并给出可执行示例与演练练习。

3.1 典型现象与影响#

  • VIP未漂移或重复漂移:主故障后备机未接管,或主备同时持有VIP。
  • 业务访问间歇性失败:ARP表频繁变动,客户端连通性不稳定。
  • 日志中频繁出现状态切换:MASTER/BACKUP状态反复切换。
  • 双主脑裂:两台节点均宣称MASTER,导致流量被分流或冲突。

3.2 原理草图与判定思路#

文章图片

判定原则:
- 只有一台应持有VIP;
- VRRP心跳必须双向可达;
- 健康检查结果必须稳定一致。

3.3 快速定位与诊断流程(含命令与解释)#

  1. 确认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与日志确认状态切换频率与原因。

  1. 检查VRRP心跳链路
# 需要安装tcpdump(如未安装)
yum -y install tcpdump || apt -y install tcpdump

# 抓取VRRP包(协议号112)
tcpdump -i eth0 -nn proto 112

预期:可看到来自对端的VRRP广告包;若无包,排查防火墙、交换机多播策略或单播配置。

  1. 验证健康检查脚本
# 手动执行vrrp_script
bash -x /etc/keepalived/check_nginx.sh; echo $?

解释:返回码为0表示健康;非0则触发降权或切换。

  1. 检查优先级与抢占
grep -nE "priority|nopreempt|advert_int|virtual_router_id" /etc/keepalived/keepalived.conf

解释:主备virtual_router_idadvert_int必须一致;优先级高者为主,nopreempt禁抢占。

  1. 确认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 脑裂(双主)处理步骤(含命令)#

  1. 立即隔离异常节点
# 临时停止Keepalived(隔离节点)
systemctl stop keepalived

# 或临时下线网卡
ip link set eth0 down
  1. 确认业务主节点
    - 以业务层主从状态为准(如数据库主、应用主)。
    - 保证数据一致性优先。

  2. 清理残留VIP与ARP

# 移除错误节点VIP
ip addr del 192.168.10.100/24 dev eth0

# 刷新ARP(广播更新)
arping -U -I eth0 192.168.10.100 -c 3
  1. 恢复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_interfacetrack_script增强状态判断;
  • 防脑裂机制:STONITH或外部仲裁(如kafka/etcd锁)参与仲裁。

3.7 现场处理清单(Checklist)#

  • [ ] VIP是否存在于正确节点
  • [ ] VRRP包是否收发正常
  • [ ] 健康检查脚本返回是否正确
  • [ ] 主备优先级与抢占策略是否一致
  • [ ] 日志是否出现频繁切换
  • [ ] ARP是否频繁变动

3.8 练习与演练(建议在测试环境)#

  1. 模拟VRRP阻断
# 临时丢弃VRRP(协议112)
iptables -I INPUT -p vrrp -j DROP
# 观察切换行为,再恢复
iptables -D INPUT -p vrrp -j DROP
  1. 模拟健康检查误判
# 临时让健康检查失败
mv /etc/keepalived/check_nginx.sh /etc/keepalived/check_nginx.sh.bak
# 观察状态变化后恢复
mv /etc/keepalived/check_nginx.sh.bak /etc/keepalived/check_nginx.sh
  1. 验证脑裂处理流程
    - 人为让两台都持有VIP(停止一端VRRP后手动加VIP),再按“脑裂处理步骤”恢复。