将服务部署到 swarm

Swarm 服务使用声明性模型,这意味着您需要定义 desired 状态,并依赖 Docker 来维护此状态。这 state 包括(但不限于)以下信息:

  • 服务容器应运行的镜像名称和标记
  • 参与服务的容器数量
  • 是否向 swarm 外部的客户端公开了任何端口
  • 服务是否应在 Docker 启动时自动启动
  • 服务重新启动时发生的特定行为(例如 是否使用滚动重启)
  • 服务可以运行的节点的特征(例如资源 约束和放置首选项)

有关 Swarm 模式的概述,请参阅 Swarm 模式关键概念。 有关服务工作原理的概述,请参阅服务的工作原理

创建服务

要创建无需额外配置的单副本服务,您只需要 以提供镜像名称。此命令使用 随机生成的 name,并且没有已发布的端口。这是一个天真的例子,因为 您无法与 Nginx 服务交互。

$ docker service create nginx

该服务被安排在可用节点上。确认服务 已成功创建并启动,请使用以下命令:docker service ls

$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE                                                                                             PORTS
a3iixnklxuem        quizzical_lamarr    replicated          1/1                 docker.io/library/nginx@sha256:41ad9967ea448d7c2b203c699b429abe1ed5af331cd92533900c6d77490e0268

创建的服务并不总是立即运行。服务可以处于待处理状态 state (如果其镜像不可用),则没有节点满足 配置,或出于其他原因。有关更多信息,请参阅 待处理服务 信息。

要为您的服务提供名称,请使用以下标志:--name

$ docker service create --name my_web nginx

就像使用独立容器一样,您可以指定一个命令,该命令 服务的容器应该运行,方法是将其添加到镜像名称之后。这个例子 启动一个名为 Service 的服务,该服务使用镜像并运行 命令:helloworldalpineping docker.com

$ docker service create --name helloworld alpine ping docker.com

您还可以指定要使用的服务的镜像标签。此示例修改 前一个使用标签:alpine:3.6

$ docker service create --name helloworld alpine:3.6 ping docker.com

有关镜像标签分辨率的更多详细信息,请参阅指定服务应使用的镜像版本

Swarm 的 gMSA

注意

此示例仅适用于 Windows 容器。

Swarm 现在允许使用 Docker 配置作为 gMSA 凭证规范 - 这是经过 Active Directory 身份验证的应用程序的要求。这减轻了将凭证规范分发到使用它们的节点的负担。

以下示例假定 gMSA 及其凭证规范(称为 credspec.json)已存在,并且要部署到的节点已为 gMSA 正确配置。

要将配置用作凭证规范,请首先创建包含凭证规范的 Docker 配置:

$ docker config create credspec credspec.json

现在,您应该有一个名为 credspec 的 Docker 配置,并且您可以使用此凭证规范创建服务。为此,请在配置名称中使用 --credential-spec 标志,如下所示:

$ docker service create --credential-spec="config://credspec" <your image>

您的服务在启动时使用 gMSA 凭证规范,但与典型的 Docker 配置(通过传递 --config 标志使用)不同,凭证规范不会装载到容器中。

使用私有注册表上的镜像创建服务

如果您的镜像在需要登录的专用注册表中可用,请在登录后将标志与 一起使用。如果 您的镜像存储在 上,这是一个私有注册表,请使用 如下所示的命令:--with-registry-authdocker service createregistry.example.com

$ docker login registry.example.com

$ docker service  create \
  --with-registry-auth \
  --name my_service \
  registry.example.com/acme/my_image:latest

这会将登录令牌从本地客户端传递到 swarm 节点,其中 使用加密的 WAL 日志部署服务。有了这些信息, 节点能够登录到 Registry 并拉取镜像。

提供托管服务账户的凭证规格

在 Enterprise Edition 3.0 中,通过使用 Docker 配置功能集中分发和管理组托管服务帐户 (gMSA) 凭据,从而提高了安全性。Swarm 现在允许将 Docker 配置用作 gMSA 凭证规范,从而减轻了将凭证规范分发到使用它们的节点的负担。

注意

此选项仅适用于使用 Windows 容器的服务。

凭证规范文件在运行时应用,无需基于主机的凭证规范文件或注册表项 - 不会将 gMSA 凭证写入工作器节点上的磁盘。在容器启动之前,您可以向运行 swarm kit worker 节点的 Docker Engine 提供凭证规范。使用基于 gMSA 的配置部署服务时,凭证规范将直接传递到该服务中容器的运行时。

