Docker中部署Keepalived实现入口网关高可用,必须使用host网络模式和NET_ADMIN权限,确保VRRP报文可达;需配置一致的virtual_router_id、合理priority值,并通过vrrp_script健康检查Nginx/HAProxy服务状态,避免仅依赖进程存活判断。

用 Docker 跑 Keepalived + 入口网关(比如 Nginx 或 HAProxy),核心不是“把 Keepalived 塞进容器”,而是让它能真正接管宿主机网络、感知服务状态、并可靠漂移 VIP。关键在权限、网络模式和健康检查设计,不是简单启动两个容器就完事。
必须用 host 网络 + NET_ADMIN 权限
Keepalived 依赖 VRRP 协议发二层组播报文,必须直接操作宿主机网络栈。bridge 或 overlay 网络完全不可用。
- 启动容器时一定要加 --net=host 和 --cap-add=NET_ADMIN
- 不能挂载 /etc/keepalived 到只读路径,配置需可写(尤其日志或运行时状态)
- 容器内 interface 名称(如 ens33、eth0)必须与宿主机真实网卡名一致,否则 VRRP 报文发不出去
健康检查不能只看进程,要联动网关服务
Keepalived 默认只检测本机 keepalived 进程是否存活。但高可用入口网关的真正目标是:后端网关(Nginx/HAProxy)挂了,VIP 就得立刻切走。
- 在 keepalived.conf 里定义 vrrp_script,例如检测 Nginx 是否响应 HTTP 200 或端口是否通
- 脚本建议用 curl -I 或 timeout 3 bash -c "echo > /dev/tcp/127.0.0.1/80" 避免误判
- weight 设置为负值(如 -5),让健康失败时优先级自动低于备节点,触发主备切换
网关容器与 Keepalived 容器协同部署
推荐两种轻量可控方式,避免把 Nginx 和 Keepalived 打包进一个镜像(职责耦合、升级困难):
- 方案一(推荐):Nginx/HAProxy 用标准镜像(如 nginx:stable、haproxy:2.9),以 host 网络或自定义 bridge 暴露端口;Keepalived 单独容器,通过 127.0.0.1 检测本地网关端口
- 方案二:用 docker-compose 统一编排,但 Keepalived 容器仍需 host 网络,其他服务用默认 bridge,通过宿主机 localhost 通信
- 不要用 --link,已废弃;也不要用容器名解析 VIP,VRRP 不走 DNS
配置要点与避坑提醒
很多故障源于配置细节被忽略:
- 注释掉 vrrp_strict:不注释会导致 Keepalived 拒绝非严格 VRRP 格式报文,在 Docker+host 网络下常导致 VIP 不生效
- virtual_router_id 必须相同:主备节点该值必须一致(1–255),否则无法组成 VRRP 组
- priority 主节点 > 备节点:典型值如 101 vs 90,差值建议 ≥10,避免抖动
- virtual_ipaddress 的 CIDR 掩码要对:例如 192.168.10.100/24,掩码必须匹配宿主机所在子网,否则 ARP 不通


















