docker 服务创建

描述创建新服务
用法docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]

此命令适用于 Swarm 编排器。

描述

按照指定参数创建服务。

注意

这是一个集群管理命令,必须在 swarm 上执行 Manager 节点。要了解 Manager 和 worker,请参阅 文档。

选项

选择违约描述
--cap-addAPI 1.41+添加 Linux 功能
--cap-dropAPI 1.41+丢弃 Linux 功能
--configAPI 1.30+指定要向服务公开的配置
--constraint放置约束
--container-label容器标签
--credential-specAPI 1.29+托管服务帐户的凭证规范(仅限 Windows)
-d, --detachAPI 1.29+立即退出,而不是等待服务收敛
--dnsAPI 1.25+设置自定义 DNS 服务器
--dns-optionAPI 1.25+设置 DNS 选项
--dns-searchAPI 1.25+设置自定义 DNS 搜索域
--endpoint-modevip端点模式(vip 或 dnsrr)
--entrypoint覆盖镜像的默认 ENTRYPOINT
-e, --env设置环境变量
--env-file读入环境变量文件
--generic-resource用户定义的资源
--groupAPI 1.25+为容器设置一个或多个补充用户组
--health-cmdAPI 1.25+运行以检查运行状况的命令
--health-intervalAPI 1.25+运行检查之间的时间 (ms|s|m|h)
--health-retriesAPI 1.25+报告运行状况不佳所需的连续失败
--health-start-interval接口 1.44+在开始期间运行检查之间的时间 (ms|s|m|h)
--health-start-periodAPI 1.29+容器在将重试次数计算为不稳定之前初始化的开始时间 (ms|s|m|h)
--health-timeoutAPI 1.25+允许运行一项检查的最长时间 (ms|s|m|h)
--hostAPI 1.25+设置一个或多个自定义主机到 IP 映射 (host:ip)
--hostnameAPI 1.25+容器主机名
--initAPI 1.37+在每个服务容器中使用 init 来转发信号和接收流程
--isolationAPI 1.35+服务容器隔离模式
-l, --label服务标签
--limit-cpu限制 CPU
--limit-memory限制内存
--limit-pidsAPI 1.41+限制最大进程数(默认值 0 = 无限制)
--log-driver记录服务的驱动程序
--log-opt记录驱动程序选项
--max-concurrentAPI 1.41+要并发运行的作业任务数(默认值等于 --replicas)
--modereplicated服务模式(、、、replicatedglobalreplicated-jobglobal-job)
--mount将文件系统挂载附加到服务
--name服务名称
--network网络附件
--no-healthcheckAPI 1.25+禁用任何容器指定的 HEALTHCHECK
--no-resolve-imageAPI 1.30+不查询注册表来解析镜像摘要和支持的平台
--oom-score-adjAPI 1.46+调整主机的 OOM 首选项(-1000 到 1000)
--placement-prefAPI 1.28+添加版面偏好设置
-p, --publish将端口发布为节点端口
-q, --quietSuppress progress 输出
--read-onlyAPI 1.28+以只读方式挂载容器的根文件系统
--replicas任务数
--replicas-max-per-nodeAPI 1.40+每个节点的最大任务数(默认值 0 = 无限制)
--reserve-cpu预留 CPU
--reserve-memory储备内存
--restart-condition满足条件时重新启动 (, , ) (默认noneon-failureanyany)
--restart-delay重启尝试之间的延迟 (ns|us|ms|s|m|h)(默认 5 秒)
--restart-max-attempts放弃前的最大重启次数
--restart-window用于评估重启策略的窗口 (ns|us|ms|s|m|h)
--rollback-delayAPI 1.28+任务回滚之间的延迟 (ns|us|ms|s|m|h)(默认为 0s)
--rollback-failure-actionAPI 1.28+回滚失败时的操作 (, ) (默认pausecontinuepause)
--rollback-max-failure-ratioAPI 1.28+回滚期间允许的失败率(默认值为 0)
--rollback-monitorAPI 1.28+每个任务回滚后监控失败的持续时间 (ns|us|ms|s|m|h)(默认 5 秒)
--rollback-orderAPI 1.29+回滚顺序 (, ) (默认start-firststop-firststop-first)
--rollback-parallelism1API 1.28+同时回滚的最大任务数(0 表示一次回滚所有任务)
--secretAPI 1.25+指定要向服务公开的密钥
--stop-grace-period强制终止容器前的等待时间 (ns|us|ms|s|m|h) (默认为 10 秒)
--stop-signalAPI 1.28+停止容器的信号
--sysctlAPI 1.40+Sysctl 选项
-t, --ttyAPI 1.25+分配伪 TTY
--ulimitAPI 1.41+Ulimit 选项
--update-delay更新之间的延迟 (ns|us|ms|s|m|h)(默认为 0s)
--update-failure-action更新失败时的操作 (, , ) (默认pausecontinuerollbackpause)
--update-max-failure-ratioAPI 1.25+更新期间允许的失败率(默认值为 0)
--update-monitorAPI 1.25+每次任务更新后监控失败的持续时间 (ns|us|ms|s|m|h)(默认为 5 秒)
--update-orderAPI 1.29+更新顺序 (, ) (默认start-firststop-firststop-first)
--update-parallelism1同时更新的最大任务数(0 表示一次更新所有任务)
-u, --user用户名或 UID (格式: <name|uid>[:<group|gid>])
--with-registry-auth将注册表身份验证详细信息发送到 swarm 代理
-w, --workdir容器内的工作目录