必须采用以下格式之一:--credential-spec

  • file://<filename>:引用的文件必须存在于 docker 数据目录的子目录中,在 Windows 上默认为。例如,指定 loads .CredentialSpecsC:\ProgramData\Docker\file://spec.jsonC:\ProgramData\Docker\CredentialSpecs\spec.json
  • registry://<value-name>:凭证规范是从守护程序主机上的 Windows 注册表中读取的。
  • config://<config-name>:在 CLI 中,配置名称会自动转换为配置 ID。 使用指定中包含的凭证规范。config

以下简单示例从 Active Directory (AD) 实例中检索 gMSA 名称和 JSON 内容:

$ name="mygmsa"
$ contents="{...}"
$ echo $contents > contents.json

确保已为 gMSA 正确配置了要部署到的节点。

要将配置用作凭证规范,请在名为 . 您可以为 的名称指定任何名称。credpspec.jsonconfig

$ docker config create --label com.docker.gmsa.name=mygmsa credspec credspec.json

现在,您可以使用此凭证规范创建服务。使用配置名称指定标志:--credential-spec

$ docker service create --credential-spec="config://credspec" <your image>

您的服务在启动时使用 gMSA 凭证规范,但与典型的 Docker 配置(通过传递 --config 标志使用)不同,凭证规范不会装载到容器中。

更新服务

您可以使用该命令更改有关现有服务的几乎所有内容。当您更新服务时,Docker 会停止其 容器,并使用新配置重新启动它们。docker service update

由于 Nginx 是一项 Web 服务,因此如果您发布 80 端口,效果会好得多 发送到 Swarm 外部的客户端。您可以在创建服务时指定此项。 使用 or 标志。更新现有服务时,标志 是。还有一个标志可以删除一个端口,该 之前出版过。-p--publish--publish-add--publish-rm

假设上一节中的服务仍然存在,请使用 以下命令将其更新为发布端口 80。my_web

$ docker service update --publish-add 80 my_web

要验证它是否有效,请使用 :docker service ls

$ docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE                                                                                             PORTS
4nhxl7oxw5vz        my_web              replicated          1/1                 docker.io/library/nginx@sha256:41ad9967ea448d7c2b203c699b429abe1ed5af331cd92533900c6d77490e0268   *:0->80/tcp

有关发布端口工作原理的更多信息,请参阅发布端口

您可以更新有关现有服务的几乎所有配置详细信息, 包括它运行的镜像名称和标记。请参阅在创建服务后更新服务的镜像

删除服务

要删除服务,请使用命令。您可以删除 service 的 ID 或名称,如命令输出中所示。以下命令将删除该服务。docker service removedocker service lsmy_web

$ docker service remove my_web

服务配置详细信息

以下部分提供有关服务配置的详细信息。本主题 并未涵盖所有标志或场景。在几乎所有情况下,只要您可以 在创建服务时定义配置,您还可以更新现有的 service 的配置。

请参阅 docker service createdocker service update 的命令行参考,或运行 其中一个带有标志的命令。--help

配置运行时环境

您可以在 容器:

  • 使用标志的环境变量--env
  • 使用标志的容器内的工作目录--workdir
  • 使用标志的用户名或 UID--user

以下服务的容器将环境变量设置为 、从目录运行,并以用户身份运行。$MYVARmyvalue/tmp/my_user

$ docker service create --name helloworld \
  --env MYVAR=myvalue \
  --workdir /tmp \
  --user my_user \
  alpine ping docker.com

更新现有服务运行的命令

要更新现有服务运行的命令,您可以使用该标志。 以下示例更新了名为 它运行命令,而不是它正在运行的任何命令 以前:--argshelloworldping docker.com

$ docker service update --args "ping docker.com" helloworld

指定服务应使用的镜像版本

当您创建服务时,未指定有关 要使用的镜像,则服务使用带有标签的版本。 您可以强制服务在几个 不同的方法,具体取决于您想要的结果。latest

