Docker Swarm 是 Docker Engine 内置的集群编排功能,适合希望以较低运维复杂度实现多主机部署、服务扩缩容和故障迁移的团队。它采用声明式服务模型:管理员定义副本数量、镜像和网络等目标状态,管理节点持续检查实际状态,并在节点异常时重新调度任务。本文从集群规划、部署上线到节点故障恢复,整理一套可直接实践的操作流程。🚀
一、部署前的架构规划
Swarm 节点分为 Manager 与 Worker。Manager 负责维护集群状态、调度任务和处理管理请求,Worker 负责运行服务任务。生产环境建议部署奇数个 Manager,例如 3 个或 5 个,以便维持 Raft 多数派。需要注意,增加 Manager 虽能提升容错能力,但也会增加状态同步开销,具体原则可参考 Docker 集群管理文档。
- Manager:建议使用固定 IP,并保持主机时间同步。
- Worker:根据业务负载配置,可按需横向增加。
- 网络:节点之间需放通 TCP 2377、TCP/UDP 7946 和 UDP 4789。
- 存储:数据库等有状态服务应使用可靠的外部存储或共享存储。
- 安全:只开放必要端口,并限制管理端口的访问来源。
Swarm 能迁移服务任务,但不会自动迁移节点本地磁盘中的业务数据。有状态服务必须提前设计数据复制、备份与恢复方案。
二、初始化 Swarm 集群
首先在计划作为首个 Manager 的服务器上安装 Docker Engine,并确认各节点的 Docker 版本兼容。随后执行:
docker swarm init --advertise-addr 192.168.10.11
--advertise-addr 应填写其他节点能够稳定访问的固定地址。初始化成功后,Docker 会输出 Worker 加入集群所需的命令与令牌。若之后需要重新查看,可运行:
docker swarm join-token worker
docker swarm join-token manager
在 Worker 上执行输出的 docker swarm join 命令即可入群。如果要构建高可用控制面,可让另外两台服务器使用 Manager 令牌加入。完成后,在任意 Manager 上运行 docker node ls,检查各节点是否为 Ready,并确认 Manager 状态中存在一个 Leader。
三、创建网络并部署服务
跨主机通信通常使用 Overlay 网络。创建业务网络的命令如下:
docker network create --driver overlay app-net
部署无状态 Web 服务时,可先创建 3 个副本,并发布访问端口:
docker service create --name web --replicas 3 --network app-net --publish 8080:80 nginx:stable
执行 docker service ls 可查看副本完成情况,执行 docker service ps web 可检查任务被分配到了哪些节点。Swarm 的路由网格能够让外部请求通过任一可用节点的已发布端口进入服务。关于服务发现、负载均衡和期望状态协调机制,可查看 Swarm 模式说明。
使用 Stack 管理多服务应用
实际项目通常包含前端、接口、缓存和消息组件,建议通过 Compose 格式的配置文件统一管理,然后执行 docker stack deploy -c compose.yml demo。上线后使用 docker stack services demo 查看服务状态,使用 docker stack ps demo 定位失败任务。配置文件应纳入版本控制,但密码、证书和令牌不要直接写入仓库,可使用 Swarm Secret 管理敏感内容。🔐
四、Worker 节点故障恢复
当 Worker 宕机或网络中断时,Manager 会发现该节点不可达,并尝试在其他可用节点上重建受影响的服务副本。管理员应先运行 docker node ls 判断节点状态,再使用 docker service ps 服务名 检查任务是否已经迁移。
- 检查故障主机的电源、网络、磁盘空间和 Docker 服务状态。
- 确认其他节点具备足够的 CPU、内存、端口和镜像拉取能力。
- 修复主机后启动 Docker,观察节点是否自动恢复为 Ready。
- 如果原节点身份损坏,可在 Manager 上删除旧节点,再使用新的加入令牌重新入群。
- 验证服务副本、健康检查、日志以及外部访问是否恢复正常。
计划维护时不要直接关机,应先执行 docker node update --availability drain worker01。Drain 会停止该节点上的 Swarm 服务任务,并在其他 Active 节点上创建替代任务,但不会影响通过 docker run 或 Compose 单独启动的容器。维护完成后执行 docker node update --availability active worker01,相关行为可参考 节点排空说明。🛠️
五、Manager 故障与仲裁恢复
Manager 使用 Raft 共识维护集群状态,因此必须保留多数派。例如 3 个 Manager 最多允许同时失去 1 个,5 个 Manager 最多允许同时失去 2 个。如果失去多数派,现有任务可能继续运行,但服务更新、任务调度和节点管理等操作将无法正常进行。
单个 Manager 故障且仲裁仍存在时,应先修复主机;如果节点无法恢复,可使用 docker node rm 节点名 清理旧记录,再让新节点以 Manager 身份加入。若确认旧节点永久离线,可在必要时增加新的 Manager,恢复合理的奇数节点规模。
当所有可恢复的 Manager 均无法组成多数派时,只能选择一台保存了较完整 Swarm 状态的 Manager,执行 docker swarm init --force-new-cluster --advertise-addr 固定IP 重建单节点控制面,再逐步加入其他 Manager。该操作会改变集群成员关系,执行前应备份 /var/lib/docker/swarm,并确认没有其他旧 Manager 继续对外提供管理入口,避免产生状态冲突。⚠️
六、提升集群可恢复性的实践
- 定期备份 Manager 的 Swarm 状态目录,并演练恢复流程。
- 为服务配置健康检查、资源限制、重启策略和滚动更新策略。
- 设置节点标签与部署约束,避免关键副本集中在同一故障域。
- 监控节点可用性、任务失败、磁盘容量、容器重启次数和证书状态。
- 发布前确认剩余节点容量,避免故障迁移后因资源不足导致副本无法启动。
- 更新令牌或人员变动后及时轮换加入令牌,降低凭据泄露风险。
总结
Docker Swarm 的部署并不复杂,真正影响稳定性的关键在于固定的 Manager 地址、合理的仲裁节点数量、充足的故障迁移容量以及可靠的数据存储。日常维护应优先使用 Drain 平滑迁移任务,Worker 故障重点检查副本重建,Manager 故障则必须先判断仲裁是否仍然存在。只有把监控、备份和恢复演练纳入常规运维,才能让自动调度能力真正转化为可验证的业务可用性。✅