Docker Stack

大规模场景下的多服务部署和管理是一件很难的事情。Docker Stack 为解决该问题而生,Docker Stack 通过提供期望状态、滚动升级、简单易用、扩缩容、健康检查等特性简化了应用的管理,这些功能都封装在一个完美的声明式模型当中。

Stack 能够在单个声明文件中定义复杂的多服务应用。Stack 还提供了简单的方式来部署应用并管理其完整的生命周期:初始化部署 -> 健康检查 -> 扩容 -> 更新 -> 回滚,以及其他功能!

在 Compose 文件中定义应用,然后通过 docker stack deploy 命令完成部署和管理。

Compose 文件中包含了构成应用所需的完整服务栈。此外还包括了卷、网络、安全以及应用所需的其他基础架构。然后基于该文件使用 docker stack deploy 命令来部署应用。

Stack 是基于 Docker Swarm 之上来完成应用的部署。安全等高级特性,其实都是来自 Swarm。

Docker 适用于开发和测试。Docker Stack 则适用于大规模场景和生产环境。

如果了解 Docker Compose,就会发现 Docker Stack 非常简单。在许多方面,Stack 一直是期望的 Compose——完全集成到 Docker 中,并能够管理应用的整个生命周期。

从体系结构上来讲,Stack 位于 Docker 应用层级的最顶端。Stack 基于服务进行构建,而服务又基于容器,如下图所示。

在后续的讲解中会一直使用示例应用 AtSea Shop。该示例托管在 Github 的 dockersamples/atsea-sample-shop-app 库中,基于 Apache 2.0 许可证开源。

使用该应用是因为其复杂度适中,不会因为太复杂而难以完整解释。除此之外,该应用还是个多服务应用,并且利用了认证和安全相关的技术。应用架构如下图所示。

如上图所示,该应用由 5 个服务、3 个网络、4 个密钥以及 3 组端口映射构成。具体细节将会结合 Stack 文件进行分析。

提示:服务指的是 Docker 服务(由若干容器组成的集合,作为一个整体进行统一管理,并且在 Docker API 中存在对应的服务对象)。

复制 Github 仓库,以获取全部源代码文件。

$ git clone https://github.com/dockersamples/atsea-sample-shop-app.git Cloning

该应用的代码由若干目录和源码文件组成。重点关注的文件是 docker-stack.yml。该文件通常被称为 Stack 文件,在该文件中定义了应用及其依赖。

在该文件整体结构中,定义了 4 种顶级关键字。

    version:代表了Compose文件格式的版本号。为了应用于Stack,需要3.0或者更高的版本。
    services:中定义了组成当前应用的服务都有哪些。
    networks:列出了必需的网络。
    secrets:定义了应用用到的密钥。
如果展开顶级的关键字,可以看到类似上图中的结构。Stack 文件由 5 个服务构成,分别为“reverse_proxy”“database”“appserver”“visualizer”“payment_gateway”。Stack 文件中包含 3 个网络,分别为“front-tier”“back-tier”“payment”。

最后,Stack 文件中有 4 个密钥,分别为“postgres_password”“staging_token”“revprox_key”“revprox_cert”。这是在访问https://github.com/dockersamples/atsea-sample-shop-app.git里面的docker-stack.yml的内容。

Stack 文件定义了应用的很多依赖要素,理解这一点很重要。Stack 文件是应用的一个自描述文件,并且作为一个很好的工具弥合了开发和运维之间的隔阂。

Stack配置文件

Stack 文件就是 Docker Compose 文件。唯一的要求就是 version:一项需要是“3.0”或者更高的值。具体可以关注 Docker 文档中关于 Compose 文件的最新版本信息。

在 Docker 根据某个 Stack 文件部署应用的时候,首先会检查并创建 networks:关键字对应的网络。如果对应网络不存在,Docker 会进行创建。
网络

networks:
front-tier:
back-tier:
payment:
driver: overlay
driver_opts:
encrypted: 'yes'

该文件中定义了 3 个网络:front-tier、back-tier 以及 payment。默认情况下,这些网络都会采用 overlay 驱动,新建对应的覆盖类型的网络。但是 payment 网络比较特殊,需要数据层加密。

默认情况下,覆盖网络的所有控制层都是加密的。如果需要加密数据层,有两种选择。

    在 docker network create 命令中指定 -o encrypted 参数。
    在 Stack 文件中的 driver_opts 之下指定 encrypted:'yes'。