镜像版本可以用几种不同的方式表示:

  • 如果指定标签,则管理器(或 Docker 客户端,如果使用内容信任)会将该标签解析为摘要。 当在 worker 节点上收到创建容器任务的请求时, Worker 节点只能看到摘要,而看不到标签。

    $ docker service create --name="myservice" ubuntu:16.04
    

    某些标记表示离散版本,例如 .像这样的标签 随着时间的推移,几乎总是分解为稳定的摘要。推荐 请尽可能使用此类标签。ubuntu:16.04

    其他类型的标记(如 或 )可能会解析为新的 digest 的 Digest 频率,具体取决于镜像作者更新标签的频率。是的 不建议使用频繁更新的标签运行服务,以 防止不同的 Service Replica 任务使用不同的镜像版本。latestnightly

  • 如果您根本不指定版本,按照惯例,镜像的标签 解析为摘要。工作人员在创建 服务任务。latest

    因此,以下两个命令是等效的:

    $ docker service create --name="myservice" ubuntu
    
    $ docker service create --name="myservice" ubuntu:latest
    
  • 如果直接指定摘要,则镜像的确切版本始终为 在创建服务任务时使用。

    $ docker service create \
        --name="myservice" \
        ubuntu:16.04@sha256:35bc48a1ca97c3971611dc4662d08d131869daa692acb281c7e9e052924e38b1
    

创建服务时,镜像的标签将解析为特定的摘要 该标签在创建服务时指向。为此 Worker 节点 service 永远使用该特定摘要,除非该服务明确 更新。如果您确实使用经常更改的标签,则此功能尤其重要 例如 ,因为它确保所有服务任务都使用相同的版本 的镜像。latest

注意

如果内容信任为 enabled,则客户端实际上会将镜像的标签解析为之前的摘要 联系 Swarm Manager,以验证镜像是否已签名。 因此,如果您使用内容信任,则 swarm 管理器会收到请求 预先解决。在这种情况下,如果客户端无法将镜像解析为 digest 时,请求将失败。

如果经理无法将标签解析为摘要,则每个 worker node 负责将标签解析为摘要,不同的节点可能会 使用不同版本的镜像。如果发生这种情况,则会显示类似 记录 following,将占位符替换为真实信息。

unable to pin image <IMAGE-NAME> to digest: <REASON>

要查看镜像的当前摘要,请发出命令并查找该行。这 以下是此内容当时的当前摘要 写的。为清楚起见,输出被截断。docker inspect <IMAGE>:<TAG>RepoDigestsubuntu:latest

$ docker inspect ubuntu:latest
"RepoDigests": [
    "ubuntu@sha256:35bc48a1ca97c3971611dc4662d08d131869daa692acb281c7e9e052924e38b1"
],

创建服务后,除非您明确使用标志运行,否则其镜像永远不会更新,如下所述。其他更新 扩展服务、添加或删除网络或卷等操作, 重命名服务或任何其他类型的更新操作不会更新 service 的镜像。docker service update--image

创建服务后更新服务镜像

每个标签代表一个摘要,类似于 Git 哈希。某些标记(如 )会经常更新以指向新的摘要。其他 (如 ) 表示已发布的软件版本,不应 update 指向新的摘要(如果有)。当您创建服务时,它会 受限制使用镜像的特定摘要创建任务,直到您 使用带标志更新服务。latestubuntu:16.04service update--image

当您使用该标志运行时,swarm manager 会查询 Docker Hub 或当前摘要标签的私有 Docker 注册表 指向并更新 Service 任务以使用该摘要。service update--image

注意

如果您使用内容信任,则 Docker 客户端解析镜像,Swarm Manager 接收镜像和摘要, 而不是标签。

通常,经理可以将标签解析为新的摘要和服务 更新,重新部署每个任务以使用新镜像。如果经理不能 解决标签或其他问题,接下来的两节概述了什么 期待。

如果 Manager 解析了标签

如果 swarm 管理器可以将 image 标签解析为摘要,它会指示 worker nodes 重新部署任务并使用该摘要中的镜像。

  • 如果 worker 在该摘要中缓存了镜像,则它会使用它。

  • 如果没有,它会尝试从 Docker Hub 或私有注册表中提取镜像。

    • 如果成功,则使用新镜像部署任务。

    • 如果 worker 无法拉取镜像,则服务将无法在该镜像上部署 worker 节点。Docker 再次尝试部署任务,可能在不同的 worker 节点。

如果 Manager 无法解析标签

