docker 服务创建
描述 | 创建新服务 |
---|---|
用法 | docker service create [OPTIONS] IMAGE [COMMAND] [ARG...] |
群此命令适用于 Swarm 编排器。
描述
按照指定参数创建服务。
注意
这是一个集群管理命令,必须在 swarm 上执行 Manager 节点。要了解 Manager 和 worker,请参阅 文档。
选项
选择 | 违约 | 描述 |
---|---|---|
--cap-add | API 1.41+添加 Linux 功能 | |
--cap-drop | API 1.41+丢弃 Linux 功能 | |
--config | API 1.30+指定要向服务公开的配置 | |
--constraint | 放置约束 | |
--container-label | 容器标签 | |
--credential-spec | API 1.29+托管服务帐户的凭证规范(仅限 Windows) | |
-d, --detach | API 1.29+立即退出,而不是等待服务收敛 | |
--dns | API 1.25+设置自定义 DNS 服务器 | |
--dns-option | API 1.25+设置 DNS 选项 | |
--dns-search | API 1.25+设置自定义 DNS 搜索域 | |
--endpoint-mode | vip | 端点模式(vip 或 dnsrr) |
--entrypoint | 覆盖镜像的默认 ENTRYPOINT | |
-e, --env | 设置环境变量 | |
--env-file | 读入环境变量文件 | |
--generic-resource | 用户定义的资源 | |
--group | API 1.25+为容器设置一个或多个补充用户组 | |
--health-cmd | API 1.25+运行以检查运行状况的命令 | |
--health-interval | API 1.25+运行检查之间的时间 (ms|s|m|h) | |
--health-retries | API 1.25+报告运行状况不佳所需的连续失败 | |
--health-start-interval | 接口 1.44+在开始期间运行检查之间的时间 (ms|s|m|h) | |
--health-start-period | API 1.29+容器在将重试次数计算为不稳定之前初始化的开始时间 (ms|s|m|h) | |
--health-timeout | API 1.25+允许运行一项检查的最长时间 (ms|s|m|h) | |
--host | API 1.25+设置一个或多个自定义主机到 IP 映射 (host:ip) | |
--hostname | API 1.25+容器主机名 | |
--init | API 1.37+在每个服务容器中使用 init 来转发信号和接收流程 | |
--isolation | API 1.35+服务容器隔离模式 | |
-l, --label | 服务标签 | |
--limit-cpu | 限制 CPU | |
--limit-memory | 限制内存 | |
--limit-pids | API 1.41+限制最大进程数(默认值 0 = 无限制) | |
--log-driver | 记录服务的驱动程序 | |
--log-opt | 记录驱动程序选项 | |
--max-concurrent | API 1.41+要并发运行的作业任务数(默认值等于 --replicas) | |
--mode | replicated | 服务模式(、、、replicated global replicated-job global-job ) |
--mount | 将文件系统挂载附加到服务 | |
--name | 服务名称 | |
--network | 网络附件 | |
--no-healthcheck | API 1.25+禁用任何容器指定的 HEALTHCHECK | |
--no-resolve-image | API 1.30+不查询注册表来解析镜像摘要和支持的平台 | |
--oom-score-adj | API 1.46+调整主机的 OOM 首选项(-1000 到 1000) | |
--placement-pref | API 1.28+添加版面偏好设置 | |
-p, --publish | 将端口发布为节点端口 | |
-q, --quiet | Suppress progress 输出 | |
--read-only | API 1.28+以只读方式挂载容器的根文件系统 | |
--replicas | 任务数 | |
--replicas-max-per-node | API 1.40+每个节点的最大任务数(默认值 0 = 无限制) | |
--reserve-cpu | 预留 CPU | |
--reserve-memory | 储备内存 | |
--restart-condition | 满足条件时重新启动 (, , ) (默认none on-failure any any ) | |
--restart-delay | 重启尝试之间的延迟 (ns|us|ms|s|m|h)(默认 5 秒) | |
--restart-max-attempts | 放弃前的最大重启次数 | |
--restart-window | 用于评估重启策略的窗口 (ns|us|ms|s|m|h) | |
--rollback-delay | API 1.28+任务回滚之间的延迟 (ns|us|ms|s|m|h)(默认为 0s) | |
--rollback-failure-action | API 1.28+回滚失败时的操作 (, ) (默认pause continue pause ) | |
--rollback-max-failure-ratio | API 1.28+回滚期间允许的失败率(默认值为 0) | |
--rollback-monitor | API 1.28+每个任务回滚后监控失败的持续时间 (ns|us|ms|s|m|h)(默认 5 秒) | |
--rollback-order | API 1.29+回滚顺序 (, ) (默认start-first stop-first stop-first ) | |
--rollback-parallelism | 1 | API 1.28+同时回滚的最大任务数(0 表示一次回滚所有任务) |
--secret | API 1.25+指定要向服务公开的密钥 | |
--stop-grace-period | 强制终止容器前的等待时间 (ns|us|ms|s|m|h) (默认为 10 秒) | |
--stop-signal | API 1.28+停止容器的信号 | |
--sysctl | API 1.40+Sysctl 选项 | |
-t, --tty | API 1.25+分配伪 TTY | |
--ulimit | API 1.41+Ulimit 选项 | |
--update-delay | 更新之间的延迟 (ns|us|ms|s|m|h)(默认为 0s) | |
--update-failure-action | 更新失败时的操作 (, , ) (默认pause continue rollback pause ) | |
--update-max-failure-ratio | API 1.25+更新期间允许的失败率(默认值为 0) | |
--update-monitor | API 1.25+每次任务更新后监控失败的持续时间 (ns|us|ms|s|m|h)(默认为 5 秒) | |
--update-order | API 1.29+更新顺序 (, ) (默认start-first stop-first stop-first ) | |
--update-parallelism | 1 | 同时更新的最大任务数(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-auth
docker service create
registry.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) 的服务
使用标志设置复制的
服务。以下命令创建具有副本任务的服务:--replicas
redis
5
$ docker service create --name redis --replicas=5 redis:7.4.1
4cdgfyky7ozwh3htjfw0d12qv
上述命令为服务设置所需的任务数。甚至
尽管命令会立即返回,但服务的实际扩展可能需要
一段时间。该列同时显示实际数字和所需数字
服务的副本任务。REPLICAS
在以下示例中,所需状态为 replicas,但当前
任务数为 :5
RUNNING
3
$ 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-config
root
0444
uid
gid
mode
0755
$ 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 的选项 服务中的卷:
选择 | 必填 | 描述 |
---|---|---|
类型 | 挂载的类型可以是 volume、bind、tmpfs 或 npipe。如果未指定 type,则默认为 volume。
| |
src 或 source | 对于 type=bind 和 type=npipe |
|
DST 或目标或目标 | 是的 | 容器内的挂载路径,例如 /some/path/in/container/。 如果该路径在容器的文件系统中不存在,则 Engine 会创建 挂载卷或绑定挂载之前位于指定位置的目录。 |
readonly 或 ro | Engine mounts binds and volumes read-write unless readonly 选项 在挂载 bind 或 volume 时给出。请注意,将 readonly 设置为 bind-mount 可能不会将其 submounts 设为 readonly,具体取决于内核版本。另请参阅 bind-recursive。
|
绑定挂载的选项
以下选项只能用于 bind mounts ():type=bind
选择 | 描述 |
---|---|
bind-propagation (绑定传播) | 请参阅 bind propagation 部分。 |
一致性 | 挂载的一致性要求;其中之一
|
bind-recursive 绑定递归 | 默认情况下,submounts 也是递归绑定挂载的。但是,当
bind mount 配置了 readonly 选项,因为子挂载可能不会以只读方式挂载,
取决于内核版本。
设置 bind-recursive 以控制递归 bind-mount 的行为。 值是以下值之一:
|
bind-nonrecursive (绑定非递归) | bind-nonrecursive 自 Docker Engine v25.0 起已弃用。
请改用 bind-recursive。 值是可选的:
|
绑定传播
绑定传播是指是否在给定的
绑定装载或命名卷可以传播到该装载的复制副本。考虑
挂载点 ,它也挂载在 上。传播设置
控制 上的挂载是否也可以在 上使用 。每
propagation 设置具有递归对位点。在递归的情况下,
请考虑 也挂载为 。传播设置
控制 AND/OR 是否存在。/mnt
/tmp
/tmp/a
/mnt/a
/tmp/a
/foo
/mnt/a
/tmp/a
该选项默认为 bind mounts 和
卷挂载,并且只能配置为绑定挂载。换句话说,命名的
卷不支持绑定传播。bind-propagation
rprivate
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 以禁用复制文件
从容器的文件系统到卷并挂载空卷。 值是可选的:
|
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
--volume
docker run
该标志允许您指定卷驱动程序和卷驱动程序 选项,而无需提前创建卷。相反,允许您指定共享的单个卷驱动程序 由 all volumes,使用 flag.
--mount
docker run
--volume-driver
该标志允许您为卷指定自定义元数据(“标签”), 在创建卷之前。
--mount
使用 with 时, host-path 必须引用主机上的现有路径。系统不会为您创建路径,并且服务将失败 如果路径不存在,则显示错误。
--mount
type=bind
该标志不允许使用 or 标志重新标记卷。 用于标记。
--mount
Z
z
selinux
使用命名卷创建服务
以下示例创建一个使用命名卷的服务:
$ 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 | 节点 ID | node.id==2ivku8v2gvtg4 |
node.hostname | 节点主机名 | node.hostname!=node-2 |
node.role | 节点角色 (manager /worker ) | node.role==manager |
node.platform.os | Node 操作系统 | node.platform.os==windows |
node.platform.arch | 节点架构 | node.platform.arch==x86_64 |
node.labels | 用户定义的节点标签 | node.labels.security==high |
engine.labels | Docker 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-pref
spread
datacenter
datacenter
- 三个节点
node.labels.datacenter=east
- 两个节点
node.labels.datacenter=south
- 一个具有
node.labels.datacenter=west
由于我们分布在标签和
service 有 9 个副本,则每个数据中心将有 3 个副本。有
三个节点与 value 相关联,因此每个节点都将获得一个
为此值保留 3 个副本。有两个值为 的节点,该值的三个副本将在它们之间分配,
一个接收两个副本,另一个只接收一个副本。最后,有一个节点,该节点将获取为 保留的所有三个副本。datacenter
east
south
west
west
如果一个类别中的节点(例如,具有 的节点)由于以下原因无法处理其应有的任务份额
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 | 用于绑定端口 (ingress 或 host) 的模式。 默认为 ingress 以使用路由网格。 |
协议 | --发布 8080:80/TCP | --publish published=8080,target=80,protocol=tcp | 要使用的协议 tcp 、 udp 或 sctp 。默认为 tcp。要为这两个协议绑定一个端口,请指定 -p 或 --publish 标志两次。 |
当您使用 mode 发布服务端口时,swarm 路由网格
使服务在每个节点上的已发布端口上可访问,而不管
节点上运行的服务有一个任务。如果使用 mode,
该端口仅绑定在运行服务的节点上,并且给定端口
on 一个节点只能绑定一次。您只能使用
长语法。有关更多信息,请参阅使用 swarm 模式路由网格。ingress
host
为托管服务账户提供凭证规格 (--credentials-spec)
此选项仅用于使用 Windows 容器的服务。必须采用 或 .--credential-spec
file://<filename>
registry://<value-name>
使用格式时,引用的文件必须为
存在于 Docker 数据目录的子目录中,
默认为 Windows 上。例如
指定负载 。file://<filename>
CredentialSpecs
C:\ProgramData\Docker\
file://spec.json
C:\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-job
global-job
$ docker service create --name myjob \
--mode replicated-job \
bash "true"
此命令将运行一个 Task,该 Task 将使用该镜像执行
command ,它将返回 0,然后退出。bash
true
尽管 Jobs 最终是一种不同类型的服务,但它们是 与其他服务相比的注意事项:
- 任何 update 或 rollback 配置选项均无效。Job 可以是 已更新,但无法转出或回滚,因此 期权没有意义。
- 工作在到达该州时永远不会重新启动。这意味着
对于 Jobs,设置为 与将其设置为 相同。
Complete
--restart-condition
any
on-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 任务。