数据层加密会导致额外开销,而影响额外开销大小的因素有很多,比如流量的类型和流量的多少。但是,通常额外开销会在 10% 的范围之内。

正如前面提到的,全部的 3 个网络均会先于密钥和服务被创建。
密钥
密钥属于顶级对象,在当前 Stack 文件中定义了 4 个。

secrets:
postgres_password:
external: true
staging_token:
external: true
revprox_key:
external: true
revprox_cert:
external: true
注意,4 个密钥都被定义为 external。这意味着在 Stack 部署之前,这些密钥必须存在。

当然在应用部署时按需创建密钥也是可以的,只需要将 file: <filename> 替换为 external: true。但该方式生效的前提是,需要在主机文件系统的对应路径下有一个文本文件,其中包含密钥所需的值,并且是未加密的。这种方式存在明显的安全隐患。

服务
部署中的主要操作都在服务这个环节。

每个服务都是一个 JSON 集合(字典),其中包含了一系列关键字。我们会依次介绍每个关键字,并解释操作的具体内容。
1) reverse_proxy 服务
reverse_proxy 服务定义了镜像、端口、密钥以及网络。

reverse_proxy:
image: dockersamples/atseasampleshopapp_reverse_proxy
ports:
- "80:80"
- "443:443"
secrets:
- source: revprox_cert
target: revprox_cert
- source: revprox_key
target: revprox_key
networks:
- front-tier
image 关键字是服务对象中唯一的必填项。该关键字定义了将要用于构建服务副本的 Docker 镜像。

Docker 是可选项,除非指定其他值,否则镜像会从 Docker Hub 拉取。可以通过在镜像前添加对应第三方镜像仓库服务 API 的 DNS 名称的方式,来指定某个镜像从第三方服务拉取。例如 Google 的容器服务的 DNS 名称为 gcr.io。

Docker Stack 和 Docker Compose 的一个区别是,Stack 不支持构建。这意味着在部署 Stack 之前,所有镜像必须提前构建完成。

ports 关键字定义了两个映射。

    80:80 将 Swarm 节点的 80 端口映射到每个服务副本的 80 端口。
    443:443 将 Swarm 节点的 443 端口映射到每个服务副本的 443 端口。
默认情况下,所有端口映射都采用 Ingress 模式。这意味着 Swarm 集群中每个节点的对应端口都会映射并且是可访问的,即使是那些没有运行副本的节点。

另一种方式是 Host 模式,端口只映射到了运行副本的 Swarm 节点上。但是,Host 模式需要使用完整格式的配置。例如,在 Host 模式下将端口映射到 80 端口的语法如下所示。

ports:
- target: 80
published: 80
mode: host
推荐使用完整语法格式,这样可以提高易读性,并且更灵活(完整语法格式支持 Ingress 模式和 Host 模式)。但是,完整格式要求 Compose 文件格式的版本至少是 3.2。

secret 关键字中定义了两个密钥:revprox_cert 以及 revprox_key。这两个密钥必须在顶级关键字 secrets 下定义,并且必须在系统上已经存在。

密钥以普通文件的形式被挂载到服务副本当中。文件的名称就是 stack 文件中定义的 target 属性的值,其在 Linux 下的路径为 /run/secrets。Linux 将 /run/secrets 作为内存文件系统挂载。

本服务密钥中定义的内容会在每个服务副本中被挂载,具体路径为 /run/secrets/revprox_cert 和 /run/secrets/revprox_key。若将其中之一挂载为 /run/secrets/uber_secret,需要在 stack 文件中定义如下内容。

secrets:
- source: revprox_cert
target: uber_secret
networks 关键字确保服务所有副本都会连接到 front-tier 网络。网络相关定义必须位于顶级关键字 networks 之下,如果定义的网络不存在,Docker 会以 Overlay 网络方式新建一个网络。

 2) database 服务
数据库服务也在 Stack 文件中定义了,包括镜像、网络以及密钥。除上述内容之外,数据库服务还引入了环境变量和部署约束。

database:
image: dockersamples/atsea_db
environment:
POSTGRES_USER: gordonuser
POSTGRES_DB_PASSWORD_FILE: /run/secrets/postgres_password
POSTGRES_DB: atsea
networks:
- back-tier
secrets:
- postgres_password
deploy:
placement:
constraints:
- 'node.role == worker'
environment 关键字允许在服务副本中注入环境变量。在该服务中,使用了 3 个环境变量来定义数据库用户、数据库密码的位置(挂载到每个服务副本中的密钥)以及数据库服务的名称。

