Keepalived脑裂本质是主备节点心跳中断后各自升主,导致VIP双绑;需通过三步交叉验证(VIP状态、VRRP抓包、客户端响应)确认,再以脚本降权止血,并排查防火墙、virtual_router_id、STP、内核参数四类根因。

Keepalived脑裂导致VIP两端同时绑定,本质是主备节点失去心跳共识后各自升主。这不是偶然故障,而是心跳链路、配置逻辑或网络策略存在系统性漏洞的信号。解决重点不在“谁先抢到VIP”,而在“如何让只有一个节点能合法持有VIP”。
立即止血:确认双VIP并人工干预
先执行三步交叉验证,避免误判:
- 在两台节点上同步运行
ip addr show | grep "inet.*VIP",若都显示UP状态且含相同 /32 子网掩码,即为真实双VIP; - 在备节点执行
tcpdump -i eth0 vrrp -n -c 5,30秒内无任何输出,说明VRRP报文已中断; - 从至少两个不同网段的客户端持续
curl -I http://VIP/health,观察响应头中的Server或后端日志时间戳是否不一致。
确认后,不建议直接重启 keepalived。优先通过预设脚本强制降权退服:echo "priority 50" > /etc/keepalived/keepalived.conf.d/force_backup.conf && systemctl reload keepalived
根因排查:聚焦四类高频诱因
80% 的双VIP由以下问题触发,按排查效率排序:
-
防火墙拦截VRRP协议:CentOS/RHEL默认禁用 vrrp 协议(非 udp/112),需显式放行:
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT -
virtual_router_id 不一致:主备配置中同一
vrrp_instance的virtual_router_id必须完全相同(1–255),差一个数字即各自成团; -
STP或交换机临时丢包:尤其在虚拟化环境,
ethtool eth0查 link 状态是否抖动;可临时改用单播模式替代组播; -
内核参数干扰:检查
net.ipv4.conf.all.accept_redirects = 0和net.ipv4.ip_forward = 0,非网关场景必须关闭转发。
生产加固:三重防御代替单点依赖
靠“不出错”不如建“出错也能收敛”。上线前必须部署:
-
单播替代组播:在
vrrp_instance块中添加unicast_src_ip 主节点IP和unicast_peer { 备节点IP },绕过交换机多播限制; -
健康脚本动态降权:在
vrrp_script中定义服务检测,失败时执行weight -20,确保即使心跳未断,业务异常也会自动让权; -
网关ping仲裁:添加独立脚本定期 ping 上游网关,连续失败则强制
systemctl stop keepalived,切断VIP抢占资格。
验证闭环:三重手段确认修复有效
改完配置不能只看 keepalived 启动成功,要实测收敛能力:
-
VIP绑定验证:手动停主节点 keepalived,观察备节点是否在
advert_int × 3秒内接管,且主恢复后不自动抢回(除非配置了preempt_delay); - VRRP抓包验证:在备节点抓包,确认仅收不发;主节点抓包,确认持续发送且源IP正确;
- 客户端分流验证:用两台跨网段机器持续 curl VIP 接口,响应应始终来自同一节点,Header 中 server 字段稳定不变。