如果 swarm 管理器无法将镜像解析为摘要,则不会丢失所有内容:

  • 管理器指示 Worker 节点使用镜像重新部署任务 在那个标签上。

  • 如果 worker 具有解析为该标签的本地缓存镜像,则使用 那个镜像。

  • 如果 worker 没有解析为标签的本地缓存镜像,则 worker 尝试连接到 Docker Hub 或私有注册表以拉取 镜像。

    • 如果成功,则 worker 将使用该镜像。

    • 如果失败,则任务部署失败,Manager 将再次尝试部署 任务,可能位于不同的 worker 节点上。

发布端口

创建 Swarm 服务时,您可以将该服务的端口发布到主机 以两种方式在 swarm 之外:

  • 您可以依赖布线网格。 当您发布服务端口时,swarm 会使该服务可通过 target 端口,无论是否有 服务是否在该节点上运行。这不那么复杂,而且是正确的 多种服务类型的选择。

  • 您可以直接在运行该服务的 swarm 节点上发布服务任务的端口。这将绕过路由网格并提供 最大的灵活性,包括您开发自己的路由的能力 框架。但是,您有责任跟踪每个任务的位置 运行请求并将其路由到任务,以及跨节点进行负载均衡。

请继续阅读以了解有关每种方法的更多信息和用例。

使用路由网格发布服务的端口

要将服务的端口从外部发布到 swarm,请使用 flag。swarm 使服务 可在每个 Swarm 节点上的已发布端口访问。如果外部主机 连接到任何 Swarm 节点上的该端口,路由网格会将其路由到 Task。 外部主机不需要知道 IP 地址或内部使用的 port 来与服务交互。当用户或进程 连接到服务时,任何运行 Service Task 的工作节点都可能响应。为 有关 Swarm 服务网络的更多详细信息,请参阅管理 Swarm 服务网络--publish <PUBLISHED-PORT>:<SERVICE-PORT>

示例:在 10 节点 swarm 上运行三任务 Nginx 服务

假设您有一个 10 节点的 swarm,并且您部署了一个运行 10 节点 Swarm 上的 3 个任务:

$ docker service create --name my_web \
                        --replicas 3 \
                        --publish published=8080,target=80 \
                        nginx

三个任务在最多三个节点上运行。您无需知道哪些节点 正在运行任务;连接到 10 个节点中任何一个节点上的端口 8080 将您连接到三个任务之一。您可以使用 . 以下示例假定 它是 swarm 节点之一。如果 事实并非如此,或者无法解析为您的 IP 地址 host,请替换主机的 IP 地址或可解析的主机名。nginxcurllocalhostlocalhost

HTML 输出被截断:

$ curl localhost:8080

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...truncated...
</html>

后续连接可以路由到同一个 swarm 节点或不同的 swarm 节点。

直接在 swarm 节点上发布服务的端口

如果您满足以下条件,则使用路由网格可能不是您的应用的正确选择 需要根据应用程序状态做出路由决策,或者您需要总计 控制将请求路由到服务任务的流程。发布 服务的端口直接位于运行它的节点上,请使用 flag 的选项。mode=host--publish

注意

如果你直接在 swarm 节点上发布服务的端口,using and also set 这将创建一个隐式的 限制,您只能在给定 Swarm 上为该服务运行一个任务 节点。您可以通过指定 without a port 来解决此问题 定义,这会导致 Docker 为每个任务分配一个随机端口。mode=hostpublished=<PORT>published

此外,如果使用而未使用 标志 ,则很难知道 哪些节点正在运行服务以将工作路由到它们。mode=host--mode=globaldocker service create

示例:在每个 swarm 节点上运行 nginx Web 服务器服务

nginx 是一个开源的反向代理,load balancer、HTTP 缓存和 Web 服务器。如果您使用 路由网格,连接到任何 Swarm 节点上的 nginx 端口都会显示 Web 页面,用于(实际上)运行该服务的随机 Swarm 节点。

以下示例在 swarm 中的每个节点上运行 nginx 作为服务,并且 在每个 Swarm 节点上本地公开 nginx 端口。

$ docker service create \
  --mode global \
  --publish mode=host,target=80,published=8080 \
  --name=nginx \
  nginx:latest

您可以在每个 swarm 节点的端口 8080 上访问 nginx 服务器。如果您添加了 node 添加到 swarm 中,则会在其上启动 nginx 任务。您不能再开始另一个 service 或 container 绑定到端口 8080 的任何 Swarm 节点上。

注意

这是一个纯粹的说明性示例。创建应用层 多层服务的路由框架很复杂,超出了 本主题。