environment:
POSTGRES_USER: gordonuser
POSTGRES_DB_PASSWORD_FILE: /run/secrets/postgres_password
POSTGRES_DB: atsea
将三者作为密钥传递会更安全,因为这样可以避免将数据库名称和数据库用户以明文变量的方式记录在文件当中。

该服务还在 deploy 关键字下定义了部署约束。这样保证了当前服务只会运行在 Swarm 集群的 worker 节点之上。

deploy:
placement:
constraints:
- 'node.role == worker'
部署约束是一种拓扑感知定时任务,是一种很好的优化调度选择的方式。Swarm 目前允许通过如下几种方式进行调度。

    节点ID,如 node.id==o2p4kw2uuw2a。
    节点名称,如 node.hostname==wrk-12。
    节点角色,如 node.role!=manager。
    节点引擎标签,如 engine.labels.operatingsystem==ubuntu16.04。
    节点自定义标签,如 node.labels.zone==prod1。

    注意: == 和 != 操作符均支持。

3) appserver 服务
appserver 服务使用了一个镜像,连接到 3 个网络,并且挂载了一个密钥。此外 appserver 服务还在 deploy 关键字下引入了一些额外的特性。

appserver:
image: dockersamples/atsea_app
networks:
- front-tier
- back-tier
- payment
deploy:
replicas: 2
update_config:
parallelism: 2
failure_action: rollback
placement:
constraints:
- 'node.role == worker'
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
secrets:
- postgres_password
接下来进一步了解 deploy 关键字中新增的内容。

首先,services.appserver.deploy.replicas = 2 设置期望服务的副本数量为 2。缺省情况下,默认值为 1。如果服务正在运行,并且需要修改副本数,则需要显示声明该值。这意味着需要更新 stack 文件中的 services.appserver.deploy.replicas,设置一个新值,然后重新部署当前 stack。

services.appserver.deploy.update_config 定义了 Docker 在服务滚动升级的时候具体如何操作。对于当前服务,Docker 每次会更新两个副本(parallelism),并且在升级失败后自动回滚。

回滚会基于之前的服务定义启动新的副本。failure_action 的默认操作是 pause,会在服务升级失败后阻止其他副本的升级。failure_action 还支持 continue。

update_config:
parallelism: 2
failure_action: rollback
services.appserver.deploy.restart-policy 定义了 Swarm 针对容器异常退出的重启策略。当前服务的重启策略是,如果某个副本以非 0 返回值退出(condition: onfailure),会立即重启当前副本。重启最多重试 3 次,每次都会等待至多 120s 来检测是否启动成功。每次重启的间隔是 5s。

restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s

4) visualizer 服务
visualizer 服务中指定了镜像,定义了端口映射规则、更新配置以及部署约束。此外还挂载了一个指定卷,并且定义了容器的优雅停止方式。

visualizer:
image: dockersamples/visualizer:stable
ports:
- "8001:8080"
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
update_config:
failure_action: rollback
placement:
constraints:
- 'node.role == manager'
当 Docker 停止某个容器的时候,会给容器内部 PID 为 1 的进程发送 SIGTERM 信号。容器内 PID 为 1 的进程会有 10s 的优雅停止时间来执行一些清理操作。如果进程没有处理该信号,则 10s 后就会被 SIGKILL 信号强制结束。stop_grace_period 属性可以调整默认为 10s 的优雅停止时长。

volumes 关键字用于挂载提前创建的卷或者主机目录到某个服务副本当中。在本例中,会挂载 Docker 主机的 /var/run/docker.sock 目录到每个服务副本的 /var/run/docker.sock 路径。这意味着在服务副本中任何对 /var/run/docker.sock 的读写操作都会实际指向 Docker 主机的对应目录中。

/var/run/docker.sock 恰巧是 Docker 提供的 IPC 套接字,Docker daemon 通过该套接字对其他进程暴露其 API 终端。这意味着如果给某个容器访问该文件的权限,就是允许该容器接收全部的 API 终端,即等价于给予了容器查询和管理 Docker daemon 的能力。在大部分场景下这是决不允许的。但是,这是一个实验室环境中的示例应用。

