找回密码
 立即注册

QQ登录

只需一步,快速开始

peUfSYR.png
查看: 52|回复: 0

Day 26 Docker Swarm 集群搭建

[复制链接]

876

主题

13

回帖

2808

积分

管理员

积分
2808
发表于 2026-3-29 16:17:55 | 显示全部楼层 |阅读模式
还记得小时候搬东西吗?一个人搬一台冰箱,累得半死还搬不动。但叫上三五个兄弟,嘿,轻轻松松就上了五楼。Docker Swarm 干的就是这事儿——把一群"单打独斗"的服务器组织成一个团队,让它们像一台超级计算机一样协同工作。

当你的应用从日均 100 访问量涨到 10 万,单机扛不住了怎么办?加内存?换 CPU?这叫纵向扩展,迟早有天花板。真正的出路是横向扩展——多搞几台机器一起干活。而 Docker Swarm 就是帮你把这些机器"拧成一股绳"的工具。

本文你将学到

  • Swarm 集群的核心架构和角色分工
  • 如何用两条命令组建一个集群
  • Service 的创建、扩缩容和滚动更新
  • Swarm 内置负载均衡的工作原理
  • 生产环境常见问题排查
    阅读时间:12 分钟 | 实操时间:30 分钟 | 难度等级:中级

    ━━━━━━━━━━━━━━━━━━━━

    一、Swarm 是什么?先看架构

    用一个比方来理解:Swarm 集群就像一个施工队。有个工头(Manager)负责接活、分配任务、盯进度;还有一帮工人(Worker)负责埋头干活。工头自己也可以干活,但主要职责是管理。

    来看整体架构:
    1.                     ┌─────────────────────────────────┐
    2.                     │          Swarm 集群              │
    3.                     │                                  │
    4.                     │   ┌──────────┐                   │
    5.           用户请求 ──┤──>│ Manager  │ (调度 + Raft共识)  │
    6.                     │   └────┬─────┘                   │
    7.                     │        │ 任务分发                  │
    8.                     │   ┌────┴─────────────┐           │
    9.                     │   │    │    │        │           │
    10.                     │   v    v    v        v           │
    11.                     │  ┌──┐ ┌──┐ ┌──┐  ┌──┐          │
    12.                     │  │W1│ │W2│ │W3│  │W4│          │
    13.                     │  └──┘ └──┘ └──┘  └──┘          │
    14.                     │  Worker Worker Worker Worker     │
    15.                     └─────────────────────────────────┘
    复制代码

    核心概念

    | 概念 | 说明 | 类比 |
    |------|------|------|
    | Node | 集群中的一台机器 | 施工队的一个人 |
    | Manager | 管理节点,负责调度和状态维护 | 工头 |
    | Worker | 工作节点,负责运行容器 | 工人 |
    | Service | 你要运行的应用定义 | 一份施工图纸 |
    | Task | Service 分配到具体节点的实例 | 图纸分配给某个工人的具体任务 |
    | Raft | Manager 之间的共识协议 | 工头们开会投票做决定 |

    一个关键设计:Manager 节点之间通过 Raft 协议保持数据一致。生产环境建议 3 个或 5 个 Manager(奇数个,方便投票不打平手)。Worker 想加多少加多少。

    ━━━━━━━━━━━━━━━━━━━━

    二、动手组建集群

    我们用三台机器来演示。没有三台机器?没关系,用
    1. docker-machine
    复制代码
    或者直接开三个虚拟机都行。这里假设你有三台机器:
    1. node1: 192.168.1.10  (Manager)
    2. node2: 192.168.1.11  (Worker)
    3. node3: 192.168.1.12  (Worker)
    复制代码

    2.1 初始化 Swarm(在 node1 上执行)
    1. docker swarm init --advertise-addr 192.168.1.10
    复制代码

    预期输出:
    1. Swarm initialized: current node (abc123def456) is now a manager.
    2. To add a worker to this swarm, run the following command:
    3.     docker swarm join --token SWMTKN-1-xxxxx 192.168.1.10:2377
    4. To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
    复制代码

    就这一条命令,集群就建好了。Docker 会生成一个 token,其他机器拿着这个 token 来"入伙"。

    2.2 Worker 加入集群(在 node2 和 node3 上执行)

    复制上面输出的 join 命令:
    1. docker swarm join --token SWMTKN-1-xxxxx 192.168.1.10:2377
    复制代码

    预期输出:
    1. This node joined a swarm as a worker.
    复制代码

    2.3 查看集群状态(在 Manager 上执行)
    1. docker node ls
    复制代码

    预期输出:
    1. ID                           HOSTNAME   STATUS   AVAILABILITY   MANAGER STATUS
    2. abc123def456 *               node1      Ready    Active         Leader
    3. ghi789jkl012                 node2      Ready    Active
    4. mno345pqr678                 node3      Ready    Active
    复制代码

    三个节点,一个 Leader(Manager),两个 Worker。集群就绑好了,比配置 Kubernetes 简单多了吧?

    ━━━━━━━━━━━━━━━━━━━━

    三、部署 Service

    集群有了,该在上面跑应用了。在 Swarm 里,你不直接运行容器,而是创建 Service。Service 是"声明式"的——你告诉 Swarm"我要 3 个 Nginx 实例",它帮你安排到合适的节点上。

    3.1 创建一个 Service
    1. docker service create \
    2.   --name web \
    3.   --replicas 3 \
    4.   --publish 80:80 \
    5.   nginx:alpine
    复制代码

    预期输出:
    1. qrs901tuv234
    2. overall progress: 3 out of 3 tasks
    3. 1/3: running   [==================================================>]
    4. 2/3: running   [==================================================>]
    5. 3/3: running   [==================================================>]
    6. verify: Service converged
    复制代码

    三个 Nginx 副本被分配到了三个节点上。

    3.2 查看 Service 状态
    1. docker service ls
    复制代码
    1. ID             NAME   MODE         REPLICAS   IMAGE          PORTS
    2. qrs901tuv234   web    replicated   3/3        nginx:alpine   *:80->80/tcp
    复制代码

    查看每个副本运行在哪个节点:
    1. docker service ps web
    复制代码
    1. ID            NAME    IMAGE          NODE    DESIRED STATE   CURRENT STATE
    2. aaa111        web.1   nginx:alpine   node1   Running         Running 2 minutes ago
    3. bbb222        web.2   nginx:alpine   node2   Running         Running 2 minutes ago
    4. ccc333        web.3   nginx:alpine   node3   Running         Running 2 minutes ago
    复制代码

    3.3 弹性扩缩容

    流量突然涨了?加副本:
    1. docker service scale web=5
    复制代码

    流量回落了?缩回来:
    1. docker service scale web=2
    复制代码

    就这么简单。Swarm 会自动在可用节点上分配或回收容器。

    ━━━━━━━━━━━━━━━━━━━━

    四、滚动更新

    应用要升级版本了,总不能停服吧?Swarm 支持滚动更新——一个一个换,用户完全无感知。

    4.1 执行滚动更新

    假设要把 Nginx 从 alpine 更新到最新版:
    1. docker service update \
    2.   --image nginx:latest \
    3.   --update-parallelism 1 \
    4.   --update-delay 10s \
    5.   web
    复制代码

    这条命令的意思是:每次更新 1 个副本,更新完等 10 秒再更新下一个。

    更新过程中可以实时查看:
    1. docker service ps web
    复制代码

    你会看到旧副本逐个被新副本替换。

    4.2 更新出问题?回滚

    如果新版本有 Bug,一条命令回滚:
    1. docker service rollback web
    复制代码

    Swarm 会自动把所有副本回退到上一个版本。这就像游戏里的存档读档,关键时刻能救命。

    你也可以在创建 Service 时就配好自动回滚策略:
    1. docker service create \
    2.   --name web \
    3.   --replicas 3 \
    4.   --update-failure-action rollback \
    5.   --update-max-failure-ratio 0.3 \
    6.   nginx:alpine
    复制代码

    意思是:如果超过 30% 的副本更新失败,自动回滚。

    ━━━━━━━━━━━━━━━━━━━━

    五、内置负载均衡

    Swarm 有个很贴心的设计叫 Routing Mesh(路由网格)。你访问集群中任意节点的 80 端口,Swarm 都会自动把请求转发到运行了该 Service 的节点上。
    1.          用户请求 :80
    2.               │
    3.      ┌────────┼────────┐
    4.      v        v        v
    5.    node1    node2    node3
    6.    (web.1)  (web.2)  (web.3)
    复制代码

    即使某个节点上没有运行对应的容器,请求打到这个节点也照样能处理——Swarm 内部会帮你转发。这意味着你可以把任意节点的 IP 挂到负载均衡器后面,不用关心容器具体跑在哪儿。

    验证一下:
    1. # 在任意节点上执行,都能访问到 Service
    2. curl http://192.168.1.10
    3. curl http://192.168.1.11
    4. curl http://192.168.1.12
    复制代码

    三个地址都能返回 Nginx 欢迎页。

    ━━━━━━━━━━━━━━━━━━━━

    六、实战:部署一个完整应用

    来个实际的例子,部署一个带 Redis 后端的 Web 应用:
    1. # 先创建一个 overlay 网络(跨节点通信)
    2. docker network create --driver overlay app-net
    3. # 部署 Redis
    4. docker service create \
    5.   --name redis \
    6.   --network app-net \
    7.   --replicas 1 \
    8.   redis:alpine
    9. # 部署 Web 应用
    10. docker service create \
    11.   --name app \
    12.   --network app-net \
    13.   --replicas 3 \
    14.   --publish 8080:5000 \
    15.   --env REDIS_HOST=redis \
    16.   my-web-app:latest
    复制代码

    注意这里用了 overlay 网络。这是 Swarm 的跨节点网络方案——不管容器跑在哪台机器上,通过 overlay 网络都能互相访问。Service 名字(redis)直接当域名用,Swarm 内置了 DNS 解析。

    ━━━━━━━━━━━━━━━━━━━━

    七、常见问题 Q&A

    Q1:Manager 挂了怎么办?

    如果是单 Manager,那就完蛋了(集群不可管理,但已运行的容器不受影响)。所以生产环境至少 3 个 Manager。Raft 协议能容忍 (N-1)/2 个节点故障——3 个 Manager 允许挂 1 个,5 个允许挂 2 个。

    添加 Manager 节点:
    1. # 在现有 Manager 上获取 token
    2. docker swarm join-token manager
    3. # 在新节点上执行返回的命令
    4. docker swarm join --token SWMTKN-1-manager-token 192.168.1.10:2377
    复制代码

    Q2:Worker 挂了,上面的容器怎么办?

    Swarm 会自动在其他可用节点上重新调度这些容器。比如你有 3 个副本分布在 3 个 Worker 上,其中一个 Worker 挂了,Swarm 会在剩余 2 个 Worker 上启动新副本,始终保持 3 个副本运行。

    Q3:Swarm 和 Kubernetes 怎么选?

    简单说:小团队、中小规模(几十个节点以内)用 Swarm,够用且运维成本低;大规模、复杂编排需求用 Kubernetes。Swarm 的优势是"零配置"——Docker 内置,不需要额外装任何东西。Kubernetes 功能强大但学习曲线陡峭。先用 Swarm 跑起来,等真到了 Swarm 撑不住的那天再迁移也不迟。

    ━━━━━━━━━━━━━━━━━━━━

    八、管理命令速查
    1. # 集群管理
    2. docker swarm init                    # 初始化集群
    3. docker swarm join                    # 加入集群
    4. docker swarm leave                   # 离开集群
    5. docker swarm leave --force           # Manager 强制离开
    6. # 节点管理
    7. docker node ls                       # 列出所有节点
    8. docker node inspect <node>           # 查看节点详情
    9. docker node promote <node>           # Worker 升级为 Manager
    10. docker node demote <node>            # Manager 降级为 Worker
    11. docker node rm <node>                # 移除节点
    12. # Service 管理
    13. docker service create                # 创建服务
    14. docker service ls                    # 列出服务
    15. docker service ps <service>          # 查看服务任务
    16. docker service logs <service>        # 查看服务日志
    17. docker service scale <service>=N     # 扩缩容
    18. docker service update                # 更新服务
    19. docker service rollback <service>    # 回滚服务
    20. docker service rm <service>          # 删除服务
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    小结

    今天我们把 Docker 从"单机"推向了"集群"。核心就三件事:

  • 组建集群
    1. swarm init
    复制代码
    +
    1. swarm join
    复制代码
    ,两条命令搞定
  • 部署服务
    1. service create
    复制代码
    声明式部署,自动调度到合适节点
  • 滚动更新
    1. service update
    复制代码
    无缝升级,出问题一键回滚

    Swarm 的设计哲学和 Docker 一脉相承——简单够用。它不像 Kubernetes 那样什么都能干,但对于大多数中小项目来说,它就是那个"刚刚好"的方案。

    明天 Day 27,我们聊聊生产部署策略——怎么把开发环境的容器安全、高效地推到线上去,包括 CI/CD 流水线、镜像管理和部署最佳实践。这是从"会用 Docker"到"用好 Docker"的关键一步。
  • 您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    扫码关注微信公众号

    Archiver|手机版|小黑屋|风叶林

    GMT+8, 2026-5-8 21:43 , Processed in 0.178881 second(s), 20 queries .

    Powered by 风叶林

    © 2001-2026 Discuz! Team.

    快速回复 返回顶部 返回列表