将服务连接到覆盖网络

您可以使用叠加网络连接群中的一个或多个服务。

首先,使用带有 flag 的命令在 Manager 节点上创建覆盖网络。docker network create--driver overlay

$ docker network create --driver overlay my-network

在 swarm 模式下创建覆盖网络后,所有管理器节点都可以访问 到网络。

您可以创建新服务并传递标志以附加服务 到 overlay 网络:--network

$ docker service create \
  --replicas 3 \
  --network my-network \
  --name my-web \
  nginx

群扩展到运行服务的每个节点。my-network

您还可以使用该标志将现有服务连接到覆盖网络。--network-add

$ docker service update --network-add my-network my-web

要断开正在运行的服务与网络的连接,请使用 flag。--network-rm

$ docker service update --network-rm my-network my-web

有关覆盖网络和服务发现的更多信息,请参阅将服务附加到覆盖网络Docker 群模式覆盖网络安全模型

向服务授予对密钥的访问权限

要创建有权访问 Docker 托管密钥的服务,请使用该标志。有关更多信息,请参阅管理 Docker 服务的敏感字符串 (密钥)--secret

自定义服务的隔离模式

重要

此设置仅适用于 Windows 主机,对于 Linux 主机,此设置将被忽略。

Docker 允许您指定 swarm 服务的隔离 模式。隔离模式可以是以下模式之一:

  • default:使用为 Docker 主机配置的默认隔离模式,如 由 中的 flag 或 array 配置 。如果 守护进程未指定隔离技术,是默认 对于 Windows Server,并且是 Windows 10 的。-exec-optexec-optsdaemon.jsonprocesshyperv

  • process:在主机上将服务任务作为单独的进程运行。

    注意

    process隔离模式仅在 Windows Server 上受支持。 Windows 10 仅支持隔离模式。hyperv

  • hyperv:将服务任务作为隔离任务运行。这会增加 开销,但提供了更多的隔离。hyperv

您可以在创建或更新新服务时使用 国旗。--isolation

控制服务放置

Swarm 服务提供了几种不同的方法来控制规模和 将服务放置在不同的节点上。

  • 您可以指定服务是否需要运行特定数量的副本 或者应该在每个 worker 节点上全局运行。请参阅复制服务或全球服务

  • 您可以配置服务的 CPU 或内存要求,以及 service 仅在可以满足这些要求的节点上运行。

  • 放置约束允许您配置服务 仅在具有特定(任意)数据集的节点上运行,并导致 如果不存在合适的节点,则部署失败。例如,您可以 指定您的服务应仅在 Arbitrary label(任意标签)设置为 的节点上运行。pci_complianttrue

  • 放置首选项允许您应用任意 label 并为每个节点分配一系列值,并将服务的任务分散 使用算法在这些节点之间。目前,唯一支持的算法 是 ,这会尝试将它们均匀放置。例如,如果你 使用值为 1-10 的 label 标记每个节点,然后指定 键入 的 放置首选项 ,则服务任务将作为 在获取其他 放置约束、放置首选项和其他特定于节点的 考虑限制。spreadrackrackrack

    与约束不同,放置首选项是 best-effort,而服务 如果没有节点可以满足首选项,则不会 Fail Deploy。如果指定 placement 首选项,则与该首选项匹配的节点为 当 Swarm Manager 决定哪些节点应该运行 服务任务。其他因素,例如服务的高可用性、 此外,还要考虑计划运行服务任务的节点。为 例如,如果您有 N 个带有机架标签的节点(然后是其他一些节点),并且 您的服务配置为运行 N+1 个副本,则 +1 被调度在 节点上尚未包含该服务的节点(如果有的话),无论 该节点是否具有标签。rack

复制服务或全球服务

Swarm 模式有两种类型的服务:复制服务和全局服务。对于复制的 services 中,您可以指定 Swarm Manager 要 schedule 到可用节点上。对于全局服务,调度程序会放置一个 task 的 task 任务。

您可以使用该标志控制服务类型。如果未指定 模式,则服务默认为 。对于复制的服务,您可以指定 要使用该标志开始的副本任务数。为 示例,要启动具有 3 个副本任务的复制 nginx 服务:--modereplicated--replicas

$ docker service create \
  --name my_web \
  --replicas 3 \
  nginx

