Swarm 集群
Swarm 是 Docker 自带的容器集群管理工具,是生产环境中要用到的。1,真实场景中不可能只有一台服务器运行,这种情况一旦服务器挂了,那所有的容器都停止了,所以是会有备用的服务器的。2,还有流量负载的问题,大流量数据,如果只有一个容器的话可以处理不过来。所以需要很多个容器,此时就需要 Swarm 来管理
Swarm 本质上是在 Docker 之上增加了一层"集群管理能力",但是它不仅仅是多了一层管理,还增加了:节点管理、服务调度、网络通信、副本管理、故障恢复等能力。
节点 Node
Swarm 里有一个叫节点的概念,一个在运行 Docker Engine,并加入 Swarm 集群的机器,就是一个 Node(节点)。
本地也可以是节点
其中节点又分为 manager 和 worker,manager 负责管理的节点,而 worker 是工作节点
Manager负责:
-
保存整个集群状态
-
创建和删除 Service
-
调度任务(Task)
-
管理网络
-
管理节点
Worker 负责:
-
执行 Manager 分配的任务
-
运行容器
service 服务
还有一个新概念,service(服务),Swarm 集群中不再直接管理容器,而是去管理 service。
对比容器
两者的区别:
| Container | Service | |
|---|---|---|
| 是什么 | 运行实例 | 服务定义 |
| 谁管理 | Docker | Swarm |
| 数量 | 一个具体容器 | 可以包含多个容器 |
| 是否自动恢复 | 普通 Docker 不一定 | 自动维护 |
| 是否跨节点 | 单节点 | 可以跨节点 |
Service 可以理解为"容器的期望状态"。
例如:
你告诉 Swarm:
Plain
docker service create \
--name backend \
--replicas 3 \
backend:v1
意思:
我要:
Plain
一个叫 backend 的服务
里面运行3个副本
Swarm 记录:
Plain
Service:
backend
期望:
3个容器
然后自动创建三个容器,不需要你手动指定:
Plain
backend.1
backend.2
backend.3
这些才是真正的容器。
并且因为 --replicas 3,期望是三个,所以如果其中有容器挂掉了,它会自动重启,保持三个容器。
Overlay 网络
普通 Docker 的默认网络只在一台机器内部有效;Swarm 的 Overlay 网络会把多台服务器上的容器"逻辑上放进同一个虚拟网络"。
但并不是随便创建一个网络、让服务器加入就行。前提是:
-
多台服务器先加入同一个 Swarm 集群。
-
这些服务器在真实网络上彼此可达。
-
创建的是 Swarm 的
overlay网络。 -
服务加入这个 Overlay 网络。
普通 Docker 为什么不能直接跨服务器
普通 Compose 默认创建的是 bridge 网络,例如:
Plain
docker-learning_default
它只存在于当前这台机器。
假设有两台服务器:
Plain
服务器 A
├── nginx 容器
└── bridge 网络 A
服务器 B
├── backend 容器
└── bridge 网络 B
即使两个网络名字一样:
Plain
my-network
它们也不是同一个网络,而是两台机器上各自独立的网络。
因此,服务器 A 的 Nginx 通常不能直接通过:
Plain
backend:8000
找到服务器 B 的后端容器。
但是原来的服务器之间不是不能通信,而是需要你自己管理:
-
服务器 IP
-
暴露端口
-
防火墙
-
服务地址变化
-
负载均衡
-
故障切换
Swarm 是把这些事情统一管理了。
Overlay 网络是什么
Overlay 网络可以理解为:
建立在真实服务器网络之上的一层虚拟容器网络。
例如有三台服务器:
Plain
服务器 A:10.0.0.1
服务器 B:10.0.0.2
服务器 C:10.0.0.3
真实网络保证三台服务器能通信。
Swarm 再在上面创建 Overlay 网络:
Plain
overlay 网络:my-network
服务器 A 服务器 B 服务器 C
nginx backend1 backend2
└────────────────┴────────────────┘
这些容器虽然运行在不同服务器上,但逻辑上像在同一个 Docker 网络中。
于是 Nginx 可以访问:
Plain
backend:8000
加入 Overlay 网络的步骤
服务器直接加入 overlay 网络,而是服务器先加入 Swarm,服务或容器再加入 overlay 网络。
第一步:建立 Swarm
Manager:
Plain
docker swarm init
其他服务器执行 Manager 给出的:
Plain
docker swarm join --token ... 管理节点IP:2377
此时,多台服务器组成一个 Swarm。
第二步:创建 overlay 网络
在 Manager 上:
Plain
docker network create \
--driver overlay \
app-network
这里:
Plain
--driver overlay
表示这是一个跨节点网络,不是普通的单机 bridge 网络。
第三步:让服务加入网络
例如:
Plain
docker service create \
--name backend \
--network app-network \
my-backend:v1
再创建 Nginx:
Plain
docker service create \
--name nginx \
--network app-network \
--publish 80:80 \
nginx:alpine
此时两个服务即使被调度到不同服务器,也能通过服务名通信:
Plain
nginx → backend:8000
Stack
管理对象从容器变成了服务,相应的,Swarm 管理指令的方式就从 Compose 变成了 Stack
对比 Compose
不同:
| Docker Compose | Docker Stack | |
|---|---|---|
| 环境 | 单机 | Swarm 集群 |
| 管理对象 | Container | Service |
| 命令 | docker compose up | docker stack deploy |
| 是否支持多节点 | ❌ | ✅ |
| 副本扩展 | 有限 | 原生支持 |
| 自动恢复 | 弱 | 强 |
| 相同: |
两者都是读取 compose.yml 文件,里面的主要内容是一致的,比如前端、后端等,但是某些字段会变,比如网络换成 Swarm 的网络 overlay,还有会多 replicas 字段,用于设定期望值副本个数。
Swarm 高频命令总结
集群管理
初始化
Plain
docker swarm init
加入集群
Plain
docker swarm join
查看节点
Plain
docker node ls
查看集群信息
Plain
docker info
Service 管理
创建:
Plain
docker service create
查看:
Plain
docker service ls
查看详情:
Plain
docker service inspect service_name
查看运行任务:
Plain
docker service ps service_name
日志:
Plain
docker service logs service_name
删除(有 YAML 文件可以重启):
Plain
docker service rm service_name
扩容:
Plain
docker service scale backend=5
更新:
Plain
docker service update
回滚:
Plain
docker service rollback
Stack 管理
部署:
Plain
docker stack deploy \
-c docker-compose.yml \
app
查看:
Plain
docker stack ls
查看服务:
Plain
docker stack services app
查看任务:
Plain
docker stack ps app
删除:
Plain
docker stack rm app
网络管理
查看:
Plain
docker network ls
创建:
Plain
docker network create \
--driver overlay \
network-name