Docker Swarm 完整教程
文章目录
Docker Swarm 完整教程
一、Docker Swarm 核心概念
1.1 集群化(Clustering)
从主机层面来看,Docker Swarm 管理的是 Docker Host 集群,首先需理解集群化这一关键概念:
-
集群定义:由一组网络互联的服务器组成,协同工作且具备 “单一系统” 特性,可提供高可用、负载均衡和并行处理能力。
-
集群与独立服务器的区别
:
- 独立服务器部署:资源利用率难最优,应用资源需求波动时缺乏弹性,服务器宕机需手动迁移应用。
- 集群部署:无需关注单个服务器,仅需指定应用所需的内存、CPU 等资源,由集群管理程序(如 Docker Swarm)自动分配任务;集群容量可通过添加 / 删除节点调整,始终保持整体特性。
1.2 Docker Swarm Mode
-
版本里程碑:Docker v1.12 是关键版本,Swarm 功能完全集成到 Docker Engine,无需依赖外部数据库(如 Consul、etcd、Zookeeper)。
-
核心优势
:
- 零额外配置:安装 Docker 后,启动 Swarm Mode 即可使用集群管理和服务发现功能。
- 易用性:相比 Kubernetes,创建集群无需额外安装软件,适合作为容器编排引擎的入门学习工具。
-
模式特性
:
- 未启动 Swarm Mode:仅支持普通容器命令。
- 启动 Swarm Mode:新增 Service 编排能力,支持同一主机同时运行 Swarm Service 和独立容器。
1.3 三大核心概念
| 概念 | 定义与作用 |
|---|---|
| swarm | 运行 Docker Engine 的多主机集群。Docker Engine 初始化或加入 swarm 时自动启动 Swarm Mode,具备集群管理和编排能力。 |
| node | 集群中的每个 Docker Engine 节点,分两类: - manager node:执行部署命令、拆解任务、管理集群状态,多 manager 节点会自动选举 leader。 - worker node:接收并执行 manager 分配的任务,定期上报自身和任务状态;默认 manager 同时也是 worker,可配置为 “纯管理节点”。 |
| service | 定义 worker 节点需执行的任务,Swarm 的核心目标是保证 service 始终处于 “期望状态”(如指定副本数)。 示例:启动 3 个 httpd 副本,worker2 宕机后,manager 会自动在 worker3 补全副本。 |
二、部署 Swarm 集群
2.1 集群规划
本次搭建三节点集群,节点信息如下:
| 节点角色 | 主机名 | IP 地址 | 说明 |
|---|---|---|---|
| manager node | swarm-manager | 192.168.108.30 | 集群管理节点,负责编排 |
| worker node | swarm-worker1 | 192.168.108.31 | 工作节点,执行任务 |
| worker node | swarm-worker2 | 192.168.108.32 | 工作节点,执行任务 |
环境要求:
- 所有节点 Docker 版本 ≥ v1.12,操作系统为 CentOS Stream 8(其他 Linux 系统也可)。
- 关闭所有节点防火墙(或放行 Swarm 所需端口:2377/tcp、7946/tcp/udp、4789/udp)。
- 通过克隆 Docker 教案中的虚拟机生成三个节点,修改各节点的 IP 地址和主机名。
2.2 初始化 Manager 节点
在 swarm-manager 节点执行以下命令,初始化 Swarm 集群:
bash

# --advertise-addr 指定与其他节点通信的 IP(即 manager 自身 IP)
[root@swarm-manager ~]# docker swarm init --advertise-addr 192.168.108.30
命令输出解读
执行后会返回类似以下内容,包含关键信息:

- ①
swarm-manager已成为 manager node。 - ② 提供添加 worker node 的命令(含唯一 token)。
- ③ 提示添加额外 manager node 的方法。
验证 Manager 节点状态
[root@swarm-manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
bpuyqqwojwjz9avzuaeyjszyo * swarm-manager Ready Active Leader 26.1.3
此时集群仅包含 1 个 manager 节点,* 表示当前操作的节点,Leader 表示该节点是集群领导者。
2.3 添加 Worker 节点
在 swarm-worker1 和 swarm-worker2 节点分别执行步骤 2.2 中返回的 docker swarm join 命令(需携带正确 token):
# swarm-worker1 节点执行
[root@swarm-worker1 ~]# docker swarm join --token SWMTKN-1-5it8t4f2tbrmxuhahkwp7i4jzhq7q14l35tkjotbiln0bztrzw-bmwlgmv1inatgm1hpl1739ncy 192.168.108.30:2377
This node joined a swarm as a worker.
# swarm-worker2 节点执行(命令相同)
[root@swarm-worker2 ~]# docker swarm join --token SWMTKN-1-5it8t4f2tbrmxuhahkwp7i4jzhq7q14l35tkjotbiln0bztrzw-bmwlgmv1inatgm1hpl1739ncy 192.168.108.30:2377
This node joined a swarm as a worker.
验证 Worker 节点加入结果
回到 swarm-manager 节点,执行 docker node ls 查看集群节点列表:
[root@swarm-manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
bpuyqqwojwjz9avzuaeyjszyo * swarm-manager Ready Active Leader 26.1.3
s3o9n5wkkbiyc21ehmk3xecvk swarm-worker1 Ready Active - 26.1.3
mdudczt56hzbaw7aum3smrula swarm-worker2 Ready Active - 26.1.3
可见 swarm-worker1 和 swarm-worker2 已成功加入,MANAGER STATUS 为 - 表示其为 worker 节点。
找回 Worker 加入命令
若未记录初始化时的 join 命令,可在 manager 节点执行以下命令查看:
[root@swarm-manager ~]# docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5it8t4f2tbrmxuhahkwp7i4jzhq7q14l35tkjotbiln0bztrzw-bmwlgmv1inatgm1hpl1739ncy 192.168.108.30:2377
三、运行第一个 Service
3.1 部署 Service
在 swarm-manager 节点执行以下命令,部署一个基于 httpd 镜像的 Service:
# --name 为 Service 命名,httpd 为镜像名
[root@swarm-manager ~]# docker service create --name web_server httpd
1ntzbsmbu3q3d4f969gpu0a8c # Service ID
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service 1ntzbsmbu3q3d4f969gpu0a8c converged
3.2 查看 Service 状态
1. 查看 Service 列表
[root@swarm-manager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
1ntzbsmbu3q3 web_server replicated 1/1 httpd:latest
REPLICAS: 1/1:表示 Service 期望的副本数为 1,当前已启动 1 个副本,部署完成。MODE: replicated:表示 Service 采用 “副本模式”(按指定数量分布副本)。
2. 查看副本详情
通过 docker service ps <service 名> 查看副本的运行节点和状态:
[root@swarm-manager ~]# docker service ps web_server
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
lfwcnkg6pgth web_server.1 httpd:latest swarm-worker2 Running Running 56 seconds ago
可见唯一副本被分配到 swarm-worker2 节点,状态为 Running。
3. 验证容器运行(可选)
登录 swarm-worker2 节点,通过 docker ps 确认 httpd 容器已启动:
[root@swarm-worker2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bef3b50af9ea httpd:latest "httpd-foreground" 2 minutes ago Up 2 minutes 80/tcp web_server.1.lfwcnkg6pgthdkqno2pu4w8n3
当前 web_server 在 swarm 中的分布如图所示。

四、Service 伸缩(Scale Up/Down)
4.1 扩展副本数(Scale Up)
对于 Web 服务,通常需要多副本实现负载均衡和高可用,执行以下命令将 web_server 副本数扩展到 5:
bash
[root@swarm-manager ~]# docker service scale web_server=5
web_server scaled to 5
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Service web_server converged
查看扩展结果
bash
# 查看 Service 副本数
[root@swarm-manager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
1ntzbsmbu3q3 web_server replicated 5/5 httpd:latest
# 查看副本分布
[root@swarm-manager ~]# docker service ps web_server
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
lfwcnkg6pgth web_server.1 httpd:latest swarm-worker2 Running Running 4 minutes ago
q4006zahgaqm web_server.2 httpd:latest swarm-worker1 Running Running 53 seconds ago
ug6dgvoycg91 web_server.3 httpd:latest swarm-worker2 Running Running about a minute ago
324xfyww2awh web_server.4 httpd:latest swarm-manager Running Running about a minute ago
v4btzz1lr69q web_server.5 httpd:latest swarm-worker1 Running Running 53 seconds ago
5 个副本分布在 3 个节点上,默认 manager 节点同时作为 worker 节点,因此 swarm-manager 也运行了 1 个副本。

4.2 配置 Manager 为 “纯管理节点”
若不希望 manager 节点运行 Service(避免消耗管理资源),可执行以下命令将其可用性设为 Drain(拒绝接收新任务,已运行任务会迁移):
[root@swarm-manager ~]# docker node update --availability drain swarm-manager
swarm-manager
验证节点状态
[root@swarm-manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
bpuyqqwojwjz9avzuaeyjszyo * swarm-manager Ready Drain Leader 26.1.3 # 可用性变为 Drain
s3o9n5wkkbiyc21ehmk3xecvk swarm-worker1 Ready Active - 26.1.3
mdudczt56hzbaw7aum3smrula swarm-worker2 Ready Active - 26.1.3
查看副本迁移结果
[root@swarm-manager ~]# docker service ps web_server
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
lfwcnkg6pgth web_server.1 httpd:latest swarm-worker2 Running Running 8 minutes ago
q4006zahgaqm web_server.2 httpd:latest swarm-worker1 Running Running 4 minutes ago
ug6dgvoycg91 web_server.3 httpd:latest swarm-worker2 Running Running 4 minutes ago
732oh5htny76 web_server.4 httpd:latest swarm-worker2 Running Running 49 seconds ago
324xfyww2awh \_ web_server.4 httpd:latest swarm-manager Shutdown Shutdown 50 seconds ago # 原副本已关闭
v4btzz1lr69q web_server.5 httpd:latest swarm-worker1 Running Running 4 minutes ago
swarm-manager 上的副本 web_server.4 已被关闭,同时在 swarm-worker2 上新建副本以维持 5 个副本总数。

4.3 缩减副本数(Scale Down)
执行以下命令将副本数缩减到 3:
bash
[root@swarm-manager ~]# docker service scale web_server=3
web_server scaled to 3
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service web_server converged
查看缩减结果
[root@swarm-manager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
1ntzbsmbu3q3 web_server replicated 3/3 httpd:latest
[root@swarm-manager ~]# docker service ps web_server
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
lfwcnkg6pgth web_server.1 httpd:latest swarm-worker2 Running Running 10 minutes ago
q4006zahgaqm web_server.2 httpd:latest swarm-worker1 Running Running 6 minutes ago
ug6dgvoycg91 web_server.3 httpd:latest swarm-worker2 Running Running 7 minutes ago
324xfyww2awh web_server.4 httpd:latest swarm-manager Shutdown Shutdown 2 minutes ago # 多余副本已关闭
web_server.4 和 web_server.5 两个副本被删除,仅保留 3 个副本。

五、Swarm 故障切换(Failover)
Swarm 内置故障切换机制,无需额外配置,仅需指定 Service 的 “期望状态”,集群会自动维持该状态。
5.1 模拟节点故障
以 swarm-worker1 节点宕机为例,执行以下命令关闭该节点:

[root@swarm-worker1 ~]# shutdown now
5.2 观察故障检测与副本迁移
1. 查看节点状态
在 swarm-manager 节点执行 docker node ls,可见 swarm-worker1 状态变为 Down:
[root@swarm-manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
bpuyqqwojwjz9avzuaeyjszyo * swarm-manager Ready Drain Leader 26.1.3
s3o9n5wkkbiyc21ehmk3xecvk swarm-worker1 Down Active - 26.1.3 # 节点故障
mdudczt56hzbaw7aum3smrula swarm-worker2 Ready Active - 26.1.3
2. 查看副本迁移结果
[root@swarm-manager ~]# docker service ps web_server
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
lfwcnkg6pgth web_server.1 httpd:latest swarm-worker2 Running Running 41 minutes ago
gx95mteiiaq1 web_server.2 httpd:latest swarm-worker2 Running Running about a minute ago # 新副本
q4006zahgaqm \_ web_server.2 httpd:latest swarm-worker1 Shutdown Shutdown 37 minutes ago # 故障节点副本关闭
ug6dgvoycg91 web_server.3 httpd:latest swarm-worker2 Running Running 38 minutes ago
324xfyww2awh web_server.4 httpd:latest swarm-manager Shutdown Shutdown 34 minutes ago
-
原运行在
swarm-worker1上的web_server.2被标记为Shutdown。 -
Swarm 自动在
swarm-worker2上新建web_server.2副本,维持 3 个副本的期望状态。

六、访问 Swarm Service
6.1 重新部署 Service(便于演示)
先删除原有 web_server,重新创建 2 个副本的 Service:
# 1. 删除原有 Service
[root@swarm-manager ~]# docker service rm web_server
web_server
# 2. 新建 Service,指定 2 个副本
[root@swarm-manager ~]# docker service create --name web_server --replicas=2 httpd
izro3jrl6e09czc0iz08q9p44
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service izro3jrl6e09czc0iz08q9p44 converged
# 3. 查看副本分布
[root@swarm-manager ~]# docker service ps web_server
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
9zve246nlqed web_server.1 httpd:latest swarm-worker1 Running Running 12 seconds ago
yvker0qkyfe2 web_server.2 httpd:latest swarm-worker2 Running Running 13 seconds ago
6.2 容器层面的访问限制
每个副本本质是一个容器,默认仅能在容器所在主机访问:
-
在swarm-worker1查看容器网络配置:
[root@swarm-worker1 ~]# docker inspect web_server.1.9zve246nlqedn272fgtddepok | grep -A 10 "Networks" "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "MacAddress": "02:42:ac:11:00:02", "NetworkID": "325e2b265f380ba7278c32b3a6a0def045452e684b23eae5341b494d864a262a", "EndpointID": "8e3002fa399c0b412ae04a12481d9824db22bc0c54e6c2bd7b5c47e6705d5344", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", # 容器 IP "IPPrefixLen": 16, -
在swarm-worker1访问容器:
[root@swarm-worker1 ~]# curl 172.17.0.2 <html><body><h1>It works!</h1></body></html>仅能在容器所在主机访问,无法从外部网络或其他节点访问。
6.3 暴露 Service 到外部网络
需通过端口映射将容器端口暴露到主机,有两种方式:
1. 为已有 Service 添加端口映射
# --publish-add 8080:80:将容器 80 端口映射到主机 8080 端口
[root@swarm-manager ~]# docker service update --publish-add 8080:80 web_server
web_server
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service web_server converged
2. 新建 Service 时直接指定端口映射
docker service create --name web_server --publish 8080:80 --replicas=2 httpd
3. 验证外部访问
从集群任意节点(或外部主机,需网络互通)访问 8080 端口:
# 访问 manager 节点
[root@swarm-manager ~]# curl http://192.168.108.30:8080
<html><body><h1>It works!</h1></body></html>
# 访问 worker1 节点
[root@swarm-manager ~]# curl http://192.168.108.31:8080
<html><body><h1>It works!</h1></body></html>
# 访问 worker2 节点
[root@swarm-manager ~]# curl http://192.168.108.32:8080
<html><body><h1>It works!</h1></body></html>
关键特性:无论访问哪个节点的 8080 端口,均可访问到 web_server,这依赖 Swarm 的 routing mesh 功能。
七、Routing Mesh 与 Swarm 网络
7.1 Routing Mesh 原理

-
定义:Swarm 内置的负载均衡机制,外部请求访问任意节点的映射端口时,会自动转发到 Service 的任意副本。
-
核心作用
:
- 无需关心副本分布节点,访问集群任意节点均可触达 Service。
- 支持配置外部负载均衡器(如 HAProxy),将请求分发到集群节点的映射端口,实现更高层级的负载均衡。
架构示意图

外部请求 → HAProxy(可选)→ 集群任意节点:8080 → Routing Mesh → Service 副本
↓
192.168.108.30:8080(manager)
192.168.108.31:8080(worker1)
192.168.108.32:8080(worker2)
7.2 Swarm 核心网络
执行 docker network ls 查看节点网络:
[root@swarm-worker1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
325e2b265f38 bridge bridge local
06615073d3f0 docker_gwbridge bridge local
77d2734d1c55 host host local
t2ie77rl777k ingress overlay swarm # Swarm 自动创建
a0663936827d none null local
| 网络名称 | 类型 | 作用 |
|---|---|---|
| ingress | overlay | Swarm 创建时自动生成,跨主机容器通信的核心网络;Service 配置端口映射后,副本会自动接入此网络。 |
| docker_gwbridge | bridge | 连接容器与主机网络,使容器能够访问外部网络(如互联网)。 |
| bridge/host/none | 本地网络 | 与普通 Docker 网络功能一致,仅支持单主机内容器通信。 |
7.3 端口映射后的网络变化
配置 --publish-add 8080:80 后,Swarm 会重启所有副本并切换网络:
[root@swarm-manager ~]# docker service ps web_server
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
lwfdj841ph0g web_server.1 httpd:latest swarm-worker1 Running Running 28 seconds ago
gh9s2wst0k1m \_ web_server.1 httpd:latest swarm-worker1 Shutdown Shutdown 29 seconds ago
2yc07ps3oejh web_server.2 httpd:latest swarm-worker2 Running Running 25 seconds ago
jv61apqesurf \_ web_server.2 httpd:latest swarm-worker2 Shutdown Shutdown 25 seconds ago
查看新副本的网络配置,可见容器已接入 ingress 网络:
[root@swarm-worker1 ~]# docker inspect web_server.1.lwfdj841ph0glbrwwjucmckex | grep -A 5 "ingress"
"ingress": {
"IPAMConfig": {
"IPv4Address": "10.0.0.15" # ingress 网络分配的 IP
},
"Links": null,
"Aliases": [
"lwfdj841ph0glbrwwjucmckex",
"web_server.1.lwfdj841ph0glbrwwjucmckex"
],
:latest swarm-worker2 Running Running 25 seconds ago
jv61apqesurf \_ web_server.2 httpd:latest swarm-worker2 Shutdown Shutdown 25 seconds ago
查看新副本的网络配置,可见容器已接入 ingress 网络:
[root@swarm-worker1 ~]# docker inspect web_server.1.lwfdj841ph0glbrwwjucmckex | grep -A 5 "ingress"
"ingress": {
"IPAMConfig": {
"IPv4Address": "10.0.0.15" # ingress 网络分配的 IP
},
"Links": null,
"Aliases": [
"lwfdj841ph0glbrwwjucmckex",
"web_server.1.lwfdj841ph0glbrwwjucmckex"
],
更多推荐



所有评论(0)