该服务需要 Docker 套接字访问权限的原因是需要以图形化方式展示当前 Swarm 中服务。为了实现这个目标,当前服务需要能访问管理节点的 Docker daemon。为了确保能访问管理节点 Docker daemon,当前服务通过部署约束的方式,强制服务副本只能部署在管理节点之上,同时将 Docker 套接字绑定挂载到每个服务副本中。绑定挂载如下图所示。

5) payment_gateway 服务
payment_gateway 服务中指定了镜像,挂载了一个密钥,连接到网络,定义了部分部署策略,并且使用了两个部署约束。

payment_gateway:
image: dockersamples/atseasampleshopapp_payment_gateway
secrets:
- source: staging_token
target: payment_token
networks:
- payment
deploy:
update_config:
failure_action: rollback
placement:
constraints:
- 'node.role == worker'
- 'node.labels.pcidss == yes'
除了部署约束 node.label 之外,其余配置项在前面都已经出现过了。通过 docker node update 命令可以自定义节点标签,并添加到 Swarm 集群的指定节点。

因此,node.label 配置只适用于 Swarm 集群中指定的节点上(不能用于单独的容器或者不属于 Swarm 集群的容器之上)。

在本例中,payment_gateway 服务被要求只能运行在符合 PCI DSS(支付卡行业标准,译者注)标准的节点之上。为了使其生效,可以将某个自定义节点标签应用到 Swarm 集群中符合要求的节点之上。示例中在搭建应用部署实验环境的时候完成了该操作。

因为当前服务定义了两个部署约束,所以服务副本只会部署在两个约束条件均满足的节点之上,即具备 pcidss=yes 节点标签的 worker 节点。

关于 Stack 文件的分析到这里就结束了,目前对于应用需求应该有了较好的理解。前文中提到,Stack 文件是应用文档化的重要部分之一。已经了解该应用包含 5 个服务、3 个网络以及 4 个密钥。此外还知道了每个服务都会连接到哪个网络、有哪些端口需要发布、应用会使用到哪些镜像以及哪些服务需要在特定的节点上发布。

Swarm模式下Docker Stack部署应用

部署应用之前,有几个前置处理需要完成。

    Swarm 模式:应用将采用 Docker Stack 部署,而 Stack 依赖 Swarm 模式。
    标签:某个 Swarm worker 节点需要自定义标签。
    密钥:应用所需的密钥需要在部署前创建完成。
搭建应用实验环境
接下来会完成基于 Linux 的三节点 Swarm 集群搭建,同时能满足上面应用的全部前置依赖。完成之后,实验环境如下图所示。

接下来内容分为 3 个步骤。

    创建新的 Swarm。
    添加节点标签。
    创建密钥。
首先创建新的三节点 Swarm 集群。

 1) 初始化 Swarm
在任意 Swarm 管理节点的机器上,运行下面的命令。

$ docker swarm init

 2) 添加工作节点
复制前面输出中出现的 docker swarm join 命令。将复制内容粘贴到工作节点上并运行。

//Worker 1 (wrk-1)
wrk-1$ docker swarm join --token SWMTKN-1-2hl6...-...3lqg 172.31.40.192:2377
This node joined a swarm as a worker.

//Worker 2 (wrk-2)
wrk-2$ docker swarm join --token SWMTKN-1-2hl6...-...3lqg 172.31.40.192:2377
This node joined a swarm as a worker.

 3) 确认当前 Swarm 由一个管理节点和两个工作节点构成
在管理节点中运行下面的命令。

$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
lhm...4nn * mgr-1 Ready Active Leader
b74...gz3 wrk-1 Ready Active
o9x...um8 wrk-2 Ready Active
Swarm 集群目前就绪。payment_gateway 服务配置了部署约束,限制该服务只能运行在有 pcidss=yes 标签的工作节点之上。本步骤中将在 wrk-1 上添加该节点标签。

在实际操作中,添加该标签之前必须将某个 Docker 节点按 PCI 规范进行标准化。但是,这只是一个实验环境,所以就暂且跳过这一过程,直接将标签添加到 wrk-1 节点。

在 Swarm 管理节点运行下面的命令。

 1) 添加节点标签到 wrk-1

$ docker node update --label-add pcidss=yes wrk-1
Node 标签只在 Swarm 集群之内生效。
2) 确认节点标签

$ docker node inspect wrk-1

wrk-1 工作节点现在已经配置完成,所以该节点可以运行 payment_gateway 服务副本了。

应用定义了 4 个密钥,这些都需要在应用部署前创建。

