Mooloco Blogs

最近在找工作,欢迎进入网站的各位HR查看我的博客,我的微信是Mooloco

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-data
  • docker 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_dataNFS 导出目录路径
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

发表回复

Your email address will not be published. Required fields are marked *.

*
*