例子

创建服务

$ docker service create --name redis redis:7.4.1

dmu1ept4cxcfe8k8lhtux3ro3

$ docker service create --mode global --name redis2 redis:7.4.1

a8q9dasaafudfs8q8w32udass

$ docker service ls

ID            NAME    MODE        REPLICAS  IMAGE
dmu1ept4cxcf  redis   replicated  1/1       redis:7.4.1
a8q9dasaafud  redis2  global      1/1       redis:7.4.1

使用私有注册表 (--with-registry-auth) 上的镜像创建服务

如果您的镜像在需要登录的专用注册表中可用,请在登录后将标志与 一起使用。如果 您的镜像存储在 上,这是一个私有注册表,请使用 如下所示的命令:--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 并拉取镜像。

创建具有 5 个副本任务 (--replicas) 的服务

使用标志设置复制的 服务。以下命令创建具有副本任务的服务:--replicasredis5

$ docker service create --name redis --replicas=5 redis:7.4.1

4cdgfyky7ozwh3htjfw0d12qv

上述命令为服务设置所需的任务数。甚至 尽管命令会立即返回,但服务的实际扩展可能需要 一段时间。该列同时显示实际数字和所需数字 服务的副本任务。REPLICAS

在以下示例中,所需状态为 replicas,但当前 任务数为 :5RUNNING3

$ docker service ls

ID            NAME   MODE        REPLICAS  IMAGE
4cdgfyky7ozw  redis  replicated  3/5       redis:7.4.1

创建所有任务后,实际任务数为 等于所需的数字:RUNNING

$ docker service ls

ID            NAME   MODE        REPLICAS  IMAGE
4cdgfyky7ozw  redis  replicated  5/5       redis:7.4.1

创建具有密钥 (--secret) 的服务

使用该标志为容器提供对密钥的访问权限。--secret

创建指定密钥的服务:

$ docker service create --name redis --secret secret.json redis:7.4.1

4cdgfyky7ozwh3htjfw0d12qv

创建指定密钥、目标、用户/组 ID 和模式的服务:

$ docker service create --name redis \
    --secret source=ssh-key,target=ssh \
    --secret source=app-key,target=app,uid=1000,gid=1001,mode=0400 \
    redis:7.4.1

4cdgfyky7ozwh3htjfw0d12qv

要授予服务对多个密钥的访问权限,请使用多个标志。--secret

如果未指定目标,则密钥位于容器中。 如果未指定目标,则 secret 的名称将用作内存中文件 在容器中。如果指定了 target,则将其用作文件名。在 在上面的示例中,创建了两个文件:和 对于每个指定的密钥目标。/run/secrets/run/secrets/ssh/run/secrets/app

使用配置创建服务 (--config)

使用标志为容器提供对配置的访问权限。--config

使用配置创建服务。配置将被挂载到 、 由在容器内运行命令的用户拥有(通常), 并具有 file mode 或 world-readable。您可以将 和 指定为数字 ID 或名称。使用名称时,提供的组/用户名必须 预先存在于容器中。被指定为 4 位数字序列,例如 如。redis-configroot0444uidgidmode0755

$ docker service create --name=redis --config redis-conf redis:7.4.1

使用配置创建服务并指定目标位置和文件模式:

$ docker service create --name redis \
  --config source=redis-conf,target=/etc/redis/redis.conf,mode=0400 redis:7.4.1

