12.4.1 主备切换机制与状态机
主备切换机制与状态机#
Keepalived 基于 VRRP 通过优先级与状态机完成主备选举与切换。实例启动进入 INIT,完成配置加载与接口初始化后转入 BACKUP 或 MASTER。MASTER 周期性发送 VRRP 广告,BACKUP 监听广告并在超时后触发选举或抢占。健康检查失败或接口异常会进入 FAULT 并释放 VIP。
原理草图(状态机与切换):
示例:安装与基础配置(含命令解释)
# 安装 keepalived(RHEL/CentOS)
yum -y install keepalived
# 安装 keepalived(Debian/Ubuntu)
apt-get -y install keepalived
# 启动并设置开机自启
systemctl enable --now keepalived
# 验证版本
keepalived -v
主备配置示例(完整可用,含关键参数)
文件:/etc/keepalived/keepalived.conf
global_defs {
router_id KA_NODE_A
vrrp_garp_interval 1
vrrp_gna_interval 1
}
vrrp_script chk_nginx {
script "/usr/local/bin/check_nginx.sh"
interval 2
weight -20
fall 2
rise 2
}
vrrp_instance VI_1 {
state MASTER # 本节点初始角色
interface eth0 # 绑定网卡
virtual_router_id 51 # VRRP 组ID
priority 150 # 优先级
advert_int 1 # 广告间隔(秒)
preempt_delay 5 # 抢占延迟
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.10.100/24 dev eth0
}
track_script {
chk_nginx
}
}
健康检查脚本示例(与权重联动切换)
文件:/usr/local/bin/check_nginx.sh
#!/usr/bin/env bash
# 检查 Nginx 进程,失败返回非0触发降权/切换
if pgrep -x nginx >/dev/null 2>&1; then
exit 0
else
exit 1
fi
chmod +x /usr/local/bin/check_nginx.sh
主备切换与 VIP 漂移验证(含预期效果)
# 查看 VIP 是否已绑定在 MASTER
ip addr show dev eth0 | grep 192.168.10.100
# 观察 VRRP 广告(MASTER 节点)
tcpdump -n -i eth0 vrrp
# 停止 keepalived 触发切换(MASTER 上执行)
systemctl stop keepalived
# 在 BACKUP 上确认 VIP 接管
ip addr show dev eth0 | grep 192.168.10.100
命令解释要点:
- priority:优先级越高越易成为 MASTER,范围 1–254。
- advert_int:广告发送间隔;BACKUP 约在 3 * advert_int 超时。
- nopreempt:禁止抢占,优先级更高的备机不夺主。
- preempt_delay:抢占延迟,避免短暂抖动。
- weight:健康检查权重,脚本失败降低优先级或进入 FAULT。
排错与诊断示例(含命令解释)
# 查看 keepalived 服务状态与最近日志
systemctl status keepalived
journalctl -u keepalived -n 100 --no-pager
# 检查 VIP 是否存在
ip addr show dev eth0
# 检查 VRRP 报文是否到达
tcpdump -n -i eth0 vrrp
# 检查脚本执行结果
/usr/local/bin/check_nginx.sh; echo $?
常见问题定位:
- 未切换:检查 advert_int、priority、nopreempt 与脚本权限。
- VIP 未漂移:检查网卡名、virtual_ipaddress、ARP 是否被过滤。
- 频繁切换:加大 preempt_delay,调整健康检查 fall/rise。
练习题(动手验证)
1. 将 BACKUP 的 priority 提高 30 并允许抢占,观察是否夺主。
2. 修改 advert_int=2,测算切换时间是否接近 6 秒。
3. 故意停止 Nginx,验证 weight 触发降级切换。