postgress_password。
staging_token。
revprox_cert。
revprox_key。
在管理节点运行下面的命令,来创建这些密钥。
1) 创建新的键值对
密钥中有 3 个是需要加密 key 的。在本步骤中会创建加密 key,下一步会将加密 key 放到 Docker 密钥文件当中。

$ openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout domain.key -x509 -days 365 -out domain.crt

 2) 创建 revprox_cert、revprox_key 以及 postgress_password 密钥

$ docker secret create revprox_cert domain.crt
cqblzfpyv5cxb5wbvtrbpvrrj

$ docker secret create revprox_key domain.key
jqd1ramk2x7g0s2e9ynhdyl4p

$ docker secret create postgres_password domain.key
njpdklhjcg8noy64aileyod6l
3) 创建 stage_token 密钥

$ echo staging | docker secret create staging_token -
sqy21qep9w17h04k3600o6qsj
4) 列出所有密钥

$ docker secret ls
ID NAME CREATED UPDATED
njp...d6l postgres_password 47 seconds ago 47 seconds ago
cqb...rrj revprox_cert About a minute ago About a minute ago
jqd...l4p revprox_key About a minute ago About a minute ago
sqy...qsj staging_token 23 seconds ago 23 seconds ago
上面已经完成了全部的前置准备。是时候开始部署应用了!

部署示例应用
如果还没有代码,请先复制应用的 GitHub 仓库到 Swarm 管理节点。

$ git clone https://github.com/dockersamples/atsea-sample-shop-app.git

$ cd atsea-sample-shop-app

Stack 通过 docker stack deploy 命令完成部署。基础格式下,该命令允许传入两个参数。

    Stack 文件的名称。
    Stack 的名称。
应用的 GitHub 仓库中包含一个名为 docker-stack.yml 的 Stack 文件。这里会使用该文件。这里为 Stack 起名 seastack。

在 Swarm 管理节点的 atsea-sample-shop-app 目录下运行下面的命令。

$ docker stack deploy -c docker-stack.yml seastack

可以运行 docker network ls 以及 docker service ls 命令来查看应用的网络和服务情况。

下面是命令输出中几个需要注意的地方。

网络是先于服务创建的。这是因为服务依赖于网络,所以网络需要在服务启动前创建。

Docker 将 Stack 名称附加到由他创建的任何资源名称前作为前缀。在本例中,Stack 名为 seastack,所以所有资源名称的格式都如:seastack_<resource>。例如,payment 网络的名称是 seastack_payment。而在部署之前创建的资源则没有被重命名,比如密钥。

另一个需要注意的点是出现了新的名为 seastack_default 的网络。该网络并未在Stack文件中定义,那为什么会创建呢?每个服务都需要连接到网络,但是 visualizer 服务并没有指定具体的网络。因此,Docker 创建了名为 seastack_default 的网络,并将 visualizer 连接到该网络。

可以通过两个命令来确认当前 Stack 的状态。docker stack ls 列出了系统中全部 Stack,包括每个 Stack 下面包含多少服务。docker stack ps <stack-name> 针对某个指定 Stack 展示了更详细的信息,例如期望状态以及当前状态。下面一起来了解下这两条命令。

$ docker stack ls

$ docker stack ps seastack

在服务启动失败时,docker stack ps 命令是首选的问题定位方式。该命令展示了 Stack 中每个服务的概况,包括服务副本所在节点、当前状态、期望状态以及异常信息。从下面的输出信息中能看出 reverse_proxy 服务在 wrk-2 节点上两次尝试启动副本失败。

$ docker stack ps seastack

如果想查看具体某个服务的详细信息,可以使用 docker service logs 命令。读者需要将服务名称 /ID 或者副本 ID 作为参数传入。如果传入服务名称或 ID,可以看到所有服务副本的日志信息。如果传入的是副本 ID,则只会看到对应副本的日志信息。

下面的 docker service logs 命令展示了 seastack_reverse_proxy 服务的全部副本日志,其中包含了前面输出中的两次副本启动失败的日志。

#1host not found#1host not found
输出内容为了适应页面展示,已经经过裁剪,但是还是可以看到全部 3 个服务副本的日志(两个启动失败,1 个正在运行)。每行的开始都是副本的名称,包括服务名称、副本序号、副本 ID 以及副本所在主机的名称。接下来是具体的日志输出。

    提示:大家可能已经注意到前面日志中全部副本的序号都是 1。这是因为 Docker 每次只创建一个副本,并且只有当前面的副本启动失败时才会创建新的。