要向服务授予对多个配置的访问权限,请使用多个标志。--config

如果未指定 target,则配置位于 容器中。如果没有 target 时,配置的名称将用作 容器。如果指定了 target,则将其用作文件名。/

使用滚动更新策略创建服务

$ docker service create \
  --replicas 10 \
  --name redis \
  --update-delay 10s \
  --update-parallelism 2 \
  redis:7.4.1

当您运行服务更新时,调度程序会更新 一次最多 2 个任务,两次更新之间。有关更多信息, 请参阅滚动更新 教程10s

设置环境变量(-e、--env)

这将为服务中的所有任务设置环境变量。例如:

$ docker service create \
  --name redis_2 \
  --replicas 5 \
  --env MYVAR=foo \
  redis:7.4.1

要指定多个环境变量,请指定多个标志,每个 替换为单独的键值对。--env

$ docker service create \
  --name redis_2 \
  --replicas 5 \
  --env MYVAR=foo \
  --env MYVAR2=bar \
  redis:7.4.1

创建具有特定主机名 (--hostname) 的服务

此选项将 docker 服务容器主机名设置为特定字符串。 例如:

$ docker service create --name redis --hostname myredis redis:7.4.1

在服务上设置元数据 (-l, --label)

标签是将元数据应用于服务的一对。要标记 具有两个标签的服务:key=value

$ docker service create \
  --name redis_2 \
  --label com.example.foo="bar" \
  --label bar=baz \
  redis:7.4.1

有关标签的更多信息,请参阅应用自定义 元数据

添加绑定挂载、卷或内存文件系统 (--mount)

Docker 支持三种不同类型的挂载,允许容器读取 从主机操作系统上的文件或目录或写入文件或目录,或者 在内存文件系统上。这些类型是数据卷(通常简称为 作为卷)、绑定挂载、tmpf 和命名管道。

绑定挂载使主机上的文件或目录可供 容器。绑定挂载可以是只读的,也可以是 read-write 的例如,容器可以通过以下方式共享其主机的 DNS 信息 主机或容器的绑定挂载可能 将日志写入其主机目录。如果您使用 bind mounts 和你的主机和容器具有不同的权限概念, 访问控制或其他此类详细信息,您将遇到可移植性问题。/etc/resolv.conf/var/log/myContainerLogs

命名卷是一种解耦持久数据的机制,您的 容器。 命名卷由 Docker 创建和管理,命名卷仍然存在 即使当前没有容器在使用它。命名卷中的数据可以是 在容器和主机之间以及多个 器皿。Docker 使用卷驱动程序来创建、管理和挂载卷。 您可以使用 Docker 命令备份或还原卷。

tmpfs 将 tmpfs 挂载到容器内,用于易失性数据。

npipe 将主机中的命名管道挂载到容器中。

考虑您的镜像启动轻量级 Web 服务器的情况。你可以 使用该镜像作为基础镜像,复制到您网站的 HTML 文件中,然后打包 那张图片变成了另一张图片。每次您的网站发生变化时,您都需要更新 新镜像并重新部署为您的网站提供服务的所有容器。更好的 解决方案是将网站存储在一个命名卷中,该卷附加到每个卷 您的 Web 服务器容器。要更新网站,您只需 更新命名卷。

有关命名卷的更多信息,请参阅数据卷

下表描述了适用于 bind 挂载和 named 的选项 服务中的卷:

选择必填描述
类型

挂载的类型可以是 volumebindtmpfsnpipe。如果未指定 type,则默认为 volume

  • volume:将托管卷挂载到容器中。
  • 绑定: 将主机中的目录或文件绑定挂载到容器中。
  • tmpfs:在容器中挂载 tmpfs
  • npipe:将命名的 pipe 从主机挂载到容器中(仅限 Windows 容器)。
srcsource对于 type=bindtype=npipe
  • type=volumesrc 是指定卷名称的可选方法(例如,src=my-volume)。 如果命名的卷不存在,则会自动创建该卷。如果未指定 src,则卷为 分配了一个随机名称,该名称保证在主机上是唯一的,但在集群范围内可能不唯一。 随机命名的卷与其容器具有相同的生命周期,并在容器被销毁时(在服务更新时,或者扩展或重新平衡服务时)被销毁
  • type=bindsrc 是必需的,并指定要 bind-mount 的文件或目录的绝对路径 (例如,src=/path/on/host/)。如果文件或目录不存在,则会产生错误。
  • type=tmpfs:不支持 src

