Skip to main content

docker-swarm

Docker Swarm

tip

适用场景deploy 配置仅在 Docker Swarm 模式 下生效(通过 docker stack deploy 部署), 用于定义服务的部署策略、高可用规则、资源限制等。单机模式(docker-compose up)会自动忽略该配置,无需删除。

  1. mode:部署模式
  • 指定服务的部署模式,有两种可选值:
  • replicated:默认值,指定服务的副本数量(通过 replicas 配置)。
  • global:每个节点只运行 1 个副本(适合日志收集、监控等节点级服务)。
services:
web:
image: nginx
deploy:
mode: replicated # 或 global

  1. replicas:副本数量
  • 当 mode: replicated 时,指定服务需要运行的副本数(整数)。
services:
api:
image: my-api
deploy:
mode: replicated
replicas: 3 # 启动 3 个副本

  1. placement:节点部署约束
  • 控制服务在哪些 Swarm 节点上运行,通过 constraints(强制约束)或 preferences(偏好)配置。
  • 常用约束条件:
  • node.hostname == 节点名称:指定节点 hostname
  • node.id == 节点ID:指定节点 ID
  • node.role == manager/worker:指定节点角色(管理节点 / 工作节点)
  • node.labels.标签名 == 值:通过节点标签筛选(需先给节点打标签:docker node update --label-add 标签名=值 节点名)
services:
surguard:
image: surguard:latest
deploy:
placement:
constraints:
- node.hostname == server-01 # 仅在 hostname 为 server-01 的节点运行
- node.labels.env == production # 仅在有 env=production 标签的节点运行

  1. resources:资源限制与保留
  • 限制服务使用的 CPU、内存等资源,避免单个服务耗尽节点资源。

  • limits:硬限制(服务最多使用的资源,超出可能被终止)。

  • reservations:资源保留(保证服务至少能使用的资源,节点需有足够资源才会调度)。

services:
mysql:
image: mysql
deploy:
resources:
limits:
cpus: '0.5' # 最多使用 0.5 个 CPU 核心(1 = 1 核心)
memory: 512M # 最多使用 512MB 内存
reservations:
cpus: '0.2' # 至少保留 0.2 个 CPU 核心
memory: 256M # 至少保留 256MB 内存

  1. restart_policy:重启策略
  • 定义服务容器退出后的重启规则(类似 restart 配置,但仅在 Swarm 模式生效)。

  • condition:重启条件(none:不重启;on-failure:失败时重启;any:任何情况都重启,默认)。

  • delay:重启延迟(如 5s,默认 0s)。

  • max_attempts:最大重启次数(超出后停止,默认永不停止)。

  • window:判断重启是否成功的窗口时间(如 120s,默认 0s)。

services:
redis:
image: redis
deploy:
restart_policy:
condition: on-failure # 仅在失败时重启
delay: 10s # 失败后延迟 10 秒重启
max_attempts: 3 # 最多重启 3 次
window: 60s # 60 秒内稳定运行则视为重启成功

  1. update_config:滚动更新配置
  • 定义服务更新(如镜像版本更新)时的策略,避免更新过程中服务中断。

  • parallelism:同时更新的副本数(默认 1)。

  • delay:批次更新之间的延迟(如 10s,默认 0s)。

  • failure_action:更新失败时的动作(continue:继续;rollback:回滚;pause:暂停,默认)。

  • monitor:更新后监控健康状态的时间(如 60s,默认 0s)。

  • max_failure_ratio:允许更新失败的最大比例(如 0.2 表示 20%,默认 0)。

services:
web:
image: my-web:v1
deploy:
update_config:
parallelism: 2 # 每次更新 2 个副本
delay: 30s # 两批更新间隔 30 秒
failure_action: rollback # 失败时自动回滚到上一版本
monitor: 60s # 每个副本更新后监控 60 秒是否健康

  1. rollback_config:回滚配置
  • 定义更新失败时的回滚策略(与 update_config 配置项类似)
services:
web:
image: my-web:v1
deploy:
rollback_config:
parallelism: 1 # 每次回滚 1 个副本
delay: 10s # 回滚批次间隔 10 秒
failure_action: pause # 回滚失败时暂停

  1. labels:部署标签
  • 为服务的部署对象添加元数据标签(区别于服务自身的 labels,仅用于部署层面)
services:
api:
image: my-api
deploy:
labels:
- "deploy.version=v1.2.3"
- "deploy.maintainer=dev-team"

  1. endpoint_mode:服务发现端点模式
  • 定义 Swarm 如何暴露服务的网络端点(供外部访问)。

  • vip:默认值,通过虚拟 IP(VIP)暴露服务,自动负载均衡到副本。

  • dnsrr:通过 DNS 轮询(DNS round-robin)暴露,客户端需自己处理负载均衡。

  • dnsrr 适合需要直接访问具体副本的场景(如状态 ful 服务)。

services:
db:
image: postgres
deploy:
endpoint_mode: dnsrr # 用 DNS 轮询暴露端点

Node

# 单机部署(自动使用本机IP)
docker swarm init

# 指定IP初始化(虚拟机/多网卡场景)
docker swarm init --advertise-addr 192.168.1.100 # 替换为你的主机IP

# 获取 worker 节点加入命令
docker swarm join-token worker

# 获取 manager 节点加入命令(扩展管理节点,高可用)
docker swarm join-token manager

# Worker 节点加入(从管理节点获取命令后执行)
docker swarm join --token SWMTKN-1-xxx-xxx 192.168.1.100:2377

# Manager 节点加入(高可用集群)
docker swarm join --token SWMTKN-1-xxx-xxx 192.168.1.100:2377

