玩转Docker Swarm
一、Docker Swarm 核心概念
1.1 集群化(Clustering)
从主机层面来看,Docker Swarm 管理的是 Docker Host 集群
1.1.1集群定义
由一组网络互联的服务器组成,协同工作且具备 “单一系统” 特性,可提供高可用、负载均衡和并行处理能力。
1.1.2集群与独立服务器的区别
- 独立服务器部署:资源利用率难最优,应用资源需求波动时缺乏弹性,服务器宕机需手动迁移应用。
- 集群部署:无需关注单个服务器,仅需指定应用所需的内存、CPU 等资源,由集群管理程序(如 Docker Swarm)自动分配任务;集群容量可通过添加 / 删除节点调整,始终保持整体特性。
1.2 Docker Swarm Mode
版本里程碑:Docker v1.12 是关键版本,Swarm 功能完全集成到 Docker Engine,无需依赖外部数据库(如 Consul、etcd、Zookeeper)。
1.2.1 核心优势
- 零额外配置:安装 Docker 后,启动 Swarm Mode 即可使用集群管理和服务发现功能。
- 易用性:相比 Kubernetes,创建集群无需额外安装软件,适合作为容器编排引擎的入门学习工具。
1.2.2模式特性
- 未启动 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 工作节点,执行任务
环境要求:
(1)所有节点 Docker 版本 ≥ v1.12,操作系统为 CentOS Stream 8(其他 Linux 系统也可)。
(2)关闭所有节点防火墙(或放行 Swarm 所需端口:2377/tcp、7946/tcp/udp、4789/udp)。
(3)通过克隆 Docker 教案中的虚拟机生成三个节点,修改各节点的 IP 地址和主机名。
2.2 初始化 Manager 节点
在 swarm-manager 节点执行以下命令,初始化 Swarm 集群:
# --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.3swarm-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:
[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# --name 为 Service 命名,httpd 为镜像名
3.2 查看 Service 状态
##查看 Service 列表
[root@swarm-manager ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
1ntzbsmbu3q3 web_server replicated 1/1 httpd:latestREPLICAS: 1/1:表示 Service 期望的副本数为 1,当前已启动 1 个副本,部署完成。
MODE: replicated:表示 Service 采用 “副本模式”(按指定数量分布副本)。##查看副本详情
通过 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。##验证容器运行(可选)
登录 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:
##将web_server扩展为5副本
[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##查看 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 ago5 个副本分布在 3 个节点上,默认 manager 节点同时作为 worker 节点,因此 swarm-manager 也运行了 1 个副本。
4.2 配置 Manager 为 “纯管理节点”
若不希望 manager 节点运行 Service(避免消耗管理资源),可执行以下命令将其可用性设为 Drain(拒绝接收新任务,已运行任务会迁移):
##设置swarm-manager节点为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 agoswarm-manager 上的副本 web_server.4 已被关闭,同时在 swarm-worker2 上新建副本以维持 5 个副本总数。
4.3 缩减副本数(Scale Down)
执行以下命令将web_server缩减到 3副本:
##将web_server缩减为3副本
[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 模拟work节点故障
以 swarm-worker1 节点宕机为例,执行以下命令关闭该节点:
##模拟work1节点故障
[root@swarm-worker1 ~]# shutdown now##观察故障检测与副本迁移
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.32. 查看副本迁移结果
[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 个副本的期望状态。
5.2 模拟管理节点故障
在Docker swarm集群中,当管理节点发生故障时,需要及时进行故障处理,以保证集群的正常运行。下面将详细介绍如何实现DockerSwam管理节点故障处理的步骤和操作方法。
1:检测管理节点故障
在Docker Swarm集群中,首先需要检测管理节点是否发生故障。可以通过査看Swarm集群状态来确定管理节点是否正常运行,
2:选择新的管理节点
-旦确认管理节点发生故障,需要选择一个新的节点作为新的管理节点。可以选择已有的节点或者新增一个节点来替换原来的管理节点
3:重新初始化新的管理节点
籠旦选择了新的管理节点,需要重新初始化该节点并加入到Swarm集群中。以下是具体的操作步骤(1).在新的管理节点上运行以下命令,初始化Swarm集群:
docker swarm init --advertise-addr <新节点IP>
说明:该命令用于初始化Swarm集群,并指定新节点的IP地址作为通信地址
(2)在其他工作节点上运行以下命令,加入新的管理节点:
docker swarm ioin --token<Swarm令牌 > <管理节点IP >:2377
说明:该命令用于将其他节点加入到Swarm集群中,其中Swarm令牌和管理节点IP需要替换为实际的值。
六、访问 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,
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
功能。
七、dock swarm常用命令
7.1、初始化Swarm集群
用于初始化一个Swarm集群,并将当前节点设置为Manager节点。
用法:docker swarm init --advertise-addr <Manager节点IP>
# docker swarm init --advertise-addr 192.168.1.100
这会将当前节点初始化为Swarm集群的管理节点,并向其他节点广播IP 192.168.1.100。
7.2、将Worker节点加入Swarm集群
2.1获取加入Swarm集群的工作节点令牌
# docker swarm join-token worker
2.2获取加入Swarm集群的管理节点令牌
# docker swarm join-token manager
2.3将一个Worker节点加入到Swarm集群
用法:docker swarm join --token <token> <Manager节点IP>:2377
# docker swarm join --token SWMTKN-1-3t23f5f-vvjqz9sdgxlb12 192.168.1.100:2377
7.3、查看节点状态
用法:docker node ls
# docker node ls
更新节点的状态
用来更新Swarm集群中节点的可用性状态。
用法:docker node update --availability <availability> <node-name>
# docker node update --availability drain worker-node-1
将worker-node-1节点设置为Drain状态,所有任务将被迁移到其他节点。
7.4、创建Swarm服务
用于创建一个新的Swarm服务。
用法:docker service create --name <service-name> --replicas <replicas> -p <port> <image>
# docker service create --name web-service --replicas 3 -p 8080:80 nginx
使用nginx镜像创建一个名为web-service的服务,并将其副本数设置为3,映射容器的80端口到主机的8080端口。
7.5、查看服务
列出当前Swarm集群中所有的服务。
用法:docker service ls
# docker service ls
7.6、查看服务的详细信息
用于查看特定服务的任务(容器)状态。
用法:docker service ps <service-name>
# docker service ps web-service
7.7、更新服务
用于更新已有服务的配置,如镜像、端口、副本数等。
用法:docker service update --image <image> --replicas <replicas> <service-name>
# docker service update --image nginx:latest --replicas 5 web-service
将web-service服务的镜像更新为nginx:latest,并将副本数扩展为5。
7.8、扩展或缩减服务副本数
用于动态调整服务的副本数。
用法:docker service scale <service-name>=<replicas>
# docker service scale web-service=2 #web-service的副本数扩展到2
# docker service ls
7.9、删除服务
用于删除Swarm中的服务。
用法:docker service rm <service-name>
# docker service rm web-service #删除名为web-service的服务
7.10、查看Swarm集群的状态
docker info该命令提供有关Docker引擎的详细信息,包括Swarm集群的状态。
# docker info
7.11、监控Swarm的日志
用于查看特定服务的日志。
用法:docker service logs <service-name>
# docker service logs web-service显示web-service服务的容器日志
#docker service logs -f -n 200 lksk-service-cases_lksk-service-cases
-f 代表实时刷新
-n 200 只显示最新的 **200 行** 日志(默认是 10 行)