要在每个可用节点上启动全局服务,请传递给 。每次有新节点可用时,调度程序 将 Global Service 的任务放置在新节点上。例如,要启动 在 Swarm 中的每个节点上运行 Alpine 的服务:--mode globaldocker service create

$ docker service create \
  --name myservice \
  --mode global \
  alpine top

Service Constraints 允许您设置节点在计划程序之前要满足的条件 将服务部署到节点。您可以将约束应用于 基于节点属性和元数据或引擎元数据的服务。了解更多 有关约束的信息,请参阅 CLI 参考docker service create

为服务预留内存或 CPU

要为服务保留给定的内存量或 CPU 数量,请使用 or 标志。如果没有可用的节点可以满足 要求(例如,如果您请求 4 个 CPU 并且 Swarm 中没有节点 具有 4 个 CPU),则服务将保持待处理状态,直到相应的节点 可用于运行其任务。--reserve-memory--reserve-cpu

内存不足异常 (OOME)

如果您的服务尝试使用的内存多于 swarm 节点的可用内存,则 您可能会遇到内存不足异常 (OOME) 和容器,或者 Docker 守护程序可能会被内核 OOM 终止程序杀死。为了防止这种情况 发生时,请确保您的应用程序在具有足够内存的主机上运行,并且 请参阅了解内存不足的风险

Swarm 服务允许您使用资源约束、放置首选项和 标签,以确保您的服务部署到适当的 Swarm 节点。

放置约束

使用放置约束来控制服务可以分配到的节点。在 以下示例,该服务仅在设置了 label (标签) 自。如果没有适当标记的节点可用,则 task 将等待,直到它们变为可用。标志使用相等 运算符 ( 或 )。对于复制的服务,可能会所有 服务在同一节点上运行,或者每个节点只运行一个副本,或者某些 节点不运行任何副本。对于全球服务,该服务在每个 满足放置约束和任何资源要求的节点。regioneastPending--constraint==!=

$ docker service create \
  --name my-nginx \
  --replicas 5 \
  --constraint node.labels.region==east \
  nginx

您还可以在文件中使用服务级别密钥。constraintcompose.yml

如果您指定多个放置约束,则服务只会部署到 节点。以下示例将服务限制为在其上运行 其中 设置为 且未设置为 :regioneasttypedevel

$ docker service create \
  --name my-nginx \
  --mode global \
  --constraint node.labels.region==east \
  --constraint node.labels.type!=devel \
  nginx

也可以将放置约束与放置首选项结合使用 和 CPU/内存限制。请注意,不要使用不是 可能实现。

有关约束的更多信息,请参阅 CLI 参考docker service create

放置首选项

placement constraints 限制节点服务 可以运行,则 Placement Preferences 会尝试将任务放置在适当的节点上 以算法方式 (目前,仅均匀分布)。例如,如果你 为每个节点分配一个标签,您可以将放置首选项设置为 Spread 服务在具有标签的节点之间均匀分配,按值。这样,如果 您丢失了一个机架,该服务仍在其他机架上的节点上运行。rackrack

位置首选项不是严格执行的。如果没有节点具有标签 您在首选项中指定,则部署服务时,就像 首选项。

注意

全局服务的 Placement preferences 将被忽略。

以下示例设置一个首选项以跨节点分布部署 基于标签的值。如果某些节点具有,而其他节点具有 ,则服务为 在两组节点之间尽可能均匀地部署。datacenterdatacenter=us-eastdatacenter=us-west

$ docker service create \
  --replicas 9 \
  --name redis_2 \
  --placement-pref 'spread=node.labels.datacenter' \
  redis:7.4.0

注意

缺少用于传播的标签的节点仍会收到 任务分配。作为一个组,这些节点以相等的方式接收任务 与特定标签标识的任何其他组的比例 价值。从某种意义上说,缺少标签与标签 附加到它的 null 值。如果服务应仅在 标签用于跨页首选项的节点,则 首选项应与 constraint 结合使用。

您可以指定多个放置首选项,这些首选项将在 的顺序。以下示例使用 多个 Placement 首选项。任务首先分布在各种 datacenters,然后在机架上(如相应的标签所示):

$ docker service create \
  --replicas 9 \
  --name redis_2 \
  --placement-pref 'spread=node.labels.datacenter' \
  --placement-pref 'spread=node.labels.rack' \
  redis:7.4.0

