Docker Swarm 之 栈(Stack)

摘要

Stack简介

  • 前面我们在Swarm中创建服务都是通过Service,每次创建一个,有没有类似docker compose的方式来创建多个服务呢?Docker Swarm为我们提供了Stack

  • 在 Docker Swarm 中,Stack(栈) 是用来定义和部署一组相关服务的集合。你可以把它看成是一个应用的整体,由多个服务(service)、网络(network)、卷(volume)等组成。

Stack 通常用 Docker Compose 文件(YAML 格式) 描述

  • Stack 完全兼容 Docker Compose 文件,并可以在 compose 文件中声明副本集等与Service相关的配置项。

  • 我用表格总结一下二者的差异,重点放在「Stack 支持的配置」上:

配置项 Docker Compose (本地) Docker Stack (Swarm 集群) 说明
name Stack 不支持 name 属性
build Stack 不支持 build 属性,只能使用image
deploy ❌(部分支持,通常被忽略) ✅(核心支持) Stack 支持用 deploy 定义副本数、资源限制、更新策略等
deploy.replicas 定义服务副本数
deploy.resources 定义 CPU、内存限制
deploy.placement 定义服务调度策略(在哪些节点上运行)
deploy.update_config 定义滚动更新的参数
deploy.restart_policy 定义重启策略
deploy.mode replicatedglobal
depends_on 🚫(被忽略) Stack 不支持容器启动顺序控制
build 🚫(被忽略) Stack 不支持直接构建镜像,只能用已存在的镜像
network.external 都支持外部网络
volumes.external 都支持外部卷
configs 🚫 Stack 支持 Config 对象,适合配置文件管理
secrets 🚫 Stack 支持 Secrets,用于安全存储敏感信息

Portainer 社区版 (CE)可让您在 Docker、Docker Swarm、Kubernetes 和 Azure ACI 中轻松构建和管理容器。

1
curl -L https://downloads.portainer.io/ce-lts/portainer-agent-stack.yml -o portainer-agent-stack.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
version: "3.2" #  docker-compose版本,新版的docker已经不需要配置版本号了
services:
agent: # agent服务
image: portainer/agent:lts # 镜像,不能使用 Dockerfile
volumes: # 挂载卷
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
networks: # 挂载网络,必须是 overlay
- agent_network
deploy: # 部署策略,service 特有属性
mode: global # 全局模式
placement: # 部署条件
constraints: [node.platform.os == linux] # 运行在linux节点

portainer: # portainer服务
image: portainer/portainer-ce:lts # 镜像
command: -H tcp://tasks.agent:9001 --tlsskipverify # 启动参数
ports: # 端口映射
- "9443:9443" # 浏览器访问 https://localhost:9443
- "9000:9000"
- "8000:8000"
volumes: # 挂载卷
- portainer_data:/data
networks: # 挂载网络,与agent服务网络一致
- agent_network
deploy: # 部署配置
mode: replicated # 副本模式
replicas: 1 # 副本数量
placement: # 部署条件
constraints: [node.role == manager] # 节点角色为manager

networks: # 网络声明
agent_network: # 网络名称
driver: overlay # 网络驱动
attachable: true # 允许容器加入

volumes: # 挂载卷声明
portainer_data: # 挂载卷名称

Stack 命令

子命令 中文说明 示例命令
config 输出最终的配置文件(经过合并与变量替换后) docker stack config -c docker-compose.yml
deploy 部署新 stack 或更新已有 stack docker stack deploy -c docker-compose.yml mystack
ls 列出所有已部署的 stack docker stack ls
ps 查看 stack 中的所有任务(即各个容器实例) docker stack ps mystack
rm 删除一个或多个 stack docker stack rm mystack
services 列出某个 stack 中的所有服务 docker stack services mystack

docker stack config: 输出最终的配置文件

1
2
# 此命令也可以用来验证compose文件格式是否正确,只保证格式正确,不保证逻辑正确
docker stack config -c portainer-agent-stack.yml

docker stack deploy: 部署 stack

  • docker stack deploy == docker stack up

1
2
3
4
5
docker stack deploy -c portainer-agent-stack.yml portainer
## 输出
Creating network portainer_agent_network
Creating service portainer_agent
Creating service portainer_portainer

docker stack ls: 列出所有 stack

  • docker stack ls == docker stack list

1
2
3
4
docker stack ls
## 输出,stack名称为portainer,其内部有两个服务,agent和portainer
NAME SERVICES
portainer 2

docker stack services: 查看服务

1
2
3
4
5
6
7
8
9
10
11
12
docker stack services portainer
## 输出
ID NAME MODE REPLICAS IMAGE PORTS
h5foyujr6jq9 portainer_agent global 5/5 portainer/agent:lts
zcek2jtloe09 portainer_portainer replicated 1/1 portainer/portainer-ce:lts *:8000->8000/tcp, *:9000->9000/tcp, *:9443->9443/tcp

## 等效
docker service ls
## 输出
ID NAME MODE REPLICAS IMAGE PORTS
h5foyujr6jq9 portainer_agent global 5/5 portainer/agent:lts
zcek2jtloe09 portainer_portainer replicated 1/1 portainer/portainer-ce:lts *:8000->8000/tcp, *:9000->9000/tcp, *:9443->9443/tcp

docker stack ps: 列出 stack 下的所有服务实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
docker stack ps portainer
## 输出
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wshk9s6gyxh1 portainer_agent.hvzkh3ip5ef8gx973z1ywahbu portainer/agent:lts worker2 Running Running 30 seconds ago
n3jjzmr2fcv9 portainer_agent.kp2zerd28xgz5mmglnje0jp22 portainer/agent:lts manager1 Running Running 59 seconds ago
24yy1ew3tiya portainer_agent.oymi74epagdqeprah7s81tsa2 portainer/agent:lts manager2 Running Running 3 minutes ago
kpo4hhdvwcwd portainer_agent.r7388xl84nczjtnf53pwh7hla portainer/agent:lts manager3 Running Running 35 seconds ago
t8xjbotfuas0 portainer_agent.xkww4853bbdgv7bv8771xibob portainer/agent:lts worker1 Running Running 48 seconds ago
qox3kqypon69 portainer_portainer.1 portainer/portainer-ce:lts manager2 Running Running 2 minutes ago

## 等效
docker service ps portainer_agent portainer_portainer
## 输出
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wshk9s6gyxh1 portainer_agent.hvzkh3ip5ef8gx973z1ywahbu portainer/agent:lts worker2 Running Running 7 minutes ago
n3jjzmr2fcv9 portainer_agent.kp2zerd28xgz5mmglnje0jp22 portainer/agent:lts manager1 Running Running 8 minutes ago
24yy1ew3tiya portainer_agent.oymi74epagdqeprah7s81tsa2 portainer/agent:lts manager2 Running Running 10 minutes ago
kpo4hhdvwcwd portainer_agent.r7388xl84nczjtnf53pwh7hla portainer/agent:lts manager3 Running Running 7 minutes ago
t8xjbotfuas0 portainer_agent.xkww4853bbdgv7bv8771xibob portainer/agent:lts worker1 Running Running 7 minutes ago
qox3kqypon69 portainer_portainer.1 portainer/portainer-ce:lts manager2 Running Running 10 minutes ago

docker stack rm: 停止并删除 stack

  • docker stack rm == docker stack remove == docker stack down

1
docker stack rm portainer