Docker Swarm
某些企业依然还在使用Docker Swarm,虽然它的地位已经不及Kubernetes这种大型作业的编排系统
但是Swarm的轻量化是一个非常有优势的点,适合小型测试或者小资源使用。
核心架构和组件

| 组件 | 说明 | 生产建议 |
|---|---|---|
| Manager节点 | 集群大脑,负责调度和决策 | 至少3个(奇数) |
| Worker节点 | 执行容器运行任务 | 按需扩展 |
| 服务(Service) | 部署单元,定义容器模板 | – |
| 任务(Task) | 服务的最小执行单元 | – |
| Raft共识 | 保证Manager节点状态一致 | – |
从原理上看,和Kubernetes也差不多,如果需要方便理解,也可以选择和Kubernetes一起对照学习。
实战
单机快速搭建
# 初始化单节点Swarm
docker swarm init
# 部署测试服务
docker service create --name web --publish 8080:80 --replicas 3 nginx:latest在初始化之后,会显示一些信息,方便你将其他带有docker的节点变成Worker Node或者Manager,举例:
[root@centos7 ~]# docker swarm init
Swarm initialized: current node (dkxclj2aqhiwemwxyzla41o2y) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5nptr24v7dvyov0apoxlqz0z45mhtsldvpfhy1zg5mw3j3a976-7kgsq8fvbr953w4v43nc2my5z 192.168.1.204:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
生产环境集群搭建
# Manager节点初始化(指定IP)
docker swarm init --advertise-addr 192.168.1.100
# 获取加入令牌
MANAGER_TOKEN=$(docker swarm join-token -q manager)
WORKER_TOKEN=$(docker swarm join-token -q worker)
# Worker节点加入(在Worker节点执行)
docker swarm join --token $WORKER_TOKEN 192.168.1.100:2377
节点管理命令
# 查看节点状态
docker node ls
# 提升Worker为Manager
docker node promote worker-node1
# 排空节点(停止新任务分配,意思是该节点不再支持运行task,将会把task转移到其他节点)
docker node update --availability drain node-2服务部署与管理
基础服务操作
# 创建服务
docker service create \
--name redis \
--replicas 3 \
--publish published=6379,target=6379 \
--limit-cpu 1 \
redis:6-alpine
# 查看服务列表
docker service ls
# 扩缩容服务
docker service scale redis=5
# 删除服务
docker service rm redis服务更新策略
示例:Redis滚动更新
docker service update \
--image redis:7-alpine \
--update-parallelism 2 \
--update-delay 10s \
--update-failure-action rollback \
--rollback-parallelism 1 \
--rollback-delay 5s \
redis这条命令的意思是:
把 redis 服务的镜像升级为 redis:7-alpine,并按 2 个一批、每批间隔 10 秒进行滚动更新;如果更新失败,则每次回滚 1 个、间隔 5 秒,恢复到旧版本。
这是一个非常标准、非常安全的 生产级滚动更新 + 自动回滚命令。
示例:Nginx端口更新
docker service update \
--image nginx:latest \
--publish-rm 8080:80 \
--publish-add 8090:80 \
--replicas 6 \
web| 参数 | 说明 |
|---|---|
--image nginx:latest | 更新镜像版本 |
--publish-rm 8080:80 | 删除旧端口映射 |
--publish-add 8090:80 | 添加新的端口映射 |
--replicas 6 | 副本数从 3 调整到 6 |
web | 服务名称 |
🧩 小说明:为什么不能用 --publish 8090:80 覆盖旧端口?
在 Swarm Mode 中,端口映射是可累计的,不会自动替换
所以要先 移除旧的, 再 添加新的:
--publish-rm:删除某条端口映射--publish-add:添加新映射
检查命令
查看服务状态:
docker service ls
查看任务运行在哪些节点:
docker service ps web
查看更新后的配置:
docker service inspect web全局服务模式
全局服务模式(global mode)是 Docker Swarm 的一种服务部署方式,用来让每个节点上都自动运行一个任务(task)。
它与我们平常用的副本模式(replicated)完全不同。
# 每个节点运行一个监控代理
docker service create \
--mode global \
--name node-exporter \
--mount type=bind,source=/proc,target=/host/proc \
prom/node-exporter为什么要用全局模式?
因为 node-exporter 是一个 节点监控程序:
- 它采集主机 CPU、内存、磁盘、网络等指标
- 必须在每个节点上都运行
- 每个节点都应该有一个独立的采集器
- 但每个节点只需要一个,不需要多个
因此用全局模式最合适。
你不用写 replicas,因为 Swarm 会自动保证:
集群中有多少个节点 → 就自动创建多少个 node-exporter
如果你增加节点,它会自动在新节点跑一个 task。
如果你删除节点,对应 task 也自动移除。
网络架构深入
网络类型对比
| 网络类型 | 作用 | 特点 |
|---|---|---|
| ingress | 外部访问入口 | 自动创建,路由网格 |
| overlay | 跨主机容器通信 | 加密通信,需手动创建 |
| bridge | 单主机容器通信 | 默认网络 |
| host | 直接使用宿主机网络 | 高性能,无隔离 |
创建自定义Overlay网络
docker network create -d overlay \
--subnet 10.1.0.0/24 \
--gateway 10.1.0.1 \
--opt encrypted \
my-overlay服务使用自定义网络
docker service create \
--name api \
--network my-overlay \
--network ingress \
--publish 8080:80 \
my-api:latest存储管理方案
数据卷类型