DST目标目标

是的

容器内的挂载路径,例如 /some/path/in/container/。 如果该路径在容器的文件系统中不存在,则 Engine 会创建 挂载卷或绑定挂载之前位于指定位置的目录。

readonlyro

Engine mounts binds and volumes read-write unless readonly 选项 在挂载 bind 或 volume 时给出。请注意,将 readonly 设置为 bind-mount 可能不会将其 submounts 设为 readonly,具体取决于内核版本。另请参阅 bind-recursive

  • true1 或 no 值:以只读方式挂载绑定或卷。
  • false0:以读写方式挂载 bind 或 volume。

绑定挂载的选项

以下选项只能用于 bind mounts ():type=bind

选择描述
bind-propagation (绑定传播)

请参阅 bind propagation 部分

一致性

挂载的一致性要求;其中之一

  • default:等效于 consistent
  • consistent:完全一致性。容器运行时和主机始终保持相同的挂载视图。
  • cached:主机的挂载视图是权威的。在主机上进行的更新在容器中可见之前,可能会有延迟。
  • delegated:容器运行时的挂载视图是权威的。在主机上看到容器中所做的更新之前,可能会有延迟。
bind-recursive 绑定递归默认情况下,submounts 也是递归绑定挂载的。但是,当 bind mount 配置了 readonly 选项,因为子挂载可能不会以只读方式挂载, 取决于内核版本。 设置 bind-recursive 以控制递归 bind-mount 的行为。

值是以下值之一:


  • <enabled:启用递归绑定挂载。 如果内核为 v5.12 或更高版本,则只读挂载将递归为只读。 否则,它们不会以递归只读方式进行。
  • <disabled:禁用递归绑定挂载。
  • <writable:启用递归绑定挂载。 只读挂载不会以递归只读方式进行。
  • <readonly:启用递归绑定挂载。 如果内核为 v5.12 或更高版本,则只读挂载将递归为只读。 否则,Engine 将引发错误。
如果未指定该选项,则默认行为与启用的设置相对应。
bind-nonrecursive (绑定非递归)bind-nonrecursive 自 Docker Engine v25.0 起已弃用。 请改用 bind-recursive

值是可选的:


  • true1:相当于 bind-recursive=disabled
  • false0:相当于 bind-recursive=enabled
绑定传播

绑定传播是指是否在给定的 绑定装载或命名卷可以传播到该装载的复制副本。考虑 挂载点 ,它也挂载在 上。传播设置 控制 上的挂载是否也可以在 上使用 。每 propagation 设置具有递归对位点。在递归的情况下, 请考虑 也挂载为 。传播设置 控制 AND/OR 是否存在。/mnt/tmp/tmp/a/mnt/a/tmp/a/foo/mnt/a/tmp/a

该选项默认为 bind mounts 和 卷挂载,并且只能配置为绑定挂载。换句话说,命名的 卷不支持绑定传播。bind-propagationrprivate

  • shared:原始挂载的子挂载暴露给副本挂载, 副本挂载的子挂载也会传播到 原始坐骑。
  • slave:类似于共享挂载,但仅在一个方向上。如果 原始挂载暴露了一个子挂载,副本挂载可以看到它。 但是,如果副本挂载公开了子挂载,则原始的 mount 看不到它。
  • private:挂载为 private。其中的子安装座不会暴露在 复制副本挂载和复制副本挂载的子挂载不是 暴露在原始支架上。
  • rshared:与 shared 相同,但传播也扩展到 和 from 嵌套在任何原始或复制副本挂载中的挂载点 点。
  • rslave:与 相同,但传播也扩展到 和 from 嵌套在任何原始或复制副本挂载中的挂载点 点。slave
  • rprivate:默认值。与 相同,意味着没有挂载点 原始挂载点或复制副本挂载点中的任何位置传播 在任一方向。private

有关绑定传播的更多信息,请参阅共享子树的 Linux 内核文档

命名卷的选项

以下选项只能用于命名卷 ():type=volume

选择描述
卷驱动程序

用于卷的 volume-driver 插件的名称。默认为 “local”,如果 卷 不存在。

卷标要应用于卷的一个或多个自定义元数据(“标签”) 创造。例如,volume-label=mylabel=hello-world,my-other-label=hello-mars。了解更多 有关标签的信息,请参阅 应用自定义元数据.
卷 nocopy默认情况下,如果您将空卷附加到容器,并且 files 或 目录已存在于容器中的挂载路径 (DST) 中, Engine 会将这些文件和目录复制到卷中,从而允许 主机来访问它们。设置 volume-nocopy 以禁用复制文件 从容器的文件系统到卷并挂载空卷。

