一、环境准备与基础规划
我手头有两台 CentOS 7.9 服务器,IP 分别是 192.168.1.10 和 192.168.1.11。它们将作为 Keepalived 的节点,对外提供一个虚拟 IP(VIP):192.168.1.100。业务层是 Nginx,两台机器都安装并设置好相同的 Nginx 服务,监听 80 端口。
我的目标是:当主节点(Master)宕机或 Nginx 进程异常退出时,备用节点(Backup)能自动接管 VIP,继续对外提供服务,实现故障自动切换。
二、安装与基础设置
安装 Keepalived 很简单,直接用 yum:
yum install -y keepalived
安装后,重点在于设置文件。Keepalived 的核心设置在 /etc/keepalived/keepalived.conf。我分别设置了主、备两台机器。
主节点(192.168.1.10)设置:
global_defs {
notification_email {
admin@example.com
}
notification_email_from keepalived@example.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_MASTER
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
track_script {
chk_nginx
}
}
备节点(192.168.1.11)设置:
global_defs {
notification_email {
admin@example.com
}
notification_email_from keepalived@example.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_BACKUP
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
track_script {
chk_nginx
}
}
关键点说明:
state:主节点为 MASTER,备节点为 BACKUP。priority:主节点优先级 100,备节点 90。数值越大,越可能成为 MASTER。virtual_router_id:同一个集群内必须一致。track_script:关联一个自定义脚本,用于检测 Nginx 进程状态。
三、核心排坑:Nginx 进程检测脚本
这是第一个大坑。很多新手会忽略 track_script 的作用,或者写一个不完善的检测脚本。我的脚本 /etc/keepalived/check_nginx.sh 内容如下:
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
systemctl start nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
exit 1
else
exit 0
fi
else
exit 0
fi
排坑点:
- 脚本权限:必须赋予执行权限,否则 Keepalived 无法调用。执行
chmod +x /etc/keepalived/check_nginx.sh。 - 脚本逻辑:我的脚本不是简单地“检测到 Nginx 挂了就通知 Keepalived 降权”,而是先尝试重启 Nginx。如果重启失败,才返回非零值,触发 Keepalived 切换。这样做的好处是,如果 Nginx 只是短暂异常,脚本能自动恢复,避免不必要的 VIP 漂移。
- weight 参数:我在设置中设置了
weight -20。当脚本返回非零时,Keepalived 会将当前节点的优先级减去 20。如果主节点优先级从 100 降到 80,而备节点是 90,那么备节点就会成为新的 MASTER,VIP 自动漂移。
四、启动与验证
设置完成后,启动 Keepalived:
systemctl start keepalived
systemctl enable keepalived
查看 VIP 是否在主节点上:
ip addr show dev eth0
正常情况下,主节点 eth0 上会出现 192.168.1.100。
验证故障切换:
- 手动停止主节点的 Nginx:
systemctl stop nginx。 - 观察日志:
tail -f /var/log/messages,会看到 Keepalived 检测到 Nginx 异常,尝试重启失败后,主动降低优先级,并通知备节点接管。 - 此时,在备节点上执行
ip addr show dev eth0,应该能看到 VIP 已经漂移过来。
五、第二个排坑点:网络边界防护与 ARP 问题
在验证过程中,我发现有时 VIP 无法 ping 通,或者客户端访问时断时续。排查后发现是网络边界防护规则和 ARP 广播问题。
解决方案:
- 网络边界防护放行:Keepalived 使用 VRRP 协议(IP 协议号 112),需要在网络边界防护中放行。执行:
firewall-cmd --add-rich-rule='rule protocol value="112" accept' --permanent
firewall-cmd --reload
- ARP 问题:当 VIP 漂移后,某些交换机或客户端可能还缓存了旧的 MAC 地址。可以在 Keepalived 设置中添加
garp_master_delay 和 garp_master_refresh 参数,强制发送免费 ARP 刷新缓存。
六、总结与最佳实践
经过这一轮搭建和排坑,我总结了几个关键点:
- 检测脚本是灵魂:不要只写一个简单的
killall -0 nginx,要包含自动恢复逻辑,避免误切换。 - 优先级设计要合理:主备优先级差要大于
weight 值,否则可能出现“脑裂”或反复切换。 - 网络层要打通:网络边界防护、交换机设置要提前规划,VRRP 协议必须放行。
- 日志是排坑利器:遇到问题先看
/var/log/messages,Keepalived 的日志非常详细。
最后,Keepalived 虽然经典,但并非万能。如果你的业务对数据一致性要求极高,或者需要跨机房容灾,建议结合 DNS 负载均衡或云原生方案。但对于大多数内部服务的高可用需求,Keepalived + Nginx 这套组合,依然是最简单、最可靠的方案之一。
希望这篇“排坑记”能帮你顺利搭建起自己的高可用集群。运维路上,坑多路远,但每填一个坑,都是一次成长。
👨💻 运维老兵经验:根据实际生产环境,以上步骤建议先在测试环境验证,并做好备份。参数值需根据服务器设置调整,不要盲目照搬。