本文档介绍了 Docker Swarm 集群的基本概念、工作原理以及相关命令使用示例,包括如何在服务调度中使用自定义标签。本文档适用于需要管理和扩展 Docker 容器化应用程序的生产环境场景。
Docker Swarm 是用于管理 Docker 集群的原生工具,从 Docker 1.12.0 版本开始,Swarm 已经内置于 Docker 引擎中。Swarm 可以将多台 Docker 主机组织成一个统一的虚拟主机,使用户能够轻松部署、管理和扩展容器化应用程序。
docker-compose.yml
文件快速搭建和调试容器化应用。docker swarm init
命令初始化集群,执行节点自动成为 Manager(通常也是 Leader)。
角色 | IP | Hostname |
---|---|---|
Manager1 | 172.16.10.110 | manager1 |
Manager2 | 172.16.10.111 | manager2 |
Worker1 | 172.16.10.120 | worker1 |
Worker2 | 172.16.10.121 | worker2 |
在 Manager1 上执行以下命令:
docker swarm init --advertise-addr 172.16.10.110
执行成功后,输出中会显示用于其他节点加入集群的 token。注意:
--advertise-addr
用于指定通信的 IP 地址(默认端口为 2377),在多网卡环境下建议指定。查看 token:
docker swarm join-token manager # 查看管理节点 token
docker swarm join-token worker # 查看工作节点 token
加入 Manager2
在 Manager2 上执行(请替换 <manager_token>
与对应的广播地址):
docker swarm join --advertise-addr <Manager2_IP> --token <manager_token> 172.16.10.110:2377
加入 Worker1 和 Worker2 分别在 Worker 节点上执行:
docker swarm join --advertise-addr <Worker_IP> --token <worker_token> 172.16.10.110:2377
在 Manager1 上使用 docker node ls
查看当前集群状态。
要将节点退出并从集群移除:
在目标节点上执行:
docker swarm leave [--force] # Manager 节点退出需加 --force
在 Manager 节点上删除该节点:
docker node rm <节点名称>
以下命令需在 Manager 节点上执行(Worker 节点无操作权限):
查看集群所有节点
docker node ls
查看指定节点详情
docker node inspect <节点名称> --pretty
节点升级与降级
bash复制编辑docker node promote <节点名称> # 将 Worker 升级为 Manager
docker node demote <节点名称> # 将 Manager 降级为 Worker
节点下线(暂停任务调度)
docker node update --availability drain <节点名称>
节点上线
docker node update --availability active <节点名称>
创建服务时常用的命令格式如下:
bash复制编辑docker service create --name <服务名> \
[-d] [-p] [-e] [--network] [--replicas] [--mount] \
image:tag
测试 1:指定副本数、端口映射
docker service create -d --name web-nginx --replicas 2 -p 80:80 nginx
测试 2:传递环境变量
bash复制编辑docker service create -d --name mysql --replicas=1 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASES=test \
mysql:5.7
查看所有服务:
docker service ls
查看指定服务及其任务分布:
docker service ps <服务名>
示例输出:
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
0jlt1yx8dcox mysql replicated 1/1 mysql:5.7 *:3306->3306/tcp
fxha9cy659vu web-nginx replicated 3/3 nginx:1.24.0 *:80->80/tcp
docker service ps mysql
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wit44m5i6plf mysql.1 mysql:5.7 master Running Running 3 minutes ago
docker service rm <服务名称>
服务模式
示例:
docker service create --name cadvisor --mode global \
--mount type=bind,src=/,dst=/rootfs,readonly \
--mount type=bind,src=/var/run,dst=/var/run \
--mount type=bind,src=/sys,dst=/sys,readonly \
--mount type=bind,src=/var/lib/docker/,dst=/var/lib/docker,readonly \
--publish 8888:8080 \
gcr.io/cadvisor/cadvisor:latest
调度约束
通过指定调度约束,可以控制服务任务只在符合要求的节点上运行。
根据节点主机名调度:
docker service create --name my-service \
--constraint 'node.hostname == node01' \
nginx:latest
根据自定义标签调度:
给节点添加自定义 Label
在 Manager 节点上执行(假设给 node01 添加 hm=node01
):
docker node update --label-add hm=node01 node01
查看节点标签:
docker node inspect node01 --pretty
使用标签调度创建服务
docker service create --name my-service \
--constraint 'node.labels.hm == node01' \
nginx:latest
在 docker-compose.yml
文件中也可通过 deploy.placement.constraints
设置:
version: '3.8'
services:
web:
image: nginx:latest
deploy:
replicas: 1
placement:
constraints:
- "node.labels.hm == node01"
ports:
- "80:80"
部署命令:
docker stack deploy -c docker-compose.yml mystack
移除节点标签
docker node update --label-rm hm node01
查看服务日志:
docker service logs <服务名>
弹性伸缩指动态增加或减少服务任务数。
创建服务时指定副本数
docker service create -d --name mysql --replicas=2 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
在线伸缩命令
使用 update 命令:
docker service update --replicas <新副本数> <服务名>
或者使用 scale 命令:
docker service scale <服务名>=<副本数>
滚动更新允许在不中断服务的情况下更新服务。常用于灰度发布与镜像升级。
例如升级 MySQL 服务镜像版本,从 v5.7 到 v8.0,同时调整副本数量:
docker service update --replicas 5 \
--image mysql:8.0 \
--update-delay 60s \
--update-parallelism 5 \
mysql
参数说明:
--update-delay
:指定滚动更新每个任务之间的延时(支持秒、分钟、小时)。--update-parallelism
:指定同时更新的任务数。有两种方式:
方式一:使用 rollback 命令
docker service rollback mysql
此命令会回滚到上次成功部署的状态。
方式二:手动指定旧版本进行更新
docker service update --image mysql:5.7 mysql
查看更新状态
docker service inspect --pretty mysql
输出中 UpdateConfig
部分会显示当前服务的更新状态,例如 rollback_completed
表示已回滚。
docker service create
的局限该命令一次只能创建一个服务,多个服务时较为繁琐,因此推荐使用 Compose 文件配合 docker stack deploy
部署整个应用堆栈。
在 Compose 文件中,可在 deploy
下配置与 Swarm 相关的属性。请注意,使用 docker-compose up
时会忽略 deploy
部分,因此必须通过 docker stack deploy
部署。
示例:
yaml复制编辑version: '3.8'
services:
web:
image: nginx:latest
deploy:
replicas: 2 # 服务副本数
mode: replicated # 服务模式:replicated(默认)或 global
placement:
constraints:
- "node.hostname == node01" # 根据主机名调度
- "node.labels.hm == node01" # 根据自定义标签调度
restart_policy:
condition: on-failure # 仅在容器异常退出时重启
delay: 10s # 尝试重启的间隔时间
max_attempts: 3 # 最大重启尝试次数
ports:
- "80:80"
使用以下命令部署堆栈:
docker stack deploy -c docker-compose.yml mystack
查看堆栈列表:
docker stack ls
查看堆栈服务:
docker stack services mystack
查看堆栈任务:
docker stack ps mystack
删除堆栈:
docker stack rm mystack