冷蟊初退 孤灯野澜 志起鸡鸣 墓不悲秋 技术交流 软件开发 商业合作 加Q:411239339

Day 26 Docker Swarm 集群搭建

浏览:16次阅读
没有评论

共计 5255 个字符,预计需要花费 14 分钟才能阅读完成。

还记得小时候搬东西吗?一个人搬一台冰箱,累得半死还搬不动。但叫上三五个兄弟,嘿,轻轻松松就上了五楼。Docker Swarm 干的就是这事儿——把一群 " 单打独斗 " 的服务器组织成一个团队,让它们像一台超级计算机一样协同工作。

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

本文你将学到

  • Swarm 集群的核心架构和角色分工
  • 如何用两条命令组建一个集群
  • Service 的创建、扩缩容和滚动更新
  • Swarm 内置负载均衡的工作原理
  • 生产环境常见问题排查

阅读时间:12 分钟 | 实操时间:30 分钟 | 难度等级:中级


一、Swarm 是什么?先看架构

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

来看整体架构:

                    ┌─────────────────────────────────┐
                    │          Swarm 集群              │
                    │                                  │
                    │   ┌──────────┐                   │
          用户请求 ──┤──>│ Manager  │ (调度 + Raft 共识)  │
                    │   └────┬─────┘                   │
                    │        │ 任务分发                  │
                    │   ┌────┴─────────────┐           │
                    │   │    │    │        │           │
                    │   v    v    v        v           │
                    │  ┌──┐ ┌──┐ ┌──┐  ┌──┐          │
                    │  │W1│ │W2│ │W3│  │W4│          │
                    │  └──┘ └──┘ └──┘  └──┘          │
                    │  Worker Worker Worker Worker     │
                    └─────────────────────────────────┘

核心概念

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

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


二、动手组建集群

我们用三台机器来演示。没有三台机器?没关系,用 docker-machine 或者直接开三个虚拟机都行。这里假设你有三台机器:

node1: 192.168.1.10  (Manager)
node2: 192.168.1.11  (Worker)
node3: 192.168.1.12  (Worker)

2.1 初始化 Swarm(在 node1 上执行)

docker swarm init --advertise-addr 192.168.1.10

预期输出:

Swarm initialized: current node (abc123def456) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-xxxxx 192.168.1.10:2377

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 命令:

docker swarm join --token SWMTKN-1-xxxxx 192.168.1.10:2377

预期输出:

This node joined a swarm as a worker.

2.3 查看集群状态(在 Manager 上执行)

docker node ls

预期输出:

ID                           HOSTNAME   STATUS   AVAILABILITY   MANAGER STATUS
abc123def456 *               node1      Ready    Active         Leader
ghi789jkl012                 node2      Ready    Active
mno345pqr678                 node3      Ready    Active

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


三、部署 Service

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

3.1 创建一个 Service

docker service create \
  --name web \
  --replicas 3 \
  --publish 80:80 \
  nginx:alpine

预期输出:

qrs901tuv234
overall progress: 3 out of 3 tasks
1/3: running   [==================================================>]
2/3: running   [==================================================>]
3/3: running   [==================================================>]
verify: Service converged

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

3.2 查看 Service 状态

docker service ls
ID             NAME   MODE         REPLICAS   IMAGE          PORTS
qrs901tuv234   web    replicated   3/3        nginx:alpine   *:80->80/tcp

查看每个副本运行在哪个节点:

docker service ps web
ID            NAME    IMAGE          NODE    DESIRED STATE   CURRENT STATE
aaa111        web.1   nginx:alpine   node1   Running         Running 2 minutes ago
bbb222        web.2   nginx:alpine   node2   Running         Running 2 minutes ago
ccc333        web.3   nginx:alpine   node3   Running         Running 2 minutes ago

3.3 弹性扩缩容

流量突然涨了?加副本:

docker service scale web=5

流量回落了?缩回来:

docker service scale web=2

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


四、滚动更新

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

4.1 执行滚动更新

假设要把 Nginx 从 alpine 更新到最新版:

docker service update \
  --image nginx:latest \
  --update-parallelism 1 \
  --update-delay 10s \
  web

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

更新过程中可以实时查看:

docker service ps web

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

4.2 更新出问题?回滚

如果新版本有 Bug,一条命令回滚:

docker service rollback web

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

你也可以在创建 Service 时就配好自动回滚策略:

docker service create \
  --name web \
  --replicas 3 \
  --update-failure-action rollback \
  --update-max-failure-ratio 0.3 \
  nginx:alpine

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


五、内置负载均衡

Swarm 有个很贴心的设计叫 Routing Mesh(路由网格)。你访问集群中任意节点的 80 端口,Swarm 都会自动把请求转发到运行了该 Service 的节点上。

         用户请求 :80
              │
     ┌────────┼────────┐
     v        v        v
   node1    node2    node3
   (web.1)  (web.2)  (web.3)

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

验证一下:

# 在任意节点上执行,都能访问到 Service
curl http://192.168.1.10
curl http://192.168.1.11
curl http://192.168.1.12

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


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

来个实际的例子,部署一个带 Redis 后端的 Web 应用:

# 先创建一个 overlay 网络(跨节点通信)docker network create --driver overlay app-net

# 部署 Redis
docker service create \
  --name redis \
  --network app-net \
  --replicas 1 \
  redis:alpine

# 部署 Web 应用
docker service create \
  --name app \
  --network app-net \
  --replicas 3 \
  --publish 8080:5000 \
  --env REDIS_HOST=redis \
  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 节点:

# 在现有 Manager 上获取 token
docker swarm join-token manager

# 在新节点上执行返回的命令
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 撑不住的那天再迁移也不迟。


八、管理命令速查

# 集群管理
docker swarm init                    # 初始化集群
docker swarm join                    # 加入集群
docker swarm leave                   # 离开集群
docker swarm leave --force           # Manager 强制离开

# 节点管理
docker node ls                       # 列出所有节点
docker node inspect            # 查看节点详情
docker node promote            # Worker 升级为 Manager
docker node demote             # Manager 降级为 Worker
docker node rm                 # 移除节点

# Service 管理
docker service create                # 创建服务
docker service ls                    # 列出服务
docker service ps           # 查看服务任务
docker service logs         # 查看服务日志
docker service scale =N     # 扩缩容
docker service update                # 更新服务
docker service rollback     # 回滚服务
docker service rm           # 删除服务 

小结

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

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

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

明天 Day 27,我们聊聊生产部署策略——怎么把开发环境的容器安全、高效地推到线上去,包括 CI/CD 流水线、镜像管理和部署最佳实践。这是从 " 会用 Docker" 到 " 用好 Docker" 的关键一步。

正文完
创作不易,扫码加点动力
post-qrcode
 0
果较瘦
版权声明:本站原创文章,由 果较瘦 于2026-03-29发表,共计5255字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。