Docker Swarm 集群管理
Swarm 是 Docker 官方提供的容器编排(orchestration)工具,用于管理多个 Docker 主机组成的集群。自 Docker 1.12 起,Swarm 模式被集成到 Docker 引擎中,无需额外安装组件即可使用。Swarm 集群支持服务部署、自动扩缩容、滚动更新、负载均衡、高可用等特性,在实际项目中广泛用于微服务架构的部署与运维。
一、Swarm 核心概念
1. 节点(Node)
- Manager 节点:负责集群管理、任务调度、维护集群状态。可有多个(建议奇数个以实现 Raft 共识)。
- Worker 节点:执行任务(运行容器),不参与调度决策。
注:可以这样理解,集群中的主机叫做节点,有负责管理调度的Manager节点,还有实际执行任务的Worker节点,Manager节点决定Worker节点具体执行什么任务,什么时候执行。Manager节点本身也可以执行任务。
核心逻辑:
管理节点是"决策者"(负责接收指令、维护服务定义、调度容器),工作节点是"执行者"(运行容器、汇报状态)。用户所有的集群操作(创建/删除服务、扩缩容等)都通过管理节点完成,工作节点无需手动干预,由管理节点统一管控。
Manager 节点为什么是奇数个
Docker Swarm 中管理节点(Manager Node)需要设置为奇数个(1、3、5 等),核心原因与它采用的 Raft 共识算法有关。
Raft 算法的核心是"少数服从多数":当管理节点之间同步集群状态(如服务配置、节点信息等)时,必须获得超过半数节点的同意才能达成共识,确保数据一致性。
举几个例子:
- 若有 3 个管理节点:最多允许 1 个节点故障(3/2 + 1 = 2,即只要 2 个节点正常,就能达成共识);
- 若有 5 个管理节点:最多允许 2 个节点故障(5/2 + 1 = 3,3 个节点正常即可达成共识);
- 若用偶数个(如 2 个):当 1 个节点故障时,剩下 1 个节点无法满足"超过半数"(2 的半数是 1,1 不超过半数),集群会失去共识能力,无法处理新的管理操作(如部署服务、修改配置等)。
因此,奇数个管理节点能最大化集群的容错能力:既保证在部分节点故障时仍能正常达成共识,又避免因节点过多导致通信效率下降(节点越多,达成共识的成本越高)。
实际场景中,小型集群常用 3 个管理节点(容错 1 个),中大型集群用 5 个(容错 2 个),极少用超过 5 个的情况(除非对高可用有极致要求)。
2. 服务(Service)
- 定义期望状态(如副本数、镜像、端口映射等)。
- Swarm 会确保服务始终处于该状态(如某个容器挂了,会自动重启或迁移到其他节点)。
在 Docker Swarm 中,"服务(Service)"是集群管理的核心概念,简单说就是对"容器集群"的抽象定义------它规定了"要运行什么容器、运行多少个副本、如何网络通信、如何持久化数据"等规则,Swarm 会根据这些规则自动维护容器的运行状态。
具体来说,服务有这几个关键特点:
-
声明式定义:你只需要告诉 Swarm"我要一个 Nginx 服务,3 个副本,映射 80 端口",不需要手动在每个节点启动容器,Swarm 会自动调度并维持这个状态(比如某个副本挂了,会自动在其他节点重建)。
-
副本与调度:服务的"副本数"(replicas)决定了要运行多少个相同的容器实例,Swarm 会根据节点资源(CPU、内存)和健康状态,把这些副本分散到集群的节点上(默认包括管理节点,除非限制)。
-
统一访问入口:服务可以关联 Swarm 的 overlay 网络,集群内部通过服务名就能访问(类似 DNS 解析),外部可以通过"路由网格(Routing Mesh)"访问------即使容器副本分布在不同节点,访问任意节点的映射端口,都会自动转发到对应的容器。
-
动态更新:服务创建后,可以随时调整配置(比如增减副本数、更新镜像版本、修改环境变量),Swarm 会平滑地滚动更新,不中断服务(比如先停一个旧副本,启动一个新副本,逐个替换)。
举个例子:创建一个 nginx-service 服务,设置 3 个副本,Swarm 会自动在集群中启动 3 个 Nginx 容器,如果你手动删掉其中一个,Swarm 会检测到"实际副本数小于期望数",自动在其他节点补一个新的,始终保证 3 个副本运行。
简单说,"服务"就是 Swarm 中"容器集群的管理单位",通过它可以实现容器的自动化部署、扩缩容、高可用和统一管理,这也是 Swarm 作为容器编排工具的核心价值。
3. 任务(Task)
- 每个服务实例(容器)称为一个任务。
- 任务由 Manager 分配给 Worker 执行。
4. 网络(Overlay Network)
- Swarm 使用 overlay 网络实现跨主机容器通信。
- 默认提供 ingress 网络用于外部访问服务(基于 VIP + IPVS 或 iptables 的负载均衡)。
后面会详细介绍
5. Stack(堆栈)
- 使用 Docker Compose 文件(v3+)定义多服务应用。
- 通过
docker stack deploy一键部署整个应用栈。
在 Docker Swarm 中,"Stack(堆栈)"是多个关联服务的集合,用于将一组相互配合的服务(比如前端、后端、数据库等)作为一个整体进行管理。它相当于一个"服务组合",通过统一的配置文件定义和部署,简化多服务应用的生命周期管理。
举个例子:一个 Web 应用通常需要 Nginx(前端)、Node.js(后端)、MySQL(数据库)三个服务,这三个服务相互依赖(前端调用后端,后端连接数据库)。如果单独创建每个服务,需要分别执行命令或配置,还得手动处理它们的网络、依赖关系;而用 Stack 管理,只需在一个 docker-compose.yml 配置文件中定义这三个服务的关系(如网络连接、环境变量传递、启动顺序等),然后通过一条命令部署整个 Stack,Swarm 会自动创建所有服务并保证它们协同工作。
Stack 的核心特点:
-
统一配置与部署:用一个 YAML 配置文件(通常是 docker-compose.yml )定义所有服务的参数(镜像、端口、网络、数据卷等),执行 docker stack deploy -c 配置文件 堆栈名 即可一键部署所有服务。
-
服务间关联:通过自定义 overlay 网络让 Stack 内的服务相互通信(服务名可直接作为域名解析),无需手动配置网络连接。
-
整体生命周期管理:可以通过 docker stack ls 查看所有堆栈, docker stack ps 堆栈名 查看堆栈内所有服务的运行状态, docker stack rm 堆栈名 一键删除整个堆栈的所有服务,操作更高效。
简单说,Stack 是 Swarm 中"多服务应用的管理单位",适合部署包含多个组件的完整应用(如微服务架构),让复杂应用的部署和管理变得简单统一。
二、Swarm 集群搭建步骤(简要)
-
初始化 Manager 节点:
bashdocker swarm init --advertise-addr <MANAGER_IP> -
获取 Worker 加入命令:
bashdocker swarm join-token worker -
在 Worker 节点执行加入命令:
bashdocker swarm join --token <TOKEN> <MANAGER_IP>:2377 -
验证集群状态:
bashdocker node ls
三、实际项目中的典型使用场景
场景 1:微服务部署
-
将前端、后端、数据库等拆分为多个服务。
-
使用
docker service create或docker stack deploy部署。 -
示例
docker-compose.yml(v3):yamlversion: '3.8' services: web: image: nginx:alpine ports: - "80:80" deploy: replicas: 3 restart_policy: condition: on-failure api: image: my-api:latest deploy: replicas: 2 networks: default: driver: overlay部署命令:
bashdocker stack deploy -c docker-compose.yml myapp
场景 2:滚动更新与回滚
-
更新服务镜像:
bashdocker service update --image my-api:v2 myapp_api -
查看更新状态:
bashdocker service ps myapp_api -
回滚到上一版本:
bashdocker service rollback myapp_api
场景 3:配置管理(Config)与密钥管理(Secret)
-
存储敏感信息(如数据库密码):
bashecho "mydbpass" | docker secret create db_password - -
在服务中使用:
yamlservices: app: image: my-app secrets: - db_password secrets: db_password: external: true
场景 4:高可用与自动恢复
- Manager 节点故障时,其他 Manager 自动接管。
- 容器崩溃或节点宕机,Swarm 会自动在健康节点重建任务。
四、Swarm 与其他编排工具对比
| 特性 | Docker Swarm | Kubernetes (K8s) |
|---|---|---|
| 学习曲线 | 简单,命令直观 | 较陡峭,概念多 |
| 集成度 | 原生集成 Docker | 需独立安装,依赖 CRI 等 |
| 网络模型 | Overlay(内置) | CNI 插件(如 Calico、Flannel) |
| 适用规模 | 中小型项目 | 大型、复杂生产环境 |
| 社区与生态 | 较小 | 极大,CNCF 主导 |
对于中小型团队或快速原型开发,Swarm 仍是轻量高效的选择。
五、最佳实践建议
- Manager 节点数量:3 或 5 个(避免脑裂)。
- 使用 Stack 而非单个 Service:便于整体管理。
- 限制资源使用 :在
deploy.resources中设置 limits/requests。 - 日志与监控:结合 ELK 或 Prometheus + cAdvisor。
- 安全加固:启用 TLS、限制 API 访问、使用 Secret 管理敏感数据。
六、常见命令速查
bash
# 查看节点
docker node ls
# 创建服务
docker service create --name web --publish 80:80 --replicas 3 nginx
# 查看服务
docker service ls
docker service ps <service_name>
# 扩容/缩容
docker service scale web=5
# 删除服务
docker service rm web
# 部署 Stack
docker stack deploy -c compose.yml myapp
# 查看 Stack
docker stack ls
docker stack services myapp
总结
Docker Swarm 是一个轻量级、易用的容器编排方案,适合对 Kubernetes 复杂性望而却步的团队。虽然在大型云原生场景中逐渐被 K8s 取代,但在内部系统、CI/CD 测试环境、边缘计算等场景中仍有广泛应用价值。掌握 Swarm 有助于理解容器编排的基本原理,也为学习更复杂的平台打下基础。
Overlay 网络 和 Ingress 网络
Docker Swarm 的网络模型是其核心能力之一,尤其 Overlay 网络 和 Ingress 网络 对实现跨主机通信与外部访问至关重要。
一、Overlay 网络:跨主机容器通信的基石
1. 什么是 Overlay 网络?
- Overlay 网络是一种虚拟网络,构建在物理(Underlay)网络之上。
- 它允许不同 Docker 主机(节点)上的容器像在同一个局域网中一样通信,即使它们实际分布在不同的物理机器上。
- 在 Swarm 模式下,Overlay 网络由 Docker 自动创建和管理,底层使用 VXLAN(Virtual Extensible LAN) 封装技术。
2. 工作原理
-
当你在 Swarm 中创建一个 Overlay 网络时:
bashdocker network create --driver overlay mynet -
Docker 会在所有参与该网络的节点上自动配置 VXLAN 隧道。
-
容器分配的 IP 地址来自同一个子网(如
10.0.1.0/24),但实际运行在不同主机上。 -
容器间通信时,源主机将原始数据包封装在 UDP 报文中(目标端口通常为 4789),通过物理网络发送到目标主机,目标主机解封装后交给目标容器。
✅ 关键点:Overlay 网络对应用透明,容器无需知道对方在哪个物理主机上。
3. 特性
- 加密支持 (可选):
--opt encrypted启用 IPsec 加密。 - 服务发现 :Swarm 内置 DNS,容器可通过服务名解析 IP(如
ping web)。 - 多主机隔离:不同 Overlay 网络之间默认隔离,保障安全。
4. 示例
yaml
# docker-compose.yml
version: '3.8'
services:
app:
image: myapp
networks:
- mynet
db:
image: postgres
networks:
- mynet
networks:
mynet:
driver: overlay
attachable: true # 允许独立容器加入
部署后,app 和 db 即使运行在不同节点,也能通过 db:5432 直接通信。
二、Ingress 网络:外部访问 Swarm 服务的统一入口
1. 什么是 Ingress 网络?
- Ingress 是 Swarm 默认创建的一个特殊 Overlay 网络 ,名为
ingress。 - 它专用于处理发布到集群外部的服务流量 (即
--publish或ports配置的端口)。 - 所有通过
published port暴露的服务(如80:80)都会接入此网络。
2. 核心机制:Routing Mesh(路由网格)
Swarm 的 Ingress 网络实现了 Routing Mesh 功能,具有以下特点:
| 特性 | 说明 |
|---|---|
| 任意节点可接收请求 | 无论服务实际运行在哪台 Worker 节点,你都可以向任意 Manager 或 Worker 节点的 published 端口发起请求。 |
| 自动负载均衡 | 请求会被透明地转发到后端真实运行该服务任务的容器。 |
| 高可用 | 即使某个节点宕机,其他节点仍可接收并转发流量。 |
3. 负载均衡实现方式
Swarm 使用两种机制实现 Ingress 负载均衡(取决于内核版本和配置):
(1)VIP(Virtual IP) + IPVS(推荐)
- 每个服务在 Ingress 网络中分配一个 虚拟 IP(VIP)。
- 所有节点上的内核 IPVS 模块维护一个连接调度表,将请求分发到后端任务。
- 优点:性能高、支持多种调度算法(轮询、最少连接等)。
- 要求:Linux 内核 ≥ 4.0(大多数现代发行版满足)。
(2)VIP + iptables(兼容模式)
- 若 IPVS 不可用,Swarm 回退到 iptables DNAT 规则。
- 性能略低,但兼容性更好。
📌 你可以通过
docker service inspect <service>查看服务的 VIP:
json"Endpoint": { "Spec": { "Mode": "vip" }, "VirtualIPs": [{ "NetworkID": "...", "Addr": "10.255.0.5/16" }] }
4. 数据流示例
假设你部署了一个 Web 服务:
bash
docker service create --name web --publish 8080:80 --replicas 3 nginx
- 服务在 3 个节点上运行(比如 node2、node3、node4)。
- 你在 node1(未运行任何 web 容器)上访问
http://node1:8080。 - 流程如下:
- 请求到达 node1 的 8080 端口;
- Docker 的 Ingress 网络捕获该请求;
- 通过 Routing Mesh,请求被负载均衡到 node2/node3/node4 上的真实容器;
- 响应原路返回给客户端。
✅ 用户无需知道服务实际在哪台机器上运行!
三、Overlay vs Ingress:对比总结
| 特性 | 自定义 Overlay 网络 | Ingress 网络 |
|---|---|---|
| 用途 | 服务间内部通信 | 外部访问服务 |
| 是否默认存在 | 否(需手动创建) | 是(Swarm 初始化时自动创建) |
| 能否自定义 | 可以(命名、加密等) | 不建议修改(系统保留) |
| 负载均衡 | 无(仅连通性) | 有(Routing Mesh + VIP) |
| 端口发布 | 不支持 --publish |
必须通过它发布端口 |
四、常见问题解答
Q1:为什么不能直接用 host 网络发布服务?
- Host 网络绕过 Docker 网络栈,无法使用 Routing Mesh,失去"任意节点访问"和负载均衡能力。
- 且端口冲突风险高,不推荐在 Swarm 中使用。
Q2:Ingress 网络能加密吗?
- 默认不加密。若需安全传输,建议:
- 在应用层使用 HTTPS;
- 或通过 TLS 终止代理(如 Traefik、Nginx)前置。
Q3:如何排查 Overlay 网络问题?
- 检查节点间 UDP 4789 端口是否开放(VXLAN 通信);
- 使用
docker network inspect mynet查看连接容器; - 在容器内
ping或curl测试连通性。
总结
- Overlay 网络 = 容器跨主机通信的"高速公路";
- Ingress 网络 = 外部流量进入 Swarm 的"统一入口 + 智能分发器";
- 二者结合,使 Swarm 具备了服务发现、负载均衡、高可用、透明通信等云原生核心能力。
理解这两者,是掌握 Docker Swarm 网络架构的关键一步。