docker swarm高可用需三步:1.部署奇数个manager节点(推荐3或5个)实现raft共识;2.服务副本跨worker节点调度并加约束隔离;3.配置重启策略、滚动更新、健康检查及ingress网络,前置负载均衡器保障访问。

构建 Docker Swarm 高可用服务群,核心是让管理节点不单点、服务副本不集中、故障时自动恢复。它不依赖外部组件,靠原生 Raft 共识和声明式服务模型就能实现稳定运行。
多 Manager 节点部署(防止单点失效)
Swarm 的高可用根基在 Manager 层。Raft 协议要求奇数个 Manager 才能达成多数派共识,推荐生产环境至少 3 个(可容忍 1 个宕机),5 个更稳妥(容忍 2 个宕机)。
- 首节点执行
docker swarm init --advertise-addr=本机IP,获得初始集群和两个 token(manager/worker) - 其余 Manager 节点必须用
docker swarm join --token <manager_token> --advertise-addr=本机IP 主节点IP:2377</manager_token>加入 - 每个 Manager 的
--advertise-addr必须填自己真实 IP,否则其他节点无法反向通信 - 加入后用
docker node ls查看,Manager 列应显示Leader或Reachable,不可全为Unavailable
服务副本跨节点调度(避免局部雪崩)
即使 Manager 高可用,若所有服务副本都挤在同一个 Worker 上,该节点故障仍会导致服务中断。需主动控制分布策略。
- 创建服务时指定
--replicas N(如 3),Swarm 默认会尽量打散到不同节点 - 用约束条件强制隔离:
--constraint 'node.role==worker'防止调度到 Manager 节点 - 对关键服务加亲和性限制:
--constraint 'node.labels.zone!=prod-db'把应用与数据库错开物理节点 - 验证分布:运行
docker service ps <service-name></service-name>,确认每个任务(Task)的 NODE 列分散在不同主机名下
服务自愈与滚动更新配置(保障持续可用)
容器崩溃、节点离线、镜像升级这些日常事件,不能靠人工干预。要通过服务定义固化恢复逻辑。
- 设置重启策略:
--restart-condition any(任何退出都重启)或on-failure(仅非零退出码重启) - 启用滚动更新:
--update-parallelism 1 --update-delay 10s --update-order start-first实现零停机升级 - 添加健康检查(在镜像 Dockerfile 中):
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost/health || exit 1,Swarm 会据此自动替换不健康实例 - 对有状态服务,挂载命名卷并设置
--mount type=volume,source=dbdata,target=/var/lib/mysql,避免容器重建丢失数据
网络与外部访问加固(打通流量链路)
服务跑起来只是第一步,用户得能稳定访问。Swarm 内置的 Ingress 网络和 DNS 是基础,但生产环境还需外层兜底。
- 发布端口统一用
--publish published=80,target=80,Swarm 自动在所有节点开放 80 端口并做负载分发 - 外部流量建议前置一层负载均衡器(如 Nginx、HAProxy 或云厂商 ALB),将请求轮询转发到所有 Manager 和 Worker 的 80 端口
- 确保节点间开放必要端口:2377(TCP,管理通信)、7946(UDP/TCP,节点发现)、4789(UDP,overlay 网络)
- 避免使用
--publish mode=host,它绕过 Ingress,破坏跨节点负载均衡能力











