Keepalived 高可用配置与故障排查
概述
Keepalived 是一个基于 VRRP(Virtual Router Redundancy Protocol)协议的高可用解决方案,主要用于实现服务器集群的故障转移和负载均衡。它通过监控服务状态并自动切换 VIP(Virtual IP)来保证业务连续性。
核心架构
- VRRP 协议:主备节点间的心跳检测机制
- VIP 管理:虚拟 IP 地址在主备节点间的自动漂移
- 健康检查:支持 TCP、HTTP、SSL、自定义脚本等多种检查方式
- 多层集成:可与 LVS、Nginx、HAProxy 等负载均衡器深度集成
生产环境配置示例
基础配置文件 (/etc/keepalived/keepalived.conf)
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
script_user root
enable_script_security
}
vrrp_script chk_haproxy {
script "/usr/local/bin/check_haproxy.sh"
interval 2
weight -2
fall 2
rise 1
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100/24 dev eth0 label eth0:1
}
track_script {
chk_haproxy
}
notify_master "/usr/local/bin/notify.sh master"
notify_backup "/usr/local/bin/notify.sh backup"
notify_fault "/usr/local/bin/notify.sh fault"
}
HAProxy 健康检查脚本 (/usr/local/bin/check_haproxy.sh)
#!/bin/bash
# Check if HAProxy is running and responding
if [ $(ps -C haproxy --no-headers | wc -l) -eq 0 ]; then
exit 1
fi
# Check if HAProxy port is listening
if ! nc -z 127.0.0.1 80; then
exit 1
fi
# Check HAProxy stats page
if ! curl -s --head http://127.0.0.1:8404/haproxy?stats | grep "200 OK" > /dev/null; then
exit 1
fi
exit 0
通知脚本 (/usr/local/bin/notify.sh)
#!/bin/bash
# Notify script for Keepalived state changes
STATE=$1
# Log state change
logger "Keepalived state changed to $STATE"
# Send notification via email or webhook
if [ "$STATE" = "MASTER" ]; then
echo "Keepalived became MASTER on $(hostname)" | mail -s "[ALERT] Keepalived MASTER" admin@example.com
elif [ "$STATE" = "BACKUP" ]; then
echo "Keepalived became BACKUP on $(hostname)" | mail -s "[INFO] Keepalived BACKUP" admin@example.com
fi
关键参数调优说明
| 参数 | 推荐值 | 说明 |
|---|---|---|
priority |
主节点:100-150,备节点:90-140 | 优先级越高越容易成为 MASTER,主备需有足够差距 |
advert_int |
1 | VRRP 广告间隔(秒),生产环境建议 1-3 秒 |
preempt_delay |
300 | 抢占延迟(秒),避免脑裂,建议 300 秒 |
nopreempt |
false | 是否禁用抢占,默认 false,主恢复后应自动接管 |
garp_master_delay |
5 | MASTER 启动后发送免费 ARP 延迟(秒) |
vrrp_garp_repeat |
5 | 免费 ARP 发送次数 |
监控命令
实时状态监控
# 查看 Keepalived 进程状态
systemctl status keepalived
# 查看 VRRP 状态
ip addr show | grep "192.168.1.100"
# 查看 Keepalived 日志
journalctl -u keepalived -f
# 查看 VRRP 详细状态
cat /proc/net/vrrp
# 查看 Keepalived 运行状态
killall -USR1 keepalived
故障排查步骤
检查网络连通性
# 检查 VRRP 组播通信 tcpdump -i eth0 vrrp # 检查防火墙是否放行 VRRP 协议 iptables -L INPUT | grep 224.0.0.18验证配置语法
# 检查配置文件语法 keepalived -t -f /etc/keepalived/keepalived.conf检查 VIP 分配
# 查看当前 VIP 分配情况 ip addr show | grep "inet.*192.168.1.100" # 手动添加/删除 VIP 测试 ip addr add 192.168.1.100/24 dev eth0 ip addr del 192.168.1.100/24 dev eth0检查健康检查脚本
# 手动执行健康检查脚本 /usr/local/bin/check_haproxy.sh # 检查脚本权限 ls -la /usr/local/bin/check_haproxy.sh
最佳实践
部署最佳实践
- 双网卡部署:使用专用心跳网卡(如 eth1)进行 VRRP 通信,避免业务流量干扰
- 配置同步:主备节点配置文件必须完全一致(除 priority 外)
- 时间同步:确保所有节点 NTP 时间同步,误差 < 100ms
- 资源隔离:Keepalived 进程使用独立用户运行,限制资源使用
- 日志轮转:配置 logrotate 管理 Keepalived 日志
安全最佳实践
- 认证密钥:使用强密码作为 auth_pass,定期轮换
- 脚本权限:健康检查脚本设置为 700 权限,仅 root 可读写执行
- 防火墙规则:仅允许 VRRP 组播地址 224.0.0.18 和端口 112
- SELinux:如启用 SELinux,确保 keepalived_t 类型正确配置
常见问题及解决方案
Q1:VIP 不漂移或漂移异常
原因:
- 主备节点 priority 设置相同
- 防火墙阻止 VRRP 组播通信
- 网络设备不支持组播或 IGMP Snooping 配置错误
解决方案:
- 检查 priority 配置,确保主节点高于备节点至少 10
- 在交换机上禁用 IGMP Snooping 或配置为兼容模式
- 使用 tcpdump 验证 VRRP 包是否正常收发
Q2:频繁切换(flapping)
原因:
- 健康检查过于敏感(interval 太小,fall/rise 值不合理)
- 网络抖动导致心跳包丢失
- 资源不足导致进程响应慢
解决方案:
- 调整 health check 参数:interval=3, fall=3, rise=2
- 增加 preempt_delay 到 300 秒
- 监控系统资源使用率,优化硬件配置
Q3:VIP 无法访问
原因:
- VIP 未正确绑定到接口
- ARP 缓存未刷新
- 后端服务未正常运行
解决方案:
- 检查 ip addr show 输出确认 VIP 绑定
- 在客户端执行 arp -d 清除 ARP 缓存
- 验证后端服务状态和端口监听
故障模拟与演练
模拟主节点故障
# 停止主节点 Keepalived
systemctl stop keepalived
# 观察备节点是否在 3 秒内接管 VIP
watch -n 1 "ip addr show | grep 192.168.1.100"
模拟网络分区
# 在主节点上阻断 VRRP 通信
iptables -A OUTPUT -d 224.0.0.18 -j DROP
iptables -A INPUT -s 224.0.0.18 -j DROP
# 观察是否出现脑裂现象
扩展场景
Keepalived + Nginx 高可用
# 在 Nginx 配置中添加健康检查
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
# Keepalived 监控 Nginx 进程
vrrp_script chk_nginx {
script "killall -0 nginx"
interval 2
weight -2
}
Keepalived + MySQL 主从切换
# MySQL 主从切换脚本
#!/bin/bash
# 在 notify_master 中调用
if [ "$1" = "master" ]; then
mysql -u root -p'password' -e "STOP SLAVE; RESET SLAVE ALL;"
mysql -u root -p'password' -e "CHANGE MASTER TO MASTER_HOST='192.168.1.11', MASTER_USER='repl', MASTER_PASSWORD='replpass'; START SLAVE;"
fi
性能基准测试
| 场景 | 响应时间 | 切换时间 | 备注 |
|---|---|---|---|
| 正常网络 | < 100ms | < 3s | 主备间 ping 延迟 < 1ms |
| 网络抖动 | < 200ms | < 5s | 丢包率 < 5% |
| 高负载 | < 300ms | < 8s | CPU 使用率 > 80% |
参考资料
- Keepalived 官方文档:https://www.keepalived.org/documentation.html
- VRRP RFC 5798:https://datatracker.ietf.org/doc/html/rfc5798
- Linux Virtual Server:https://www.linuxvirtualserver.org/