也可以将放置首选项与放置约束结合使用 或 CPU/内存限制。请注意,不要使用不是 可能实现。

此图说明了放置首选项的工作原理:

How placement preferences work

使用 更新服务时,会在所有现有放置首选项之后附加新的放置首选项。 删除与 论点。docker service update--placement-pref-add--placement-pref-rm

配置服务的更新行为

在创建服务时,您可以指定滚动更新行为,以指定 swarm 应在您运行 时将更改应用于服务。 您还可以将这些标志指定为更新的一部分,作为 .docker service updatedocker service update

该标志用于配置服务更新之间的时间延迟 任务或任务集。您可以将时间描述为 Number of seconds 、 minutes 或 hours 。所以表示 10 分 30 秒延迟。--update-delayTTsTmTh10m30s

默认情况下,计划程序一次更新 1 个任务。您可以传递该标志来配置最大服务任务数 调度程序同时更新。--update-parallelism

当对单个任务的更新返回状态 时,计划程序 通过继续执行另一个任务来继续更新,直到更新所有任务。 如果在更新期间的任何时候任务返回 ,则调度程序将暂停 更新。您可以使用 或 的标志来控制行为。RUNNINGFAILED--update-failure-actiondocker service createdocker service update

在下面的示例服务中,计划程序将更新应用于最多 2 个 副本。当更新的任务返回 或 时 , 计划程序会等待 10 秒,然后停止下一个要更新的任务:RUNNINGFAILED

$ docker service create \
  --replicas 10 \
  --name my_web \
  --update-delay 10s \
  --update-parallelism 2 \
  --update-failure-action continue \
  alpine

该标志控制任务可以失败的比例 在更新期间,在更新整体被视为失败之前。为 示例,其中 , 在 10% 的更新任务失败后,更新将暂停。--update-max-failure-ratio--update-max-failure-ratio 0.1 --update-failure-action pause

如果任务未失败,则认为单个任务更新失败 启动,或者如果它在使用 国旗。的默认值为 30 秒,这意味着任务在任务 started 计入服务更新失败阈值,失败 之后不计算在内。--update-monitor--update-monitor

回滚到服务的上一个版本

如果服务的更新版本未按预期运行,则 可以使用 的标志手动回滚到服务的先前版本。这将还原服务 添加到最新命令之前就位的配置。docker service update--rollbackdocker service update

其他选项可以与 ;例如,要在任务之间没有延迟地执行回滚:--rollback--update-delay 0s

$ docker service update \
  --rollback \
  --update-delay 0s
  my_web

您可以将服务配置为在服务更新失败时自动回滚 进行部署。请参阅更新失败时自动回滚

手动回滚在服务器端处理,这允许手动启动 rollbacks 以遵循新的 rollback 参数。请注意,不能 与其他标志结合使用。--rollbackdocker service update

更新失败时自动回滚

您可以这样配置服务:如果对服务进行更新 导致重新部署失败,则服务可以自动回滚到 以前的配置。这有助于保护服务可用性。您可以设置 在服务创建或更新时出现以下一个或多个标志。如果你没有 set a value 时,使用默认值。

违约描述
--rollback-delay0s回滚任务后在回滚下一个任务之前要等待的时间。值 表示在部署第一个回滚任务后立即回滚第二个任务。0
--rollback-failure-actionpause当任务回滚失败时,是否回滚或尝试回滚其他任务。pausecontinue
--rollback-max-failure-ratio0回滚期间允许的失败率,指定为介于 0 和 1 之间的浮点数。例如,给定 5 个任务,失败率 将容忍一个任务回滚失败。值 表示不容忍任何失败,而值 表示容忍任意数量的失败。.201
--rollback-monitor5s每个任务回滚后的持续时间,用于监控失败。如果任务在此时间段之前停止,则回滚被视为失败。
--rollback-parallelism1要并行回滚的最大任务数。默认情况下,一次回滚一个任务。值 of 会导致所有任务并行回滚。0

以下示例将服务配置为自动回滚 如果 A 部署失败。两个任务可以回滚 平行。任务在回滚后会监控 20 秒,以确保它们这样做 不退出,并且最大故障率为 20%。默认值为 用于 和 。redisdocker service update--rollback-delay--rollback-failure-action

$ docker service create --name=my_redis \
                        --replicas=5 \
                        --rollback-parallelism=2 \
                        --rollback-monitor=20s \
                        --rollback-max-failure-ratio=.2 \
                        redis:latest

