强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 11 章 · Swarm 部署:deploy、replicas、update_config

第 11 章 · Docker Swarm 部署

11.1 Docker Swarm 简介

Docker Swarm 是 Docker 原生的集群编排工具,将多台 Docker 主机组成一个虚拟的 Docker 引擎。

Swarm vs Compose 独立模式

维度Compose 独立模式Swarm 模式
节点数单机多节点集群
服务发现内部 DNS内部 DNS + Routing Mesh
负载均衡内置 Ingress LB
滚动更新不支持✅ 原生支持
自愈restart 策略自动重新调度
Secrets基于文件加密分发 + 内存存储
配置管理文件挂载集群级 Config 对象
部署命令docker compose updocker stack deploy

何时使用 Swarm?

你的需求是什么?
├── 本地开发/测试 → Compose 独立模式 ✅
├── 单机轻量生产 → Compose + restart 策略 ✅
├── 多节点高可用 → Swarm ✅ 或 Kubernetes
├── 大规模企业级 → Kubernetes ✅
└── 中小团队简单集群 → Swarm ✅(运维复杂度远低于 K8s)

11.2 初始化 Swarm 集群

单节点 Swarm

# 初始化 Swarm
docker swarm init

# 查看节点
docker node ls
# ID    HOSTNAME   STATUS   AVAILABILITY   MANAGER STATUS
# xxx   node1      Ready    Active         Leader

多节点 Swarm

# 在 Manager 节点上
docker swarm init --advertise-addr 192.168.1.100

# 输出 join token,用于 Worker 加入
# docker swarm join --token SWMTKN-xxx 192.168.1.100:2377

# 在 Worker 节点上执行上述 join 命令
docker swarm join --token SWMTKN-xxx 192.168.1.100:2377

# 查看集群节点
docker node ls

节点角色

角色说明最少节点
Manager运行 Swarm 管理服务(Raft 共识)1(生产建议 3 或 5)
Worker运行应用服务0+

11.3 deploy 配置

deploy 配置专门用于 Swarm 模式的部署策略。

完整的 deploy 配置

services:
  web:
    image: myapp:latest
    deploy:
      # 副本数
      replicas: 3

      # 部署约束
      placement:
        constraints:
          - node.role == worker       # 只部署到 Worker 节点
          - node.labels.zone == east  # 部署到标记为 east 的节点
        preferences:
          - spread: node.labels.zone  # 尽量分散到不同可用区

      # 资源限制
      resources:
        limits:
          cpus: "0.50"               # 最多使用 0.5 个 CPU
          memory: 512M               # 最多使用 512MB 内存
        reservations:
          cpus: "0.25"               # 保留 0.25 个 CPU
          memory: 256M               # 保留 256MB 内存
          devices:
            - capabilities: [gpu]    # 保留 GPU
              count: 1

      # 滚动更新策略
      update_config:
        parallelism: 1               # 每次更新 1 个容器
        delay: 30s                   # 每批更新间隔
        failure_action: rollback     # 失败时回滚
        monitor: 60s                 # 监控 60s 判断是否成功
        max_failure_ratio: 0.1       # 允许 10% 失败率
        order: start-first           # 先启动新容器再停止旧容器

      # 回滚策略
      rollback_config:
        parallelism: 1
        delay: 10s
        failure_action: pause
        monitor: 30s
        max_failure_ratio: 0
        order: stop-first

      # 重启策略
      restart_policy:
        condition: on-failure        # none | on-failure | any
        delay: 5s                    # 重启前等待
        max_attempts: 3              # 最大重启次数
        window: 120s                 # 判断重启成功的时间窗口

      # 端点模式
      endpoint_mode: vip             # vip(默认)| dnsrr

      # 服务标签
      labels:
        com.example.project: myapp
        com.example.environment: production

    # 网络
    networks:
      - frontend
      - backend

    # 端口(Swarm 模式下使用 ingress 发布)
    ports:
      - target: 80
        published: "80"
        protocol: tcp
        mode: ingress                # ingress(集群级)| host(单节点)

11.4 副本与扩展

设置副本数

services:
  web:
    image: myapp:latest
    deploy:
      replicas: 3    # 运行 3 个副本

动态扩缩容

# 使用 docker service scale
docker service scale myapp_web=5

# 使用 docker compose(需要 deploy 配置)
docker compose up -d --scale web=5

# 注意:--scale 会覆盖 compose.yaml 中的 replicas
# 但不能用于已发布到 Swarm 的 stack

副本分布

services:
  web:
    deploy:
      replicas: 6
      placement:
        constraints:
          - node.role == worker
        preferences:
          - spread: node.labels.zone   # 均匀分布到不同 zone
Zone A (Worker 1):  web.1  web.3  web.5
Zone B (Worker 2):  web.2  web.4  web.6

11.5 滚动更新

更新策略

services:
  web:
    image: myapp:1.0.0
    deploy:
      replicas: 6
      update_config:
        parallelism: 2        # 每次同时更新 2 个
        delay: 10s            # 两批之间等待 10s
        failure_action: rollback
        monitor: 30s
        order: start-first    # 推荐:先启新的再停旧的

更新时序

初始状态: [v1 v1 v1 v1 v1 v1]