值是可选的:


  • true1:如果未提供值,则为 Default。禁用复制。
  • false0:启用复制。
volume-opt特定于给定卷驱动程序的选项,这些选项将传递给 驱动程序。选项以逗号分隔的形式提供 键/值对列表,例如 volume-opt=some-option=some-value,volume-opt=some-other-option=some-other-value。 有关给定驱动程序的可用选项,请参阅该驱动程序的 文档。

tmpfs 的选项

以下选项只能用于 tmpfs 挂载 (type=tmpfs);

选择描述
tmpfs 大小tmpfs 挂载的大小(以字节为单位)。在 Linux 中默认无限制。
tmpfs 模式tmpfs 的文件模式(以八进制为单位)。(例如,“700”“0700”。在 Linux 中默认为 “1777”。

“--mount” 和 “--volume” 之间的区别

该标志支持 or 标志支持的大多数选项,但有一些重要的例外:--mount-v--volumedocker run

  • 该标志允许您指定卷驱动程序和卷驱动程序 选项而无需提前创建卷。相反,允许您指定共享的单个卷驱动程序 由 all volumes,使用 flag.--mountdocker run--volume-driver

  • 该标志允许您为卷指定自定义元数据(“标签”), 在创建卷之前。--mount

  • 使用 with 时, host-path 必须引用主机上的现有路径。系统不会为您创建路径,并且服务将失败 如果路径不存在,则显示错误。--mounttype=bind

  • 该标志不允许使用 or 标志重新标记卷。 用于标记。--mountZzselinux

使用命名卷创建服务

以下示例创建一个使用命名卷的服务:

$ docker service create \
  --name my-service \
  --replicas 3 \
  --mount type=volume,source=my-volume,destination=/path/in/container,volume-label="color=red",volume-label="shape=round" \
  nginx:alpine

对于服务的每个副本,引擎请求一个名为 “my-volume” 的卷 从部署任务的默认 (“local”) 卷驱动程序。如果 volume 不存在,则引擎会创建一个新卷并应用 “color” 和 “shape” 标签。

当任务启动时,卷被挂载到内部 容器。/path/in/container/

请注意,默认 (“local”) 卷是本地范围的卷驱动程序。 这意味着,根据任务的部署位置,该任务将获得一个名为 “my-volume” 的新卷,或者与其他任务共享相同的 “my-volume” 同一服务。写入单个共享卷的多个容器可以 如果容器内运行的软件不是 旨在处理写入同一位置的并发进程。还要 考虑到容器可以由 Swarm 编排器重新调度,并且 部署在不同的节点上。

创建使用匿名卷的服务

以下命令将创建一个具有三个副本的服务,其中 音量开启 :/path/in/container

$ docker service create \
  --name my-service \
  --replicas 3 \
  --mount type=volume,destination=/path/in/container \
  nginx:alpine

在此示例中,没有为卷指定名称 (),因此新卷 是为每个任务创建的。这保证了每个任务都有自己的卷 并且卷不在任务之间共享。匿名卷在 使用它们的任务已完成。source

创建使用绑定挂载主机目录的服务

以下示例将 中的 主机目录绑定挂载到 支持该服务的容器:/path/in/container

$ docker service create \
  --name my-service \
  --mount type=bind,source=/path/on/host,destination=/path/in/container \
  nginx:alpine

设置服务模式 (--mode)

服务模式确定这是复制服务还是全局服务。复制的服务运行指定数量的任务,而全局 service 在 Swarm 中的每个活动节点上运行。

以下命令将创建一个 global service:

$ docker service create \
 --name redis_2 \
 --mode global \
 redis:7.4.1

指定服务约束 (--constraint)

您可以通过定义 constraint 表达式。约束表达式可以使用 match () 或 exclude () 规则。多个约束查找满足每个 expression (AND 匹配)。约束可以将节点或 Docker Engine 标签匹配为 遵循:==!=

node 属性比赛
node.id节点 IDnode.id==2ivku8v2gvtg4
node.hostname节点主机名node.hostname!=node-2
node.role节点角色 (manager/worker)node.role==manager
node.platform.osNode 操作系统node.platform.os==windows
node.platform.arch节点架构node.platform.arch==x86_64
node.labels用户定义的节点标签node.labels.security==high
engine.labelsDocker Engine 的标签engine.labels.operatingsystem==ubuntu-24.04

engine.labels应用于 Docker Engine 标签,如操作系统、驱动程序、 等。Swarm 管理员使用 docker node update 命令。node.labels

例如,以下将 redis 服务的任务限制为 节点类型标签等于队列:

$ docker service create \
  --name redis_2 \
  --constraint node.platform.os==linux \
  --constraint node.labels.type==queue \
  redis:7.4.1

如果服务约束排除了集群中的所有节点,则会打印一条消息 未找到合适的节点,但调度程序将启动对帐 循环并在合适的节点可用时部署服务。

在下面的示例中,未找到满足约束条件的节点,导致 service 不与所需状态进行协调:

$ docker service create \
  --name web \
  --constraint node.labels.region==east \
  nginx:alpine

lx1wrhhpmbbu0wuk0ybws30bc
overall progress: 0 out of 1 tasks
1/1: no suitable node (scheduling constraints not satisfied on 5 nodes)

$ docker service ls
ID                  NAME     MODE         REPLICAS   IMAGE               PORTS
b6lww17hrr4e        web      replicated   0/1        nginx:alpine

将标签添加到集群中的节点后,服务 reconciles,并部署所需数量的副本:region=east

$ docker node update --label-add region=east yswe2dm4c5fdgtsrli1e8ya5l
yswe2dm4c5fdgtsrli1e8ya5l

$ docker service ls
ID                  NAME     MODE         REPLICAS   IMAGE               PORTS
b6lww17hrr4e        web      replicated   1/1        nginx:alpine

指定服务放置首选项 (--placement-pref)

您可以将服务设置为将任务平均划分为不同类别的 节点。这有用的一个例子是在一组任务中平衡任务 数据中心或可用区。下面的示例说明了这一点:

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

这与策略(目前唯一的 supported 策略)将任务均匀分布在 Node 标签的值上。在此示例中,我们假设每个节点都有一个节点 标签。如果此标签有三个不同的值,则 节点,则 1/3 的任务将放置在节点上 与每个值相关联。即使有更多的节点具有 1 个 value 而不是另一个。例如,请考虑以下一组节点:--placement-prefspreaddatacenterdatacenter

  • 三个节点node.labels.datacenter=east
  • 两个节点node.labels.datacenter=south
  • 一个具有node.labels.datacenter=west

由于我们分布在标签和 service 有 9 个副本,则每个数据中心将有 3 个副本。有 三个节点与 value 相关联,因此每个节点都将获得一个 为此值保留 3 个副本。有两个值为 的节点,该值的三个副本将在它们之间分配, 一个接收两个副本,另一个只接收一个副本。最后,有一个节点,该节点将获取为 保留的所有三个副本。datacentereastsouthwestwest

如果一个类别中的节点(例如,具有 的节点)由于以下原因无法处理其应有的任务份额 constraints 或 resource limitations 时,额外的任务将被分配给其他 节点。node.labels.datacenter=south

放置首选项支持引擎标签和节点标签。这 上面的示例使用节点标签,因为标签是使用 .要分布在引擎标签的值上,请使用 .node.labels.datacenter--placement-pref spread=engine.labels.<labelname>

可以向服务添加多个放置首选项。这 建立首选项层次结构,以便首先对任务进行划分 一个类别,然后进一步划分为其他类别。一个例子 这可能有用的地方是在数据中心之间公平地分配任务,以及 然后将每个数据中心内的任务拆分到选定的机架上。添加 多个放置首选项,指定多个标记 次。顺序很重要,将应用放置首选项 按照做出计划决策时给出的顺序。--placement-pref

以下示例设置具有多个放置首选项的服务。 任务首先分布在各个数据中心,然后分布在机架上 (如相应的标签所示):

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

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

指定服务的内存要求和约束(--reserve-memory 和 --limit-memory)

如果您的服务需要最少的内存量才能正常运行, 您可以使用 来指定服务应仅为 计划在具有足够多的可用内存的节点上。如果没有节点是 available 表示,则不会计划任务,而是保留在 pending 状态。--reserve-memory

以下示例要求 4GB 内存可用且可预留 在计划服务在该节点上运行之前。

$ docker service create --reserve-memory=4GB --name=too-big nginx:alpine

管理器不会在单个节点上调度一组容器,该节点的 预留超过该节点上的可用内存。

在计划并运行任务后,不会强制执行 内存限制。用于确保任务使用的 节点上的给定内存量。此示例限制使用的内存量 通过任务设置为 4GB。即使您的每个节点都具有 只有 2GB 的内存,因为这是一个上限。--reserve-memory--limit-memory--limit-memory

$ docker service create --limit-memory=4GB --name=too-big nginx:alpine

使用 且不保证 Docker 不会占用主机上的内存超过您的预期。例如,您可以 创建许多服务,这些服务的内存使用量之和可能会耗尽可用的 记忆。--reserve-memory--limit-memory

您可以通过采用 还要考虑主机上运行的其他(非容器化)软件。如果 大于或等于 ,则 Docker 不会 在没有足够内存的主机上调度服务。 将限制服务的内存保持在该限制范围内,因此如果每个服务 设置了 memory-reservation 和 limit 时,Docker 服务不太可能 使主机饱和。其他非服务容器或直接运行的应用程序 仍可能会耗尽内存。--reserve-memory--limit-memory--limit-memory

这种方法有一个缺点。预留内存还意味着您可以 未充分利用节点上的可用内存。考虑一项服务 在正常情况下使用 100MB 的内存,但根据负载可以 “峰值”为 500MB。为该服务保留 500MB(以保证可以有 500MB 对于这些 “峰值”) 会导致 400MB 的内存在大部分时间被浪费。

简而言之,您可以采取更保守或更灵活的方法:

  • 保守:保留 500MB,限制为 500MB。基本上你现在是 将服务容器视为 VM,您可能会失去一个很大的优势 容器,即每个主机的服务密度更高。

  • 灵活:限制为 500MB,前提是如果服务需要 超过 500MB,则出现故障。保留 100MB 之间的空间 “正常”要求和 500MB “峰值”要求”。这假设当 此服务处于 “高峰” 状态,其他服务或非容器工作负载可能 不会的。

您采用的方法在很大程度上取决于 工作量。在稳定之前,您应该在正常和峰值条件下进行测试 在方法上。

在 Linux 上,您还可以限制服务在给定 host 操作系统级别、using 或其他 相关的操作系统工具。cgroups

指定每个节点的最大副本数 (--replicas-max-per-node)

使用该标志可设置可在节点上运行的最大副本任务数。 以下命令创建一个 nginx 服务,其中包含 2 个副本任务,但每个节点只有一个副本任务。--replicas-max-per-node

一个有用的示例是平衡一组数据中心上的任务,并让 set 确保在 维护或数据中心故障。--placement-pref--replicas-max-per-node

下面的示例说明了这一点:

$ docker service create \
  --name nginx \
  --replicas 2 \
  --replicas-max-per-node 1 \
  --placement-pref 'spread=node.labels.datacenter' \
  nginx

将服务附加到现有网络 (--network)

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

首先,在 docker network 创建的管理器节点上创建一个覆盖网络 命令:

$ docker network create --driver overlay my-network

etjpu59cykrptrgw0z0hk5snf

在 swarm 模式下创建叠加网络后,所有管理器节点都具有 访问网络。

当您创建服务并传递标志以将服务附加到 覆盖网络:--network

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

716thylsndqma81j6kkkb5aus

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

同一网络上的容器可以使用服务发现相互访问。

长格式语法 of 允许指定别名和驱动程序选项列表:--network--network name=my-network,alias=web1,driver-opt=field1=value1

将服务端口从外部发布到 swarm (-p, --publish)

您可以发布服务端口,使其在外部可供 swarm 使用 使用标志。标志可以采用两种不同的样式 的参数。简短版本是位置化的,允许您指定 已发布端口和目标端口,用冒号 () 分隔。--publish--publish:

$ docker service create --name my_web --replicas 3 --publish 8080:80 nginx

还有一个长格式,它更易于阅读并允许您指定 更多选项。长格式是首选。您不能指定服务的 mode (使用短格式时)。下面是使用长格式的示例 对于与上述相同的服务:

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

您可以指定的选项包括:

选择短语法长语法描述
已发布端口和目标端口--发布 8080:80--发布 published=8080,target=80

容器中的目标端口以及要将其映射到的端口 节点,使用路由网格 (入口) 或主机级网络。 此表后面提供了更多选项。键值语法为 首选,因为它在某种程度上是自记录的。

模式无法使用短语法进行设置。--publish published=8080,target=80,mode=host

用于绑定端口 (ingresshost) 的模式。 默认为 ingress 以使用路由网格。

协议--发布 8080:80/TCP--publish published=8080,target=80,protocol=tcp

要使用的协议 tcpudpsctp 。默认为 tcp。要为这两个协议绑定一个端口,请指定 -p--publish 标志两次。

当您使用 mode 发布服务端口时,swarm 路由网格 使服务在每个节点上的已发布端口上可访问,而不管 节点上运行的服务有一个任务。如果使用 mode, 该端口仅绑定在运行服务的节点上,并且给定端口 on 一个节点只能绑定一次。您只能使用 长语法。有关更多信息,请参阅使用 swarm 模式路由网格ingresshost

为托管服务账户提供凭证规格 (--credentials-spec)

此选项仅用于使用 Windows 容器的服务。必须采用 或 .--credential-specfile://<filename>registry://<value-name>

使用格式时,引用的文件必须为 存在于 Docker 数据目录的子目录中, 默认为 Windows 上。例如 指定负载 。file://<filename>CredentialSpecsC:\ProgramData\Docker\file://spec.jsonC:\ProgramData\Docker\CredentialSpecs\spec.json

使用该格式时,凭证规范为 从守护程序主机上的 Windows 注册表中读取。指定的 注册表值必须位于:registry://<value-name>

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs

使用模板创建服务

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

支持的标志如下:

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

下面列出了 Go 模板的有效占位符:

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

模板示例

在此示例中,我们将根据 service 的名称、节点的 ID 和它所在的主机名。

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

va8ew30grofhjoychbr6iot8c

$ 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}}" 2e7a8a9c4da2-wo41w8hg8qanxwjwsg4kxpprj-hosttempl