授予服务对卷或绑定挂载的访问权限

为了获得最佳性能和可移植性,您应该避免写入重要数据 直接写入容器的可写层。您应该改用数据卷 或 bind mounts。此原则也适用于服务。

您可以为 swarm 中的服务创建两种类型的挂载,即挂载或挂载。无论您使用哪种类型的挂载,都可以在创建服务时使用标志进行配置,或者在更新现有服务时使用 or 标志进行配置。默认值为数据卷,如果您 不要指定类型。volumebind--mount--mount-add--mount-rm

数据量

数据卷是独立于容器而存在的存储。这 Swarm 服务下数据卷的生命周期与 器皿。卷的寿命比任务和服务长,因此必须将其删除 单独管理。可以在部署服务之前创建卷,或者如果 当任务被安排在特定主机上时,它们不存在,它们是 根据服务上的卷规范自动创建。

要将现有数据卷与服务一起使用,请使用以下标志:--mount

$ docker service create \
  --mount src=<VOLUME-NAME>,dst=<CONTAINER-PATH> \
  --name myservice \
  <IMAGE>

如果任务为 scheduled 到特定主机,然后创建一个。默认卷 driver 是 。将其他卷驱动程序与此按需创建一起使用 pattern,请使用 flag 指定驱动程序及其选项:<VOLUME-NAME>local--mount

$ docker service create \
  --mount type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=<DRIVER>,volume-opt=<KEY0>=<VALUE0>,volume-opt=<KEY1>=<VALUE1>
  --name myservice \
  <IMAGE>

有关如何创建数据卷和使用卷的更多信息 驱动程序,请参阅使用卷

绑定挂载

绑定挂载是来自调度程序部署的主机的文件系统路径 任务的容器。Docker 将路径挂载到容器中。这 在 Swarm 初始化 任务。

以下示例显示了 bind 挂载语法:

  • 要挂载读写绑定:

    $ docker service create \
      --mount type=bind,src=<HOST-PATH>,dst=<CONTAINER-PATH> \
      --name myservice \
      <IMAGE>
    
  • 要挂载只读绑定:

    $ docker service create \
      --mount type=bind,src=<HOST-PATH>,dst=<CONTAINER-PATH>,readonly \
      --name myservice \
      <IMAGE>
    

重要

绑定挂载可能很有用,但它们也可能导致问题。在 大多数情况下,建议您构建应用程序,以便 不需要从主机挂载路径。主要风险包括 以后:

  • 如果您将 mount 主机路径绑定到服务的容器中,则路径 必须存在于每个 Swarm 节点上。Docker swarm 模式调度器可以调度 满足资源可用性要求的任何计算机上的容器 并满足您指定的所有约束和放置首选项。

  • Docker swarm 模式调度程序可能会重新调度正在运行的服务 容器(如果它们变得运行状况不佳或无法访问)。

  • Host bind 挂载是不可移植的。当您使用 bind 挂载时,没有 保证您的应用程序在开发中的运行方式与开发方式相同 在生产中。

使用模板创建服务

您可以使用语法将模板用于 的某些标志 , 由 Go 的 text/template 包提供。service create

支持以下标志:

  • --hostname
  • --mount
  • --env

Go 模板的有效占位符为:

占 位 符描述
.Service.ID服务 ID
.Service.Name服务名称
.Service.Labels服务标签
.Node.ID节点 ID
.Node.Hostname节点主机名
.Task.Name任务名称
.Task.Slot任务槽

模板示例

此示例根据 service 的名称和运行容器的节点的 ID:

$ docker service create --name hosttempl \
                        --hostname="{{.Node.ID}}-{{.Service.Name}}"\
                         busybox top

要查看使用模板的结果,请使用 and 命令。docker service psdocker inspect

$ docker service ps va8ew30grofhjoychbr6iot8c

ID            NAME         IMAGE                                                                                   NODE          DESIRED STATE  CURRENT STATE               ERROR  PORTS
wo41w8hg8qan  hosttempl.1  busybox:latest@sha256:29f5d56d12684887bdfa50dcd29fc31eea4aaf4ad3bec43daf19026a7ce69912  2e7a8a9c4da2  Running        Running about a minute ago
$ docker inspect --format="{{.Config.Hostname}}" hosttempl.1.wo41w8hg8qanxwjwsg4kxpprj

了解更多信息