Keepalived主备选举由vrrp_script检测结果与priority共同决定,高priority节点须通过健康检查才能成为MASTER;否则按weight动态调权,结合advert_int和nopreempt控制切换行为。

在 Keepalived 中,主备角色的选举核心依据是 vrrp_script 检测结果与 priority(权重) 的组合逻辑,而非仅看 priority 数值大小。权重本身不直接决定“谁当主”,而是通过 VRRP 状态机与通告机制,在满足健康前提下参与选举。
priority 是选举的“入场门槛”,不是绝对胜负手
Keepalived 启动时,各节点先比较自身 priority:数值高的节点默认尝试成为 MASTER;但前提是它通过了所有 vrrp_script 的健康检查(即 script 返回 0)。若高 priority 节点的检测脚本失败(如返回非 0),其 priority 会被临时减去 fall 值(或按 track_script 配置的 weight 调整),可能低于低 priority 节点的当前有效值,从而让出 MASTER 角色。
- 例如:NodeA priority=100,script 检查 MySQL 失败 → priority 临时变为 100−30=70;NodeB priority=90,script 正常 → 有效 priority=90 → NodeB 成为 MASTER
- priority 必须为 1–255 之间的整数;MASTER 必须严格大于 BACKUP,相等时以 IP 地址大者胜(但不推荐依赖此行为)
track_script + weight 是动态调权的关键
仅靠静态 priority 无法应对服务波动。真实场景中需结合 track_script 动态调整 priority:
- 定义 vrrp_script 时用 weight -N(如 weight -20)表示检测失败时 priority 减去 N
- 用 weight +N 表示检测成功时额外增加 N(较少用,易引发震荡)
- 必须配合 rise 1 fall 1 等参数控制状态切换灵敏度,避免因瞬时抖动误切
advert_int 和 nopreempt 影响选举时机与抢占行为
priority 相同或接近时,以下配置会改变行为表现:
- advert_int:VRRP 通告间隔(秒)。值越小,状态同步越快,故障发现更及时,但会增加载荷
- nopreempt:设为 no(默认)时,高 priority 节点恢复后会立即抢占 MASTER;设为 yes 则一旦成为 BACKUP,即使 priority 更高也不会抢回,需手动干预或重启
- 注意:nopreempt 只在 state BACKUP 配置下生效;MASTER 节点不响应 nopreempt
常见误判:只改 priority 不配 script,等于没做高可用
很多配置错误源于忽略 health check 的联动性:
- 单纯把两台机器 priority 设为 100 和 90,但未定义任何 vrrp_script → 一旦主库宕机,备机仍认为自己“健康”,不会自动接管 VIP
- script 权限不足、路径错误、超时未设(timeout)、返回值未显式 exit 0/1 → 导致 Keepalived 误判状态
- 未在 vrrp_instance 中用 track_script 关联脚本 → priority 动态调整完全失效

















