Appearance
Docker Swarm
Docker Swarm 是 Docker 内置的容器集群管理工具,将多台 Docker 主机组成一个集群,提供服务高可用和水平扩展能力。
Swarm 核心概念
| 概念 | 说明 |
|---|---|
| Swarm | 集群本身,由多个 Docker 节点组成 |
| Node(节点) | 集群中的 Docker 主机 |
| Manager(管理节点) | 负责集群管理和任务调度,奇数个保证高可用 |
| Worker(工作节点) | 运行任务容器 |
| Service(服务) | 定义要运行的任务(镜像、副本数、网络等) |
| Task(任务) | 服务中的单个容器实例 |
| Stack(栈) | 多服务应用的部署单元(使用 Compose 文件) |
┌─────────────────────────────────────────────┐
│ Swarm 集群 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Manager1 │ │ Manager2 │ │ Manager3 │ │
│ │(Leader) │ │(Follower)│ │(Follower)│ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Worker1 │ │ Worker2 │ │ Worker3 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────┘初始化集群
初始化第一个 Manager 节点
bash
# 在 Manager 节点上执行(指定 Manager 的 IP)
docker swarm init --advertise-addr 192.168.1.100
# 输出:
# Swarm initialized: current node (xxx) is now a manager.
# To add a worker to this swarm, run the following command:
# docker swarm join --token SWMTKN-1-xxxx 192.168.1.100:2377
# To add a manager to this swarm, run:
# docker swarm join-token manager添加 Worker 节点
在 Worker 节点上执行初始化时给出的命令:
bash
docker swarm join \
--token SWMTKN-1-xxxx \
192.168.1.100:2377添加 Manager 节点(高可用)
bash
# 在现有 Manager 上获取 Manager 加入 token
docker swarm join-token manager
# 在新 Manager 节点上执行
docker swarm join \
--token SWMTKN-1-manager-xxxx \
192.168.1.100:2377查看集群状态
bash
# 查看所有节点
docker node ls
# 输出示例
# ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
# abc123 * manager1 Ready Active Leader
# def456 manager2 Ready Active Reachable
# ghi789 worker1 Ready Active服务管理
创建服务
bash
# 创建基本服务
docker service create \
--name web \
--replicas 3 \
--publish published=80,target=80 \
nginx:alpine
# 创建时挂载数据卷
docker service create \
--name db \
--mount type=volume,source=db-data,target=/var/lib/postgresql/data \
--env POSTGRES_PASSWORD=secret \
postgres:16-alpine
# 限制资源
docker service create \
--name api \
--replicas 2 \
--limit-memory 512m \
--limit-cpu 0.5 \
--reserve-memory 256m \
myapi:latest
# 配置重启策略
docker service create \
--name worker \
--restart-condition on-failure \
--restart-max-attempts 3 \
myworker:latest查看服务
bash
# 列出所有服务
docker service ls
# 查看服务详情
docker service inspect web
# 查看服务的所有任务(副本)
docker service ps web
# 查看服务日志
docker service logs -f web更新服务
bash
# 更新镜像(滚动更新)
docker service update --image nginx:1.25 web
# 修改副本数(扩缩容)
docker service scale web=5
docker service update --replicas 5 web
# 更新环境变量
docker service update \
--env-add NEW_VAR=value \
--env-rm OLD_VAR \
api
# 更新资源限制
docker service update \
--limit-memory 1g \
api
# 回滚到上一版本
docker service rollback web删除服务
bash
docker service rm webStack 部署
Stack 使用 Compose 文件部署多服务应用,是生产环境推荐方式:
docker-stack.yml:
yaml
services:
web:
image: nginx:alpine
ports:
- "80:80"
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
resources:
limits:
memory: 128M
networks:
- frontend
api:
image: myapi:latest
deploy:
replicas: 2
resources:
limits:
memory: 512M
environment:
DB_HOST: db
networks:
- frontend
- backend
db:
image: postgres:16-alpine
deploy:
replicas: 1
placement:
constraints:
- node.role == manager # 只在 Manager 节点运行
volumes:
- db-data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: secret
networks:
- backend
volumes:
db-data:
networks:
frontend:
driver: overlay
backend:
driver: overlaybash
# 部署 Stack
docker stack deploy -c docker-stack.yml myapp
# 查看 Stack 状态
docker stack ls
docker stack services myapp
docker stack ps myapp
# 更新 Stack(重新部署)
docker stack deploy -c docker-stack.yml myapp
# 删除 Stack
docker stack rm myapp节点管理
bash
# 查看节点详情
docker node inspect worker1
# 修改节点可用性
docker node update --availability drain worker1 # 排空节点(不接受新任务)
docker node update --availability active worker1 # 恢复
# 添加节点标签
docker node update --label-add zone=us-east worker1
# 提升 Worker 为 Manager
docker node promote worker1
# 降级 Manager 为 Worker
docker node demote manager2
# 删除节点(需先 drain)
docker node rm worker1
# 在节点上自行离开集群
docker swarm leave # Worker 节点离开
docker swarm leave --force # Manager 节点离开服务放置约束
yaml
deploy:
placement:
constraints:
- node.role == manager # 只在 Manager 上运行
- node.role == worker # 只在 Worker 上运行
- node.hostname == server1 # 只在特定主机
- node.labels.zone == us-east # 按自定义标签
preferences:
- spread: node.labels.zone # 均匀分布在各 zoneSwarm 网络
Swarm 使用 overlay 网络实现跨主机容器通信:
bash
# 创建 overlay 网络(Swarm 模式下)
docker network create \
--driver overlay \
--attachable \ # 允许独立容器连接
my-overlay-net
# 独立容器也可以连接
docker run -d \
--network my-overlay-net \
--name test \
alpine sleep 3600Secrets 管理
Swarm 提供安全的密钥管理,密钥加密存储,只分发给需要的服务:
bash
# 创建 secret
echo "my-secret-password" | docker secret create db_password -
docker secret create ssl_cert ./ssl/cert.pem
# 列出 secrets
docker secret ls
# 在服务中使用 secret
docker service create \
--name db \
--secret db_password \
-e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_password \
mysql:8.0
# 删除 secret
docker secret rm db_password在 Compose 文件中使用:
yaml
services:
db:
image: mysql:8.0
secrets:
- db_password
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
external: true # 使用已存在的 secret
# 或者
file: ./secrets/db_password.txt # 从文件创建总结
Docker Swarm 提供了简单易用的集群管理能力:
- 初始化:
docker swarm init一条命令建立集群 - 高可用:多 Manager 节点,奇数个(3 或 5)
- 服务管理:
docker service命令管理服务 - 滚动更新:不停机更新,失败自动回滚
- Stack 部署:使用 Compose 文件声明式部署
下一节介绍 Swarm 集群的高级管理。