生产环境最佳实践
# 创建命名卷
docker volume create app-datadocker volume create:创建一个 Docker 卷(volume)app-data:卷的名字- 作用:存储 MySQL 数据,使容器删除、重建或更新时数据不会丢失
- 默认情况下,命名卷是 本地卷,存储在宿主机
/var/lib/docker/volumes/下
⚠️ 注意:本地卷只在当前节点可用,如果你在 Swarm 中有多个节点,副本模式下的任务可能分布在不同节点,这样每个节点都会有一个 独立的卷,数据不会自动同步。
NFS网络共享卷
在 Docker Swarm 中,如果你希望 所有节点的 task 都能访问同一份共享数据,需要使用 网络存储(Network File System, NFS)卷。
普通本地卷只能在单节点使用,跨节点不可用。
1️⃣ 准备 NFS 服务器
假设你已经有一台 NFS 服务器:
- IP:
192.168.1.100 - 导出目录:
/export/app_data - 所有 Swarm 节点都有网络访问权限
- 确保权限正确,例如
rw并允许所有 Swarm 节点挂载
2️⃣ 在 Swarm 上创建 NFS 卷
Docker Swarm 支持通过 docker volume create 使用 NFS:
docker volume create \
--driver local \
--opt type=nfs \
--opt o=addr=192.168.1.100,rw \
--opt device=:/export/app_data \
app_data_nfs
解释:
| 参数 | 说明 |
|---|---|
--driver local | 使用本地驱动(可以挂载网络文件系统) |
--opt type=nfs | 卷类型为 NFS |
--opt o=addr=192.168.1.100,rw | 挂载选项,addr 是 NFS 服务器地址,rw 可读写 |
--opt device=:/export/app_data | NFS 导出目录路径 |
app_data_nfs | 卷名称,用于 Swarm 服务挂载 |
✅ 创建完成后,Swarm 集群任意节点都可以使用 app_data_nfs 卷。
3️⃣ 使用 NFS 卷创建服务
假设你要创建 MySQL 服务:
docker service create \
--name db \
--replicas 3 \
--mount type=volume,source=app_data_nfs,target=/var/lib/mysql \
mysql:8.0
解释:
--mount type=volume→ 挂载卷source=app_data_nfs→ 使用 NFS 卷target=/var/lib/mysql→ 容器内部路径--replicas 3→ 每个副本 task 都可以访问同一份数据
常见问题排错
服务部署故障排查
# 查看服务详情
docker service inspect --pretty web
# 查看服务日志
docker service logs -f web
# 查看容器状态
docker service ps web网络问题排查
# 检查网络连通性
docker exec -it <container> ping <target>
# 检查DNS解析
docker exec -it <container> nslookup service_name节点状态异常
# 查看节点详情
docker node inspect <node_id> --pretty
# 检查节点资源
docker node ps <node_id>进阶技巧
金丝雀发布
# 创建v1版本
docker service create --name app --replicas 5 my-app:v1
# 逐步替换为v2
docker service update \
--image my-app:v2 \
--update-parallelism 1 \
--update-delay 30s \
app自动扩缩容
# 安装自动扩缩组件
docker plugin install --alias scaler docker/scale
# 设置扩缩规则
docker service scale \
--min 2 \
--max 10 \
--step 1 \
--scale-on-cpu 80 \
web