x3ti0erg11rjpg64m75kej2mz-hosttempl

在 Windows 上指定隔离模式 (--isolation)

默认情况下,在 Windows 节点上调度的任务使用默认隔离模式运行 为此特定节点配置。要强制使用特定的隔离模式,您可以使用 标志:--isolation

$ docker service create --name myservice --isolation=process microsoft/nanoserver

Windows 上支持的隔离模式包括:

  • default:使用在运行任务的节点上指定的默认设置
  • process:使用进程隔离(仅限 Windows Server)
  • hyperv:使用 Hyper-V 隔离

创建请求通用资源的服务 (--generic-resources)

您可以通过使用标志来缩小任务可以登陆的节点类型(如果节点公布这些资源):--generic-resource

$ docker service create \
    --name cuda \
    --generic-resource "NVIDIA-GPU=2" \
    --generic-resource "SSD=1" \
    nvidia/cuda

作为作业运行

作业是一种特殊类型的服务,旨在运行操作直至完成 然后停止,而不是运行长时间运行的守护程序。当任务 属于 Job Exits Succeed(返回值为 0),则 Task 被标记为 “已完成”,并且不会再次运行。

使用以下两种模式之一启动作业,或者replicated-jobglobal-job

$ docker service create --name myjob \
                        --mode replicated-job \
                        bash "true"

