聊到 Docker Swarm,很多人第一个想到的是docker swarm init那行命令,敲完就觉得集群起来了。但真正把 Swarm 用在生产环境之后,你会发现有个词贯穿始终,那就是 Mode。集群怎么组、服务怎么调度、更新怎么推进、故障怎么切换,背后全是 Mode 在起作用。这篇是 Docker Swarm 架构拆解系列的第一篇,先把这个最基础也最容易被忽略的概念彻底讲透。
这个系列面向的是准备把 Swarm 用于实际业务的开发、运维和架构师,也适合刚接触容器编排、想搞清楚 Swarm 和单机 Docker 到底差在哪的人。读完你不仅能分清 Swarm Mode、Service Mode、Update Mode 这些术语,还能直接在命令行里完成集群初始化、服务部署和更新回滚的完整流程。我尽量把参数背后的原因也讲清楚,而不是只给一个“能跑就行”的配置。
1. Mode 到底指什么:先看清 Swarm 的三种“模式”
1.1 集群模式:把多台机器变成一台逻辑主机
Mode 在 Docker 世界里最先指的就是 Swarm Mode,也就是 Docker Engine 的集群运行模式。默认情况下,Docker 以单机模式运行,你敲docker run、docker ps操作的都是本机容器,所有资源只属于当前这台机器。而开启 Swarm Mode 之后,多台机器的 Docker 守护进程会组成一个集群,容器调度、网络互通、配置分发都由集群统一管理,对外看起来就像一台更大的“逻辑主机”。
这个转换不是靠安装额外组件实现的,而是 Docker Engine 自带的集群能力。你只需要在某一台机器上执行docker swarm init,当前节点就会成为管理节点(Manager Node),然后生成一串 join token,其他机器拿着 token 执行docker swarm join就能加入集群。整个过程不需要单独部署 etcd 或者 Consul,因为 Swarm 内置了 Raft 共识算法来维护集群状态。
判断当前机器是否处于 Swarm Mode,最直接的方式是执行docker info,看输出的Swarm字段。如果显示active,说明这台机器的 Docker 守护进程已经运行在集群模式下;如果显示inactive,则是普通的单机模式。我见过不少同事在排查问题时,先跑docker node ls,然后报错说找不到节点,最后发现根因是这台机器压根没启用 Swarm Mode。
提示:Swarm Mode 不是独立于 Docker Engine 的进程,它是引擎的一种运行状态。同一套 Docker 命令在单机模式和集群模式下行为会不一样,尤其是网络、存储和负载均衡相关的操作。
1.2 服务模式:定义副本跑在哪、跑多少
集群搭好之后,你不再用docker run直接启动容器,而是通过docker service create创建服务。服务(Service)是 Swarm 里的调度单元,它定义了容器镜像、环境变量、端口映射,以及最重要的——任务调度模式(Deployment Mode)。这里 Mode 的第二个含义就出现了:服务是以副本模式(replicated)还是全局模式(global)运行。
副本模式是默认值,你在命令里指定--replicas 3,Swarm 就会在集群里挑选三台空闲节点,各跑一个任务副本。指定--replicas 5就五个副本,Swarm 负责保证任何时刻集群里正好有五个副本在运行。全局模式则完全不同,它不关心副本数量,而是保证集群里每一台满足条件的节点上都运行一个任务。你创建一个 global 服务,Swarm 会自动在所有节点上部署,后续新节点加入集群时,这个服务也会自动在该新节点上启动。
这两种模式的选择直接影响服务的伸缩性、资源分布和故障恢复行为。比如日志采集器、监控探针这类“每台机器都应该有一个”的组件,天然适合 global 模式;而业务 API、数据库这类按流量伸缩的组件,则应该用 replicated 模式来控制副本数。
1.3 更新模式:发布新版本时如何替换任务
Mode 的第三个应用场景是服务更新。当你要把镜像从 v1 升级到 v2 时,docker service update会按一定的策略替换正在运行的任务,这套策略就是更新模式(Update Mode)。Swarm 支持滚动更新(rolling update),你可以控制每次同时替换几个任务(--update-parallelism),以及每批替换之间的间隔时间(--update-delay)。
更新模式是生产环境里最容易出事的地方。很多人第一次做滚动更新,把 parallelism 设成 10,delay 设成 0,结果一瞬间所有旧版本容器都被拉起来的新版本替换,如果新镜像有问题,整个服务直接不可用。后面我会用实际命令演示如何配置更新模式,以及如何设置失败自动回滚。
2. 从零进入 Swarm Mode:初始化与节点接入实操
2.1 初始化管理节点并理解端口与地址参数
我一般在一台干净的 Linux 服务器上开始搭建 Swarm 集群,Ubuntu 22.04 搭配 Docker Engine 24.x 是我用得比较稳的组合。初始化命令非常简单:
docker swarm init --advertise-addr 192.168.1.10 --listen-addr 192.168.1.10:2377--advertise-addr是告诉集群里的其他节点:要连接我这个管理节点,请访问这个 IP 地址。如果机器有多块网卡,这个参数特别关键,不指定的话 Docker 会自动检测,但自动检测经常选错网卡,导致其他节点无法加入。比如机器上同时有内网 IP 192.168.1.10 和公网 IP 203.0.113.5,如果你的集群只在内网通信,就明确写成内网 IP,否则节点 join 时会被拒。
--listen-addr是当前节点监听集群通信的地址和端口,默认是 0.0.0.0:2377。2377 是 Swarm 集群管理通信的专用端口,用于节点间的心跳、Raft 日志同步和领导选举。如果你启用了防火墙,务必放通 TCP 2377,另外还要放通 UDP 7946(节点间 gossip 协议)和 TCP/UDP 4789(VXLAN 数据面通信)。我踩过最典型的坑就是只放了 2377,节点能加入集群,但 overlay 网络里的容器互相 ping 不通,折腾半天才发现是 4789 被防火墙拦了。
执行完初始化之后,命令行会输出两段 join token,一个是管理节点的,一个是工作节点的。注意保存好,后面扩展集群全靠它。
2.2 工作节点接入与节点角色验证
工作节点的接入命令更简单,在另一台机器上执行:
docker swarm join --token SWMTKN-1-xxxxx 192.168.1.10:2377其中SWMTKN-1-xxxxx就是初始化时输出的 worker token。加入成功之后,回到管理节点执行docker node ls,你会看到类似下面的输出:
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION abcdef123456 node01 Ready Active Leader 24.0.7 ghijkl789012 node02 Ready Active Reachable 24.0.7 mnopqr345678 node03 Ready Active 24.0.7MANAGER STATUS列显示 Leader 或 Reachable 的节点就是管理节点,工作节点这里为空。AVAILABILITY列显示 Active 表示节点正常接收任务分配,Drain 表示排空状态、不再接收新任务但保留已有任务。生产环境维护节点时,把节点切到 Drain 是所有运维都应该养成的好习惯。
我平时验证集群是否健康会依次跑三个命令:docker node ls看节点状态、docker service ls看服务状态、docker network ls看网络是否正常。任何一个环节异常都能快速定位是大方向的问题。
2.3 节点退出与集群重置的常用操作
节点要退出集群,用docker swarm leave。工作节点执行docker swarm leave之后,管理节点上还要执行docker node rm <node-id>把节点记录彻底删掉。注意顺序很重要,如果节点已经失联,docker node rm可能会报错,需要加上--force。管理节点退出不能用简单的 leave,因为管理节点退出会导致集群可用性下降,尤其是只剩一个管理节点时,直接 leave 它等同于解散集群。正确做法是先docker node demote <node-id>把它降级为工作节点,再让它 leave。
如果你想把整个集群推倒重来,在每台节点上执行docker swarm leave --force,然后把/var/lib/docker/swarm目录清掉(通常重置 Docker 环境时会用到),最后重新 init 就行。这个操作会丢失集群所有状态,包括服务定义和加密密钥,不是特殊情况不要碰。
2.4 初始化时容易忽略的高可用配置
初始化单节点 Swarm 也能跑,但如果你准备部署生产业务,我强烈建议至少准备三台管理节点。原因在于 Swarm 用 Raft 协议管理集群状态,管理节点之间需要达成多数派共识(quorum)才能对外提供服务。三台管理节点的多数派是 2 台,两台宕机之后集群仍然能正常调度;如果只有 1 台管理节点,这台宕机整个集群控制面就瘫痪了,虽然运行中的服务不会立刻停止,但你无法发布新服务、无法扩缩容、无法更新配置。
管理节点数量建议保持奇数,2 台和 4 台都不合适。4 台管理节点和 3 台管理节点的容错能力完全一样,都最多只能挂 1 台,但 4 台意味着每次共识需要更多节点参与,性能和复杂度都更高。这个原则跟 etcd、ZooKeeper 集群的选型逻辑是一样的。
我实际搭建三节点集群时的顺序是:node01 上docker swarm init,node02 和 node03 都加入为管理节点(join 时使用 manager token),然后验证docker node ls里有三台 MANAGER STATUS 非空的节点。整个过程不超过两分钟,但换来的高可用等级完全不同。
3. 部署模式二选一:replicated 与 global 的架构取舍
3.1 两种调度模式的运行逻辑差异
创建服务时的--mode参数决定了调度器如何分发任务。默认是replicated,调度器根据你指定的副本数量,在集群内寻找合适的节点放置任务。它会综合考虑节点资源、节点标签、端口占用等因素。而global模式忽略副本数量,调度器会在每一台 AVAILABILITY 为 Active 的节点上都放置一个任务,新节点加入集群时会自动补上,节点被 Drain 或离开集群时自动移除。
我用生活中的例子来解释:replicated 模式就像外卖平台派单,你点了 3 份订单,调度后台分给 3 家店铺各自做 1 份,具体分给哪家店铺取决于哪家空闲、哪家配送范围合适;global 模式则像小区里的垃圾桶,不管小区大小,每一栋楼楼下都必须放一个,新楼盖起来自动补上,楼拆除后垃圾箱也跟着撤走。
这个差异在故障恢复场景下的行为也不同。replicated 服务某节点宕机后,Swarm 会在其他健康节点上重新调度一个副本,维持总副本数不变;global 服务某节点宕机后,Swarm 不会在其他节点上新增任务,因为 global 保证的是“每一台节点一个任务”,这台节点没了任务自然就没了,等节点恢复后任务会自动回来。
3.2 创建与验证 replicated 和 global 服务
下面我在一个三节点集群里分别创建两种模式的服务,让大家直观感受区别:
# 创建 3 副本的 Nginx 服务,模式为 replicated(默认) docker service create --name web-rep --replicas 3 --publish published=8080,target=80 nginx:1.24-alpine # 创建全局模式的 Nginx 服务 docker service create --name web-global --mode global --publish published=8081,target=80 nginx:1.24-alpine然后查看任务分布:
docker service ps web-rep输出里你会看到三个任务,分散在不同节点上,NAMES 列类似web-rep.1.xxxxx、web-rep.2.xxxxx、web-rep.3.xxxxx。
再看全局服务:
docker service ps web-global输出里同样有三个任务,但分别落在三台节点上,而且是每台节点各一个。如果你之后又加入第四台节点,不需要任何手动操作,Swarm 会自动在第四台上启动一个 web-global 任务。这是 global 模式最有用的特性。
3.3 生产环境选型建议:监控采集用 global,业务应用用 replicated
我常用的选型原则可以用一句大白话概括:凡是你希望“每台机器都有那么一个”的东西,用 global;凡是需要按流量伸缩、精细控制数量的东西,用 replicated。
最典型的 global 应用是监控采集器。比如部署 Prometheus 的 node-exporter,你期望每一台 Swarm 节点上都跑一个实例采集主机指标,节点扩容后监控自动覆盖新机器,节点下线后采集任务自动消失。用 global 模式,整个集群的监控覆盖不需要任何手动干预。再比如日志采集 agent,类似 Filebeat 或 fluentd,也是每台节点都得有的组件,同样适合 global。
replicated 模式则适用于所有无状态业务服务,比如 Web 前端、API 网关、消息消费者。它们需要根据业务流量灵活调整副本数,用docker service scale命令就能热伸缩。特别注意一点,有状态服务(比如 MySQL)虽然通常也用 replicated,但不能随便 scale 到多副本,因为数据一致性不是 Swarm 帮你解决的。我在实际项目中直接用 Swarm 跑 MySQL 的场景很少,一般只用 single-replica 的方式把 MySQL 作为服务托管起来,真正的多副本和高可用交给数据库层方案(比如主从复制、半同步复制)去处理。
还有一种针对有状态服务更优的调度方式是把服务约束到指定节点上,配合 volume 使用。比如给数据库节点打标签node.role==db,然后创建服务时加上约束条件,Swarm 只会把任务调度到这些节点上。这样做的好处是数据盘可以保持固定,不用担心任务漂移到其他节点后数据目录对不上。
| 对比维度 | replicated 模式 | global 模式 |
|---|---|---|
| 副本数量 | 由 --replicas 指定 | 每台节点固定一个 |
| 扩缩容 | 手动 scale 或自动更新 | 随节点数量变化 |
| 适用场景 | 业务接口、有状态服务、按流量伸缩的服务 | 监控采集、日志采集、网络代理 |
| 故障恢复 | 在健康节点重新调度副本 | 节点恢复后任务自动恢复 |
| 调度控制 | 精细,可配合约束和资源预留 | 简单,遍布全集群 |
注意:global 服务配合端口发布时要小心。如果你在每台节点上都有任务,端口发布又是 Swarm 的 ingress 模式,会出现所有节点都监听同一发布端口的情况。比如上面创建的 web-global 发布 8081 端口,你访问任意一台节点 IP 的 8081 端口都能命中服务,这在某些安全审计场景下可能不是你想要的。
4. 更新模式与故障切换:生产环境最关心的一课
4.1 滚动更新的参数怎么定:parallelism、delay 与 failure-action
当你发布新镜像时,docker service update的默认行为是逐个替换任务,先停止一个旧任务、启动一个新任务,等新任务运行成功后,再继续替换下一个。这种滚动更新的模式可以用--update-parallelism控制并发数,用--update-delay控制每批之间的间隔。
我建议的参数策略是这样的:先小步快跑,再平稳扩大。第一次发布,parallelism 设为 1,delay 设成 30s,观察一两个任务跑起来没问题,再手动把 parallelism 调大。更新命令本身也可以重复执行,不会产生冲突:
docker service update \ --image nginx:1.26-alpine \ --update-parallelism 1 \ --update-delay 30s \ --update-failure-action pause \ web-rep--update-failure-action有两个可选值:pause和continue。生产环境务必设置为pause,因为一旦新任务启动失败,Swarm 会暂停整个更新流程,给你留出排查时间。如果用默认的continue,Swarm 会继续尝试替换剩余任务,新版本有 bug 时整个服务的所有副本都会被污染,后果非常被动。
--update-order参数也值得留意,默认是stop-first,也就是先停旧任务再启新任务。对于无状态服务这没问题,但对有状态服务,停旧和启新之间会有一段空窗期,服务不可用。另一个选项是start-first,先启动新任务并确认健康后再停旧任务,这样能最大程度减少中断,但需要额外的网络端口或资源来同时运行新旧两套任务。我的习惯是:流量高峰期的核心服务用start-first,普通内部服务用stop-first。
4.2 失败自动回滚:给自己的发布上一道保险
光有 pause 还不够,Swarm 还支持自动回滚。你在更新服务时同时指定--rollback-parallelism和--rollback-monitor,Swarm 会在新任务运行状态异常时自动把服务回滚到上一个版本。
docker service update \ --image myapp:2.0.0 \ --update-failure-action rollback \ web-rep--update-failure-action设置为rollback之后,如果任务启动失败或者健康检查失败,Swarm 会自动执行回滚,把镜像恢复为之前的版本。这里有几个细节要注意:健康检查(HEALTHCHECK)的判定直接决定回滚是否触发,如果你没有给镜像定义健康检查,Swarm 只能靠进程退出码判断失败,很多“启动了但业务异常”的情况不会被识别。所以在制作业务镜像时,一定要在 Dockerfile 里加上合适的 HEALTHCHECK 指令,比如检查某个 HTTP 接口是否能返回 200。
我自己有过一次印象深刻的教训:更新镜像后所有容器的进程都正常启动,端口也监听了,但因为依赖的配置中心连接失败,接口一直返回 503。由于镜像没有健康检查,Swarm 认为任务运行正常,更新照常进行,等到我手动发现业务异常时,所有副本都已经切换到新版本了。那次之后,我要求团队所有业务镜像必须包含健康检查,才允许发布到 Swarm 集群。
4.3 高可用模式的底层:Raft 共识与 Leader 选举
Swarm 的高可用靠的是管理节点组成的 Raft 集群。每个管理节点都维护一份集群状态的日志,包括服务定义、任务状态、节点列表等。当管理节点收到变更指令时,Raft 协议会要求多数派节点确认写入,只有超过半数的节点都记录了这条变更,才真正生效。这套机制保证了不会出现两个管理节点各自为政、状态分叉的情况。
Leader 选举是 Raft 的核心行为。当 Leader 节点异常失联后,其他管理节点会发起新一轮选举,选出新的 Leader,选举期间集群不接受新的变更操作。这个过程通常很快,但对正在执行的服务更新、扩容操作会有短暂阻塞。生产环境的管理节点如果频繁重启,会不断触发选举,影响控制面的稳定性。
我见过有团队把五个管理节点部署在同一台物理机上的不同虚拟机里,结果物理机断电后集群完全瘫痪,所谓的高可用形同虚设。管理节点要分布在不同的故障域里,至少分散到不同的物理机或者不同的机架,否则 Raft 的容错设计发挥不出作用。
需要临时降级某个管理节点时,执行:
docker node demote <node-id> docker node promote <node-id>promote 和 demote 可以动态调整节点角色,不需要重启服务。
4.4 重启策略:容器崩溃时 Swarm 如何响应
服务还有一个经常被忽略的 Mode——Restart Policy(重启策略)。docker service create可以通过--restart-condition设置容器退出后的行为,可选值包括none、on-failure和any,默认是any。也就是说,无论容器是以正常退出码(0)还是异常退出码(非 0)结束,Swarm 都会重新拉起任务。这个策略跟 Docker 单机模式的--restart参数类似,但行为上有区别:单机模式的 restart 是 Docker 守护进程管理容器生命周期,Swarm 的重启则是调度器重新创建任务。
我遇到过一个诡异的问题:一个批处理任务设计好了跑完就退出,结果在 Swarm 里创建的服务反复重启,日志里全是重复执行记录。原因就是默认的 restart policy 是any,批处理跑完退出码为 0,Swarm 认为任务异常结束,又把它拉起来了。解决方法是创建服务时显式指定:
docker service create --restart-condition none --name batch-job busybox echo "done"反过来,如果你希望服务一直在线,即使进程正常退出也要拉起来,那就用默认的any或显式写--restart-condition any。判断一个服务到底适合哪种重启策略,关键看它是长驻型进程(Web 服务、队列消费者)还是短生命周期任务(批处理、一次性脚本),这个决策在创建服务时就应该想清楚,而不是等出问题时再补。
5. 网络模式与实测排坑:从端口到 DNS 的全链路梳理
5.1 Swarm 内置的 overlay 与 ingress 网络
创建 Swarm 集群后,你会发现docker network ls多出几个网络。ingress是 Swarm 内置的入口网络,负责对外发布端口的流量路由。docker_gwbridge是节点上的桥接网络,用于容器访问外部网络。还有一个docker_gwbridge通常是自动创建的,不需要手动维护。
当你在服务上发布端口时,比如--publish published=8080,target=80,Swarm 会在 ingress 网络上创建一个 VIP(虚拟 IP),所有节点的 8080 端口流量都被接入这个 VIP,再由 Swarm 内部的负载均衡转发到具体的任务副本。这就是 Swarm 的服务发现和负载均衡机制,客户端访问任意节点的任意发布端口都能到达服务,无需额外部署反向代理。
覆盖网络(overlay network)用于服务间通信。创建一个自定义 overlay 网络并让两个服务都接入,它们之间就可以通过服务名直接互通:
docker network create -d overlay --attachable my-overlay docker service create --name app --network my-overlay nginx:1.24-alpine docker service create --name db --network my-overlay mysql:8.0在 app 容器里,你可以直接访问主机名db,Swarm 内置的 DNS 会解析到 db 服务的 VIP。--attachable参数允许普通容器(非 Swarm 服务)也连接到这个 overlay 网络,这在调试时特别有用。我把一个 debug 容器挂到 overlay 网络上,直接 ping 服务名验证网络连通性,比登录到服务容器里操作安全得多。
5.2 跨节点通信频繁失败:指向 VXLAN 与防火墙
Swarm 的 overlay 网络基于 VXLAN 技术,数据包在节点之间通过 UDP 4789 封装传输。跨节点通信出现间歇性失败,十次里有八次是 UDP 4789 被防火墙丢弃,还有两次是 MTU 不一致。
我遇到过最隐蔽的一次:集群节点分别位于两个机房,A 机房的网络设备支持 1500 MTU,B 机房的核心交换机 MTU 设置成了 1400。VXLAN 封装后的数据包比原始数据包大 50 字节左右,超过 MTU 就直接丢包。表现症状非常奇怪:同一 overlay 网络里的两个服务,在 A 机房内部通信正常,在 B 机房内部也正常,A 和 B 之间通信时断时续。后来在管理节点上把 overlay 网络的 MTU 调整成 1350 才彻底解决。
调整网络 MTU 的方法:
docker network create -d overlay \ --opt encap=ipv4 \ --opt mtu=1350 \ my-overlay这个参数只在创建网络时生效,已经创建的网络改不了,需要重新创建再让服务切换。如果你只是临时验证,可以先用--attachable创建一个测试网络挂到服务上看效果,确认无误后再切正式网络。
5.3 虚拟化环境常见问题:Docker Desktop 与 WSL2 的影响
本地开发时,很多人用 Docker Desktop 跑 Swarm 集群。Docker Desktop 在 Windows 和 macOS 上依赖虚拟化技术,启动失败最常见的报错是 “virtualization support was not detected” 或者 “failed to start because virtualisation support wasn't detected”。这个问题通常是 Windows 的 Hyper-V 或 WSL2 功能没有启用导致的。解决办法是先到“启用或关闭 Windows 功能”里勾选“适用于 Linux 的 Windows 子系统”和“虚拟机平台”,然后重启系统,再启动 Docker Desktop。
如果你用 Docker Desktop 跑多节点 Swarm,还有一个更快的办法:Docker Desktop 自带 Kubernetes,但 Swarm 的支持相对有限,本地模拟集群最佳方案还是用 Vagrant 或者 Multipass 拉起多台 Ubuntu 虚拟机。我在 MacBook 上常用的方式是用 Multipass 创建三台 2C4G 的 Ubuntu 虚拟机,然后在每台虚拟机上安装 Docker Engine,再组成三节点 Swarm。本地实测和线上行为一致,不需要忍受 Docker Desktop 在 Mac 上偶发的网络性能问题。
5.4 排查 Mode 相关问题的命令速查
日常维护 Swarm,我建议把下面几个命令背下来,排查效率会大幅提升:
# 查看节点状态、角色和可用性 docker node ls # 查看服务任务在所有节点上的分布和状态 docker service ps <service-name> # 查看服务配置、更新策略、网络端口等细节 docker service inspect --pretty <service-name> # 查看服务日志(需要服务创建时指定日志驱动) docker service logs <service-name> # 查看特定任务所在节点和运行状态 docker inspect --format '{{.NodeID}}' <container-id>| 现象 | 可能原因 | 处理手段 |
|---|---|---|
docker node ls显示 Down | 节点网络中断或 Docker 服务停止 | 检查节点 2377 端口连通性,重启 Docker 服务 |
| 服务一直显示 Pending | 资源不足或约束不满足 | docker service ps查看错误信息,检查节点资源 |
| 跨节点容器 ping 不通 | overlay 网络异常或防火墙拦截 | 检查 4789/7946 端口,必要时重建网络 |
| 更新任务一直卡在启动中 | 镜像拉取缓慢或健康检查未通过 | docker service ps看 CurrentState,查镜像源或日志 |
| 管理节点无 Leader | Raft 共识失联 | 检查管理节点间 2377 连通性和时钟同步 |
| 滚动更新自动暂停 | update-failure-action设计为 pause | 查看失败任务日志,修复后docker service update --update-failure-action continue |
有一个细节:排查任务状态时,docker service ps输出的 CurrentState 会记录任务从创建到当前的所有状态转换,比如Assigned、Starting、Running、Failed、Shutdown。判断一个任务是否经历过重启,看它对应行的 Replica 编号和上次状态,如果同一个编号下有多个Failed记录,基本能断定是镜像问题或启动命令问题,而不是调度问题。
写在最后:一次多模式共存的实践体会
我在实际项目里把三种 Mode 的配合用得很频繁:Swarm Mode 负责集群生命周期,replicated 模式承载无状态业务,global 模式托管监控和日志采集,更新模式控制发布节奏。一开始总是把注意力放在镜像和容器本身,觉得 Mode 只是命令参数,后来才发现,Mode 才是决定整个集群行为方式的主线。比如同样一个 Nginx 服务,用 replicated 跑 3 副本和用 global 跑出来的运维方式完全不同,前者要管理扩缩容,后者要管理节点生命周期。
最后分享一个小技巧:凡是遇到 Swarm 行为不符合预期,先别急着翻日志,先回答三个问题——当前集群处于什么 Mode?服务是 replicated 还是 global?发布时设置的更新策略是什么?把这三个问题理清楚,90% 的问题都能定位到方向。这个系列后续我还会继续拆 Swarm 的服务发现、存储卷、安全加密和 Ingress 流量治理,Mode 这块的内容是地基,地基稳了,上面的架构才能站得牢。