在 Docker 容器中配置 Keepalived 实现双机热备,需启用 NET_ADMIN 权限、正确设置 network 模式与 interface 名称,配置一致的 virtual_router_id 和 authentication,并集成服务健康检查脚本以避免脑裂。

在 Docker 容器中配置 Keepalived 实现双机热备,核心是让两个容器(或宿主机上的容器)协同管理一个虚拟 IP(VIP),主节点故障时 VIP 自动漂移到备用节点。关键不在容器是否“运行 Keepalived”,而在于网络权限、配置一致性与健康检查逻辑是否闭环。
容器必须启用特权模式并挂载网络能力
Keepalived 需要直接操作内核网络栈(如绑定 VIP、发送 VRRP 广播报文),普通容器默认被隔离。启动时必须显式添加:
- --privileged:授予容器完整 root 权限和设备访问能力
- --cap-add=NET_ADMIN:仅授权网络管理能力(比 privileged 更安全,推荐)
- --network host 或自定义 bridge 网络并指定 ipv4_address:确保容器能使用宿主机网卡(如 eth0)或固定 IP 参与 VRRP 通信
示例命令:
docker run -d --name keepalived-master --cap-add=NET_ADMIN --network mynet --ip 172.20.0.10 keepalived-img配置文件需适配容器网络环境
常见错误是照搬物理机配置,导致 interface 名称不匹配或 VIP 绑定失败。务必确认:
-
interface 值应为容器实际使用的网卡名(
ip a查看,Docker 默认常为eth0或ens33) - virtual_router_id 主备必须完全一致(0–255 范围内)
- priority 主节点设为 100+,备节点设为 90–99,差值建议 ≥10 避免脑裂
- authentication 密码必须相同,且 auth_type 推荐用 PASS(简单可靠)
-
virtual_ipaddress 写法需带子网掩码,如
172.20.0.100/24 dev eth0
精简可用的 master 配置片段:
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 {
172.20.0.100/24 dev eth0
}
}
必须集成服务健康检查,不能只靠 VRRP 心跳
VRRP 本身只检测网络连通性,不感知上层服务(如 Nginx、MySQL)是否真正可用。生产环境需结合脚本做主动探测:
- 在
vrrp_script中定义检查逻辑,例如:
vrrp_script chk_nginx {
script "/bin/sh -c 'curl -f http://127.0.0.1:80/health || exit 1'"
interval 2
weight -20
} - 在
vrrp_instance中引用:
track_script { chk_nginx } - 当检查失败,主节点 priority 自动降低,触发 VIP 切换
注意:脚本中 curl 需提前安装进镜像,或使用 busybox wget 替代。
验证与排错要点
启动后不要只看容器日志,重点验证三层:
-
网络层:在容器内执行
ip a | grep 172.20.0.100,确认 VIP 是否出现在 eth0 上 -
协议层:在另一台机器用
tcpdump -i eth0 vrrp抓包,观察主节点是否持续发 Advertisement - 应用层:停止主容器内 Nginx,等待 3–5 秒,立即检查备容器 VIP 是否出现,并能 curl 通
典型失败原因:防火墙拦截 VRRP 协议(IP protocol 112)、SELinux 限制、容器未挂载 /proc/sys/net/bridge、配置中 interface 名称写错。


















