You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Keepalived的track_script在HAProxy退出时不触发故障切换?

我之前在配置Keepalived+HAProxy+Galera的高可用集群时,完完全全碰到过和你一样的问题!当时盯着syslog一脸懵——明明脚本检测到HAProxy挂了,怎么VIP还牢牢占着不放手?后来翻了官方文档、踩了一堆坑才搞明白,这其实是对Keepalived的track_script逻辑理解有偏差,或者配置细节没到位。

问题原因分析

你遇到的核心问题,是对Keepalived的track_script工作逻辑理解有误:
默认情况下,track_script检测失败只会调整当前节点的优先级(priority),而不是直接强制切换到BACKUP状态或释放VIP。只有当当前节点的优先级低于集群中其他BACKUP节点的优先级时,才会触发主备切换,主动释放VIP。

从你的日志来看,脚本确实检测到HAProxy失败了,但你的节点优先级调整后,仍然比其他BACKUP节点高,所以Keepalived会继续保持MASTER状态,VIP自然不会被释放。

另外还有一种可能:如果你的BACKUP节点因为网络问题(比如VRRP组播不通、端口被防火墙拦截)收不到MASTER节点的通告,BACKUP节点会自己升为MASTER,导致双MASTER场景,这时候两个节点都会持有VIP,看起来像是原MASTER没释放。

解决方案

针对这个问题,我给你几个经过生产环境验证的解决办法:

1. 调整track_script的权重参数,确保失败后优先级低于BACKUP节点

这是最标准的解决方式,通过权重调整让HAProxy故障后的MASTER节点优先级低于BACKUP节点,触发自动切换。

举个配置示例:

# 定义检测HAProxy的脚本
vrrp_script check_haproxy {
    script "/usr/bin/pgrep haproxy"  # 检测HAProxy进程是否存在
    interval 2                       # 每2秒检测一次
    weight -30                       # 检测失败时,优先级降低30
}

# VRRP实例配置(MASTER节点)
vrrp_instance 250 {
    state MASTER
    interface eth0                   # 绑定的业务网卡
    virtual_router_id 250
    priority 120                     # MASTER初始优先级设为120
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.100/24            # VIP地址
    }
    track_script {
        check_haproxy                # 关联检测脚本
    }
}

# BACKUP节点的配置,注意优先级要设为100
vrrp_instance 250 {
    state BACKUP
    interface eth0
    virtual_router_id 250
    priority 100                     # BACKUP初始优先级低于MASTER
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.100/24
    }
    track_script {
        check_haproxy
    }
}

当HAProxy挂掉后,MASTER节点的优先级会从120降到90,低于BACKUP的100,这时候Keepalived会自动切换到BACKUP状态,释放VIP,BACKUP节点则会升为MASTER并接管VIP。

2. 结合自定义脚本,强制停止Keepalived(适用于单BACKUP场景)

如果你的集群只有一个BACKUP节点,或者希望HAProxy故障后直接让Keepalived停止(确保VIP完全释放),可以自定义检测脚本,在HAProxy故障时主动停止Keepalived服务。

步骤如下:

  1. 创建自定义检测脚本/usr/local/bin/check_haproxy.sh:
#!/bin/bash
# 检测HAProxy是否在运行
if ! pgrep haproxy > /dev/null; then
    # HAProxy未运行,停止Keepalived
    systemctl stop keepalived
    exit 1
fi
exit 0
  1. 给脚本添加执行权限:
chmod +x /usr/local/bin/check_haproxy.sh
  1. 修改Keepalived配置中的vrrp_script:
vrrp_script check_haproxy {
    script "/usr/local/bin/check_haproxy.sh"
    interval 2
    weight -30  # 保留权重调整,双重保障
}

这样当HAProxy挂掉后,脚本会主动停止Keepalived,节点会立即释放VIP,BACKUP节点会自动接管。

3. 排查网络问题,避免双MASTER场景

如果你的BACKUP节点也出现了Entering MASTER STATE的日志,那就是网络问题导致的双MASTER:

  • 检查防火墙是否开放了VRRP的通信端口(默认是UDP 112)
  • 确认节点之间的网卡支持组播(可以用ip maddr show eth0查看组播地址是否存在)
  • 检查interface配置的网卡是否正确,避免绑定到错误的网卡(比如lo或者VPN网卡)

内容的提问来源于stack exchange,提问作者Server Fault

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:22:35