此命令将运行一个 Task,该 Task 将使用该镜像执行 command ,它将返回 0,然后退出。bashtrue

尽管 Jobs 最终是一种不同类型的服务,但它们是 与其他服务相比的注意事项:

  • 任何 update 或 rollback 配置选项均无效。Job 可以是 已更新,但无法转出或回滚,因此 期权没有意义。
  • 工作在到达该州时永远不会重新启动。这意味着 对于 Jobs,设置为 与将其设置为 相同。Complete--restart-conditionanyon-failure

作业在复制模式和全局模式下均可用。

复制的作业

复制的 Job 类似于复制的服务。设置标志 将指定要执行的作业的迭代总数。--replicas

默认情况下,复制的作业的所有副本将同时启动。要控制 在任何时间同时执行的副本总数, 该标志可用于:--max-concurrent

$ docker service create \
    --name mythrottledjob \
    --mode replicated-job \
    --replicas 10 \
    --max-concurrent 2 \
    bash "true"

上述命令总共将执行 10 个任务,但其中只有 2 个 在任何给定时间运行。

全球工作机会

全局作业与全局服务类似,每个节点上都会执行一次 Task 匹配放置约束。全局作业由 mode 表示。global-job

请注意,创建 Global job 后,添加到集群中的任何新节点 将在其上启动该作业的 Task。全局作业不会作为 whole 都处于 “done” 状态,除非每个 Node 都满足作业的 constraints 具有 Completed 任务。