# 查看所有节点(含角色、状态)
docker node ls

# 查看节点详情(如标签、资源)
docker node inspect --pretty 节点ID/节点名

# 给节点打标签(如:标记为生产环境节点)
docker node update --label-add env=production 节点名/节点ID

# 查看节点标签
docker node inspect --format '{{.Spec.Labels}}' 节点名

# 删除节点标签
docker node update --label-rm env 节点名


# 将 worker 节点提升为 manager(扩展管理节点)
docker node promote 节点名

# 将 manager 节点降级为 worker
docker node demote 节点名

# 移除节点(先排空任务,再删除)
# 1. 排空节点(迁移所有服务到其他节点)
docker node update --availability drain 节点名
# 2. 删除节点(从集群中移除)
docker node rm 节点名

# 强制删除不可用节点(如节点故障)
docker node rm -f 节点名

docker swarm leave --force

Stack

# 格式:docker stack deploy -f 文件1 -f 文件2 ... 栈名
docker stack deploy -f base.yml -f services.yml -f surgard.yml mystack

# 查看所有栈
docker stack ls

# 查看栈内所有服务
docker stack services mystack

# 查看栈详情(含服务、网络、卷)
docker stack ps mystack

# 同部署命令,修改配置文件后重新执行即可触发滚动更新
docker stack deploy -f base.yml -f services.yml -f surgard.yml mystack

docker stack rm mystack


Service

# 查看所有服务
docker service ls

# 查看指定服务详情(如:mystack_sursen-admin)
docker service inspect --pretty mystack_sursen-admin

# 查看服务运行的容器实例(含节点分布)
docker service ps mystack_sursen-admin

# 格式:docker service scale 服务名=副本数
docker service scale mystack_sursen-admin=3 # 扩展为3个副本
docker service scale mystack_sursen-admin=1 # 缩减为1个副本


# 更新服务镜像(如:升级 sursen-admin 版本)
docker service update --image registry.cn-beijing.aliyuncs.com/safewarehouse/sursen-admin:1.0.5.4 mystack_sursen-admin

# 更新服务资源限制
docker service update --limit-cpu 1 --limit-memory 1G mystack_elasticsearch

# 强制更新(忽略配置差异,重新部署所有副本)
docker service update --force mystack_sursen-admin

# 格式:docker service rollback 服务名
docker service rollback mystack_sursen-admin

# 查看服务日志(实时输出,含所有副本)
docker service logs -f mystack_sursen-admin

# 查看指定副本的日志(先通过 docker service ps 获取副本ID)
docker service logs -f --no-trunc mystack_sursen-admin 副本ID

# 查看最近100行日志
docker service logs --tail 100 mystack_mysql

# 格式:docker exec -it 容器ID/容器名 命令
# 1. 先获取服务的容器ID
docker service ps mystack_sursen-admin
# 2. 进入容器(如:容器ID为 abc123)
docker exec -it abc123 /bin/bash

# 停止服务(保留服务配置,可重新启动)
docker service scale mystack_sursen-admin=0

# 彻底删除服务
docker service rm mystack_sursen-admin

网络与数据卷管理(Swarm 环境)

# 查看所有网络(含 Swarm overlay 网络)
docker network ls

# 查看指定网络详情(如:safe_net)
docker network inspect safe_net

# 删除无用网络(栈删除后残留)
docker network prune

# 查看所有卷(含栈创建的命名卷)
docker volume ls

# 查看卷详情(如:mystack_mysql_data)
docker volume inspect mystack_mysql_data

# 备份卷数据(如:备份 mysql 数据)
docker run --rm -v mystack_mysql_data:/source -v $(pwd):/backup alpine tar -czvf /backup/mysql_backup.tar.gz -C /source .

# 删除无用卷(栈删除后残留)
docker volume prune

监控与故障排查

# 实时查看集群事件(服务更新、节点状态变化等)
docker events --filter scope=swarm

# 查看节点 CPU/内存/磁盘使用情况
docker node stats

# 查看服务启动失败的原因(重点看 "Error" 字段)
docker service ps --no-trunc mystack_sursen-admin

# 查看容器启动日志(即使容器已退出)
docker logs 容器ID(从上面命令获取)

# 查看服务健康检查状态(需配置 healthcheck)
docker service inspect --format '{{range .Spec.TasksTemplate.ContainerSpec.Healthcheck}}{{.Test}}{{end}}' mystack_mysql

deploy 配置

services:
sursen-admin:
image: registry.cn-beijing.aliyuncs.com/safewarehouse/sursen-admin:1.0.5.3
container_name: sursen-admin
ports:
- "9010:9010"
volumes:
- ./sursen-admin/config.docker.yaml:/sursen_admin_server/config.docker.yaml
networks:
- safe_net
# Swarm 部署核心配置
deploy:
mode: replicated # 按副本数部署
replicas: 2 # 2 个副本实现高可用
placement: # 部署约束
constraints:
- node.labels.env == production # 仅部署在生产环境节点
resources: # 资源限制
limits:
cpus: '0.8'
memory: 1G
reservations:
cpus: '0.4'
memory: 512M
update_config: # 滚动更新
parallelism: 1
delay: 30s
failure_action: rollback
monitor: 60s
max_failure_ratio: 0.3
rollback_config: # 回滚策略
parallelism: 1
delay: 10s
failure_action: pause
restart_policy: # 重启规则
condition: on-failure
delay: 10s
max_attempts: 3
window: 60s
endpoint_mode: vip # 服务发现模式
labels: # 部署标签
- "deploy.module=sursen-admin"
- "deploy.version=1.0.5.3"