第 1 批 (parallelism=2):
  启动 v2, v2 → 停止 v1, v1
  结果: [v1 v1 v1 v1 v2 v2]

等待 10s...

第 2 批:
  启动 v2, v2 → 停止 v1, v1
  结果: [v1 v1 v2 v2 v2 v2]

等待 10s...

第 3 批:
  启动 v2, v2 → 停止 v1, v1
  结果: [v2 v2 v2 v2 v2 v2]  ✅ 更新完成

更新命令

# 更新镜像版本
docker service update --image myapp:2.0.0 myapp_web

# 使用 Compose(修改 compose.yaml 后重新 deploy)
docker stack deploy -c compose.yaml myapp

# 手动回滚
docker service rollback myapp_web

start-first vs stop-first

顺序说明适用场景
start-first先启动新容器,再停止旧容器Web 服务(零停机)
stop-first先停止旧容器,再启动新容器有状态服务(端口冲突、数据一致性)

11.6 资源限制

services:
  web:
    deploy:
      resources:
        limits:
          cpus: "1.0"         # 硬限制:最多 1 个 CPU
          memory: 1G          # 硬限制:最多 1GB 内存
        reservations:
          cpus: "0.5"         # 软保证:至少 0.5 个 CPU
          memory: 512M        # 软保证:至少 512MB 内存

  # GPU 资源
  ml-worker:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1         # 使用 1 个 GPU
              capabilities: [gpu]

⚠️ 注意deploy.resources 仅在 Swarm 模式下生效。独立模式下使用 docker compose 时需要通过 docker run--cpus--memory 参数,或在 docker-compose.yaml 中不使用 deploy 而直接通过 mem_limit 等属性(V1 遗留方式)。


11.7 部署约束

节点约束

services:
  db:
    deploy:
      placement:
        constraints:
          # 节点角色
          - node.role == manager
          - node.role == worker

          # 节点 ID
          - node.id == abc123def

          # 节点主机名
          - node.hostname == server-01

          # 自定义标签
          - node.labels.zone == us-east
          - node.labels.disk == ssd
          - node.labels.environment == production

          # 操作系统
          - node.platform.os == linux
          - node.platform.arch == x86_64

标签管理

# 给节点添加标签
docker node update --label-add zone=us-east node1
docker node update --label-add disk=ssd node1
docker node update --label-add zone=us-west node2

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

11.8 Stack 部署

部署 Stack

# 初始化 Swarm(如果还没有)
docker swarm init

# 部署 Stack
docker stack deploy -c compose.yaml myapp

# 查看 Stack
docker stack ls

# 查看 Stack 的服务
docker stack services myapp

# 查看 Stack 的任务
docker stack ps myapp

Stack 更新

# 修改 compose.yaml 后重新部署
docker stack deploy -c compose.yaml myapp
# Swarm 会自动执行滚动更新

Stack 删除

docker stack rm myapp

与 docker compose 的区别

维度docker compose updocker stack deploy
模式独立模式Swarm 模式
build 指令✅ 支持❌ 不支持(需预构建镜像)
depends_on✅ 支持❌ 不支持
restart✅ 支持❌ 使用 restart_policy
网络创建默认 bridgeoverlay 网络
端口发布直接映射ingress routing mesh
Secrets基于文件加密分发

11.9 Overlay 网络

Swarm 使用 overlay 网络实现跨节点通信。

services:
  web:
    image: myapp:latest
    networks:
      - frontend
      - backend

  db:
    image: postgres:16
    networks:
      - backend

networks:
  frontend:
    driver: overlay
    attachable: true    # 允许非 Swarm 容器连接
  backend:
    driver: overlay
    internal: true      # 不允许外部访问

11.10 完整的 Swarm Stack 示例

# compose.swarm.yaml
services:
  web:
    image: myregistry.io/myapp-web:${VERSION:-latest}
    ports:
      - target: 80
        published: "80"
        mode: ingress
    networks:
      - frontend
      - backend
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
        order: start-first
        failure_action: rollback
      rollback_config:
        parallelism: 1
        order: stop-first
      restart_policy:
        condition: any
        delay: 5s
      placement:
        constraints:
          - node.role == worker
        preferences:
          - spread: node.labels.zone
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
        reservations:
          cpus: "0.25"
          memory: 256M
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: postgres:16-alpine
    networks:
      - backend
    volumes:
      - pgdata:/var/lib/postgresql/data
    secrets:
      - db_password
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.db == true
      resources:
        limits:
          memory: 1G

networks:
  frontend:
    driver: overlay
  backend:
    driver: overlay
    internal: true

volumes:
  pgdata:
    driver: local

secrets:
  db_password:
    external: true    # 使用 docker secret create 创建
# 部署
docker secret create db_password ./secrets/db_password.txt
docker stack deploy -c compose.swarm.yaml myapp

11.11 小结

概念说明
deploySwarm 专用配置,控制副本、更新、资源等
replicas服务副本数
update_config滚动更新策略(并行度、间隔、失败处理)
restart_policySwarm 模式的重启策略
placement部署约束,控制服务运行在哪些节点
docker stack deploy使用 Compose 文件部署 Swarm Stack
Overlay 网络跨节点容器通信

扩展阅读


上一章:第 10 章 · 敏感信息 ← | 下一章:第 12 章 · 日志 →