因为输出内容经过裁剪,所以具体原因很难明确,但看起来前两次副本启动失败原因是其依赖的某个服务仍然在启动中(一种启动时服务间依赖导致的竞争条件)。

可以继续跟踪日志(--follow),查看日志尾部内容(--tail),或者获取额外的详细信息(--details)。

 

Stack管理应用

Stack 是一组相关联的服务和基础设施,需要进行统一的部署和管理。Stack 是由普通的 Docker 资源构建而来:网络、卷、密钥、服务等。可以通过普通的 Docker 命令对其进行查看和重新配置,例如 docker network、docker volume、docker secret、docker service 等。

在此前提之下,通过 docker service 命令来管理 Stack 中某个服务是可行的。一个简单的例子是通过 docker service scale 命令来扩充 appserver 服务的副本数。但是,这并不是推荐的方式!

推荐方式是通过声明式方式修改,即将 Stack 文件作为配置的唯一声明。所有 Stack 相关的改动都需要体现在 Stack 文件中,然后更新重新部署应用所需的 Stack 文件。

下面是一个简单例子,阐述了为什么通过命令修改的方式不好(通过 CLI 进行变更)。

假设已经部署了一个 Stack,采用的 Stack 文件是《Docker Stack》一 节中从 GitHub 复制的仓库中的 docker-stack.yml。目前 appserver 服务有两个副本。如果通过 docker service scale 命令将副本修改为 4 个,当前运行的集群会有 4 个副本,但是 Stack 文件中仍然是两个。

假设通过修改 Stack 文件对 Stack 做了某些改动,然后通过 docker stack deploy 命令进行滚动部署。这会导致 appserver 服务副本数被回滚到两个,因为 Stack 文件就是这么定义的。推荐对 Stack 所有的变更都通过修改 Stack 文件来进行,并且将该文件放到一个合适的版本控制系统当中。

一起来回顾对Stack进行两个声明式修改的过程。目标是进行如下改动。

增加 appserver 副本数,数量为 2~10。将 visualizer 服务的优雅停止时间增加到 2min。修改 docker-stack.yml 文件,更新两个值:services.appserver.deploy.replicas=10和services.visualizer.stop_grace_period=2m。

目前,Stack 文件中的内容如下。

保存文件并重新部署应用。

$ docker stack deploy -c docker-stack.yml seastack

以上重新部署应用的方式,只会更新存在变更的部分。

运行 docker stack ps 命令来确认 appserver 副本数量确实增加。

$ docker stack ps seastack

注意关于 visualizer 服务有两行内容。其中一行表示某个副本在 3s 前停止,另一行表示新副本已经运行了 1s。这是因为刚才对 visualizer 服务作了修改,所以 Swarm 集群终止了正在运行的副本,并且启动了新的副本,新副本中更新了 stop_grace_period 的值。

还需要注意的是,appserver 服务目前拥有 10 个副本,但不同副本的“CURRENT STATE”一列状态并不相同:有些处于 running 状态,而有些仍在 starting 状态。

经过足够的时间,集群的状态会完成收敛,期望状态和当前状态就会保持一致。在那时,集群中实际部署和观察到的状态,就会跟 Stack 文件中定义的内容完全一致。

所有应用 /Stack 都应采用该方式进行更新。所有的变更都应该通过 Stack 文件进行声明,然后通过 docker stack deploy 进行部署。

正确的删除某个 Stack 方式是通过 docker stack rm 命令。一定要谨慎!删除 Stack 不会进行二次确认。

$ docker stack rm seastack

注意:网络和服务已经删除,但是密钥并没有。这是因为密钥是在 Stack 部署前就创建并存在了。在 Stack 最上层结构中定义的卷同样不会被 docker stack rm 命令删除。这是因为卷的设计初衷是保存持久化数据,其生命周期独立于容器、服务以及 Stack 之外。

 

常用命令

1) docker stsack deploy
用于根据 Stack 文件(通常是 docker-stack.yml)部署和更新 Stack 服务的命令。
2) docker stack ls
会列出 Swarm 集群中的全部 Stack,包括每个 Stack 拥有多少服务。
3) docker stack ps
列出某个已经部署的 Stack 相关详情。该命令支持 Stack 名称作为其主要参数,列举了服务副本在节点的分布情况,以及期望状态和当前状态。
4) docker stack rm
命令用于从 Swarm 集群中移除 Stack。移除操作执行前并不会进行二次确认。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值