1、docker service create 简介
docker service create
命令是 Docker Swarm 模式下用于创建服务的命令。服务是在 Swarm 集群中运行的可伸缩的容器应用程序。创建一个根据指定参数描述的服务。
参考文档:https://docs.docker.com/engine/reference/commandline/service_create/
注意:
此命令是一个集群管理命令,必须在 Swarm 管理节点上执行。要了解有关管理节点和工作节点的信息,请参阅文档中的 Swarm 模式部分。
2、docker service create 语法
docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]
3、docker service create 命令
1)创建一个服务
docker service create --name redis redis:3.0.6 dmu1ept4cxcfe8k8lhtux3ro3 docker service create --mode global --name redis2 redis:3.0.6 a8q9dasaafudfs8q8w32udass docker service ls ID NAME MODE REPLICAS IMAGE dmu1ept4cxcf redis replicated 1/1 redis:3.0.6 a8q9dasaafud redis2 global 1/1 redis:3.0.6
2)使用私有仓库中的镜像创建一个服务(--with-registry-auth)
如果镜像存储在需要登录的私有仓库中,请在使用 docker service create
命令时添加 --with-registry-auth
标志,并在登录后使用。如果镜像存储在私有仓库 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 日志。有了这些信息,节点就能够登录仓库并拉取镜像。
3)创建包含 5 个副本任务的服务(--replicas)
使用 --replicas 标志设置复制服务的副本任务数。以下命令创建了一个包含 5 个副本任务的 Redis 服务:
docker service create --name redis --replicas=5 redis:3.0.6 4cdgfyky7ozwh3htjfw0d12qv
上述命令设置了服务的期望任务数。尽管命令立即返回,但实际扩展服务的过程可能需要一些时间。REPLICAS 列显示服务的实际任务数和期望任务数。
在以下示例中,期望状态为 5 个副本,但当前正在运行的任务数为 3:
docker service ls ID NAME MODE REPLICAS IMAGE 4cdgfyky7ozw redis replicated 3/5 redis:3.0.7
当所有任务都创建并运行时,实际任务数将等于期望任务数:
docker service ls ID NAME MODE REPLICAS IMAGE 4cdgfyky7ozw redis replicated 5/5 redis:3.0.7
4)使用 secrets 创建服务(--secret)
使用 --secret
标志为容器提供访问权限。
指定一个 secret 创建服务:
docker service create --name redis --secret secret.json redis:3.0.6 4cdgfyky7ozwh3htjfw0d12qv
指定 secret、目标、用户/组 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:3.0.6 4cdgfyky7ozwh3htjfw0d12qv
要为服务授予多个 secrets 的访问权限,请使用多个 --secret
标志。
如果未指定目标,则 secrets 将位于容器内的 /run/secrets
目录中。如果未指定目标,则 secret 的名称将用作容器内的内存文件名。如果指定了目标,则将其用作文件名。在上述示例中,针对每个 secret 指定的目标,将创建两个文件:/run/secrets/ssh
和 /run/secrets/app
。
5)使用 configs 创建服务 (--config)
使用 --config 标志为容器提供对配置的访问权限。
创建一个带有配置的服务。配置将被挂载到redis-config
目录下,由在容器内运行命令的用户拥有所有权(通常为 root 用户),并且文件模式为 0444
或可全局读取。您可以指定 uid 和 gid 作为数字 ID 或名称。当使用名称时,所提供的组/用户名称必须在容器中预先存在。模式是指定为 4 个数字序列,例如 0755。
docker service create --name=redis --config redis-conf redis:3.0.6
创建一个带有配置的服务,并指定目标位置和文件模式:
docker service create --name redis \ --config source=redis-conf,target=/etc/redis/redis.conf,mode=0400 redis:3.0.6
要为服务授予对多个配置的访问权限,请使用多个 --config
标志。
如果未指定目标,则配置位于容器的根目录下。如果未指定目标,则配置的名称将用作容器内的文件名。如果指定了目标,则将其用作文件名。
6)创建一个带有滚动更新策略的服务
docker service create \ --replicas 10 \ --name redis \ --update-delay 10s \ --update-parallelism 2 \ redis:3.0.6
当运行服务更新时,调度程序会一次最多更新 2 个任务,每次更新之间间隔 10 秒。更多信息,请参阅滚动更新教程。
设置环境变量 (-e, --env)这将为服务中的所有任务设置环境变量。例如:
docker service create \ --name redis_2 \ --replicas 5 \ --env MYVAR=foo \ redis:3.0.6
要指定多个环境变量,请使用多个 --env 标志,每个标志都带有单独的键值对。
docker service create \ --name redis_2 \ --replicas 5 \ --env MYVAR=foo \ --env MYVAR2=bar \ redis:3.0.6
使用特定主机名创建服务 (--hostname)此选项将 Docker 服务容器的主机名设置为指定的字符串。例如:
docker service create --name redis --hostname myredis redis:3.0.6
在服务上设置元数据 (-l, --label)标签是一个应用于服务的键值对元数据。要为服务设置两个标签,请使用以下命令:
docker service create \ --name redis_2 \ --label com.example.foo="bar" \ --label bar=baz \ redis:3.0.6
有关标签的更多信息,请参阅应用自定义元数据。
7)添加绑定挂载、卷或内存文件系统 (--mount)
Docker支持三种不同类型的挂载方式,允许容器读取或写入主机操作系统上的文件或目录,或者在内存文件系统上进行操作。这些类型包括数据卷(通常简称为卷)、绑定挂载、tmpfs 和命名管道。
绑定挂载(bind mount)使得主机上的文件或目录可以在挂载的容器内访问。绑定挂载可以是只读或读写的。例如,一个容器可以通过挂载主机的 /etc/resolv.conf
文件共享主机的 DNS 信息,或者一个容器可以将日志写入主机的 /var/log/myContainerLogs
目录中。如果您使用绑定挂载,并且主机和容器对于权限、访问控制或其他细节有不同的理解,那么可能会遇到可移植性问题。
命名卷(named volume)是一种机制,用于将容器所需的持久化数据与用于创建容器的镜像和主机机器解耦。命名卷由Docker创建和管理,即使没有容器在使用,命名卷仍然存在。命名卷中的数据可以在容器和主机机器之间共享,以及在多个容器之间共享。Docker使用卷驱动程序来创建、管理和挂载卷。您可以使用Docker命令备份或恢复卷。
tmpfs 是在容器内部挂载一个临时文件系统,用于存储临时数据。
npipe 将主机上的命名管道(named pipe)挂载到容器中。
考虑这样一种情况,您的镜像启动一个轻量级的Web服务器。您可以将该镜像作为基础镜像,将网站的HTML文件复制到其中,并将其打包到另一个镜像中。每次您的网站发生更改时,您需要更新新的镜像并重新部署所有提供网站服务的容器。更好的解决方案是将网站存储在一个命名卷中,在启动时将其附加到每个Web服务器容器上。要更新网站,只需更新命名卷即可。
有关命名卷的更多信息,请参阅数据卷(Data Volumes)。
以下表格描述了适用于绑定挂载和命名卷的选项:
选项 | 是否必需 | 描述 |
type | 否 | 挂载类型,可以是 volume(卷)、bind(绑定挂载)、tmpfs(临时文件系统) 或 npipe(命名管道)。如果未指定类型,默认为 volume。 volume:将一个受管理的卷挂载到容器中。 bind:将主机上的目录或文件绑定挂载到容器中。 tmpfs:在容器中挂载一个临时文件系统。 npipe:(仅适用于 Windows 容器)将主机上的命名管道挂载到容器中。 |
src / source | 对于 bind 和 npipe 类型为必需项 | 对于 volume 类型:src 是一种可选方式, 用于指定卷的名称(例如,src=my-volume)。 如果命名卷不存在,将自动创建。如果未指定 src, 卷将被分配一个在主机上保证 唯一但在集群范围内可能不唯一的随机名称。 随机命名的卷与其容器具有相同的生命周期, 在容器被销毁时(服务更新、扩展或重新平衡服务时)也会被销毁。 对于 bind 类型:src 是必需的, 并指定要绑定挂载的文件或目录的绝对路径 (例如,src=/path/on/host/)。 如果文件或目录不存在,将产生错误。 对于 tmpfs 类型:不支持 src。 |
dst / destination / target | 是 | 容器内的挂载路径,例如 /some/path/in/container/。 如果容器的文件系统中不存在该路径, 引擎会在挂载卷或绑定挂载之前在指定位置创建一个目录。 |
readonly / ro | 引擎默认将绑定挂载和卷挂载为读写, 除非在挂载绑定或卷时指定 readonly 选项。 请注意,对于绑定挂载, 设置 readonly 不会使其子挂载点 在当前的 Linux 实现中变为只读。 另请参阅 bind-nonrecursive。 true 或 1 或不设置值: 将绑定挂载或卷挂载为只读。 false 或 0:将绑定挂载或卷挂载为读写。 |
8)绑定装载的选项
下列选项只能用于绑定装载(type=bind):
选项 | 描述 |
bind-propagation | 查看绑定传播部分。 |
consistency | 挂载的一致性要求之一: default:等同于consistent。 consistent:完全一致性。 容器运行时和主机始终保持挂载的完全一致视图。 cached:主机视图为权威。 在容器内部可见主机上进行的更新可能会有延迟。 delegated:容器运行时的视图为权威。 在主机上可见容器内进行的更新可能会有延迟。 |
bind-nonrecursive | 默认情况下,子挂载点也会递归地进行绑定挂载。 然而,当绑定挂载配置为只读选项时, 这种行为可能会令人困惑, 因为子挂载点不会作为只读挂载。 设置bind-nonrecursive以禁用递归绑定挂载。 可选值: true或1:禁用递归绑定挂载。false或0: 如果未提供值,则为默认值。 启用递归绑定挂载。 |
9)绑定传播(Bind propagation)
指的是在给定的绑定挂载点或命名卷中创建的挂载是否可以传播到该挂载点的副本。考虑一个挂载点/mnt
,它也被挂载在/tmp
上。传播设置控制着是否在/mnt/a
上也可以访问/tmp/a
的挂载点。每个传播设置都有一个递归的对应关系。对于递归,考虑/tmp/a
也被挂载为/foo
。传播设置控制/mnt/a
和/或/tmp/a
是否存在。
bind-propagation选项对于绑定挂载和命名卷的默认值都是rprivate,只能对绑定挂载进行配置。换句话说,命名卷不支持绑定传播。
shared:原始挂载点的子挂载点对副本挂载点可见,并且副本挂载点的子挂载点也会传播到原始挂载点。
slave:类似于共享挂载,但只有单向。如果原始挂载点公开了一个子挂载点,副本挂载点可以看到它。但是,如果副本挂载点公开了一个子挂载点,原始挂载点无法看到它。
private:挂载是私有的。其中的子挂载点不会传播到副本挂载点,并且副本挂载点的子挂载点不会传播到原始挂载点。
rshared:与shared相同,但传播还扩展到原始或副本挂载点中嵌套的挂载点。
rslave:与slave相同,但传播还扩展到原始或副本挂载点中嵌套的挂载点。
rprivate:默认设置。与private相同,意味着原始或副本挂载点中的任何挂载点都不会在任何方向上传播。
有关绑定传播的更多信息,请参阅Linux内核文档中的共享子树部分。
10)命名卷的选项
以下选项仅适用于命名卷(type=volume):
选项 | 描述 |
volume-driver | 用于该卷的卷驱动程序插件的名称。默认为"local", 如果卷不存在,则使用本地卷驱动程序创建卷。 |
volume-label | 在创建卷时应用于卷的一个或多个自定义元数据("标签")。 例如, volume-label=mylabel=hello-world,my-other-label=hello-mars。 有关标签的更多信息,请参阅应用自定义元数据。 |
volume-nocopy | 默认情况下,如果将空卷附加到容器, 并且在容器的挂载路径(目标路径)上已经存在文件或目录, 则引擎将这些文件和目录复制到卷中, 以便主机可以访问它们。 将volume-nocopy设置为禁用从容器文件系统复制文件到卷并挂载空卷。 可选值: true或1:如果未提供值,则为默认值。禁用复制。false或0:启用复制。 |
volume-opt | 针对特定卷驱动程序的选项,这些选项将在创建卷时传递给驱动程序。 选项以逗号分隔的键值对形式提供, 例如,volume-opt=some-option=some-value, volume-opt=some-other-option=some-other-value。 有关给定驱动程序的可用选项,请参考该驱动程序的文档。 |
11)tmpfs的选项
以下选项只能用于tmpfs装载(type=tmpfs);
选项 | 描述 |
tmpfs-size | tmpfs挂载的大小,以字节为单位。在Linux中默认为无限制。 |
tmpfs-mode | tmpfs的文件模式,以八进制表示(例如,"700"或"0700")。在Linux中默认为"1777"。 |
11)"--mount" 和 "--volume" 之间的区别如下:
- "--mount" 选项支持大多数与 "docker run" 命令的 "-v" 或 "--volume" 选项相同的功能,但也存在一些重要的区别:
- "--mount" 选项允许您为每个卷指定卷驱动程序和卷驱动程序选项,而无需事先创建卷。相反,"docker run" 命令允许您使用 "--volume-driver" 标志指定一个共享的卷驱动程序,该驱动程序将被所有卷共享。
- "--mount" 选项允许您在创建卷之前为卷指定自定义元数据("标签")。
- 使用 "--mount" 选项并指定类型为 "bind" 时,host-path 必须引用主机上已存在的路径。如果路径不存在,服务将因错误而失败。
- "--mount" 选项不允许您使用 Z 或 z 标志对卷进行 SELinux 标记。
12)创建使用命名卷的服务的示例:
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
对于服务的每个副本,引擎会从任务所在的默认("local")卷驱动程序请求名为 "my-volume" 的卷。如果该卷不存在,引擎将创建一个新的卷并应用 "color" 和 "shape" 标签。任务启动时,该卷将被挂载到容器内的 /path/in/container/。
请注意,默认的("local")卷是一个本地范围的卷驱动程序。这意味着根据任务部署的位置,该任务要么获得一个名为 "my-volume" 的新卷,要么与同一服务的其他任务共享相同的 "my-volume"。如果容器内运行的软件未设计为处理多个进程同时写入相同位置的情况,多个容器向单个共享卷写入可能会导致数据损坏。此外,还需要考虑到容器可以被 Swarm 编排器重新调度并部署到不同的节点上。
13)创建使用匿名卷的服务的示例:
创建一个包含三个副本的服务,匿名卷位于/path/in/container中:
docker service create \ --name my-service \ --replicas 3 \ --mount type=volume,destination=/path/in/container \ nginx:alpine
在此示例中,未为卷指定名称(source),因此每个任务都将创建一个新的卷。这样可以确保每个任务都拥有自己的卷,并且卷不在任务之间共享。匿名卷将在使用它们的任务完成后被删除。
14)绑定挂载主机目录的服务
docker service create \ --name my-service \ --mount type=bind,source=/path/on/host,destination=/path/in/container \ nginx:alpine
以上示例将主机上的目录 /path/on/host
绑定挂载到支持该服务的容器中的目录 /path/in/container
。
设置服务模式(--mode):服务模式确定该服务是一个复制服务(replicated service)还是一个全局服务(global service)。复制服务按指定数量运行任务,而全局服务在集群中的每个活动节点上运行。
下面的命令创建一个全局服务:
docker service create \ --name redis_2 \ --mode global \ redis:3.0.6
可以通过定义约束表达式来限制可以调度任务的节点集合。约束表达式可以使用match(==)或exclude(!=)规则。多个约束找到满足每个表达式(和匹配)的节点。约束可以匹配节点或Docker引擎标签,如下所示:
节点属性 | 匹配条件 | 示例 |
节点 ID | node.id==2ivku8v2gvtg4 | |
node.hostname | 节点主机名 | node.hostname!=node-2 |
node.role | 节点角色(manager/worker) | node.role==manager |
node.platform.os | 节点操作系统 | node.platform.os==windows |
node.platform.arch | 节点架构 | node.platform.arch==x86_64 |
node.labels | 用户定义的节点标签 | node.labels.security==high |
engine.labels | Docker 引擎的标签 | engine.labels.operatingsystem==ubuntu-22.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:3.0.6
如果服务约束排除了集群中的所有节点,将打印出找不到合适的节点的消息,但调度器将启动一个调和循环,并在合适的节点变得可用时部署服务。
在下面的例子中,没有找到满足约束的节点,导致服务无法与期望的状态协调:
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
在集群中的一个节点上添加 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
15)指定服务放置偏好 (--placement-pref)
可以设置服务以在不同类别的节点上均匀地分配任务。一个例子是在一组数据中心或可用性区域中平衡任务。下面的例子说明了这一点:
docker service create \ --replicas 9 \ --name redis_2 \ --placement-pref spread=node.labels.datacenter \ redis:3.0.6
这使用 --placement-pref 与 spread 策略(当前是唯一支持的策略)来均匀地将任务分布在 datacenter 节点标签的值上。在这个例子中,我们假设每个节点都有一个 datacenter 节点标签附加到它上面。如果在 swarm 中的节点中,这个标签有三个不同的值,那么每个值的节点将分配到三分之一的任务。即使某个值的节点比另一个值的节点多,也是如此。例如,考虑以下一组节点:
- 三个节点 node.labels.datacenter=east
- 两个节点 node.labels.datacenter=south
- 一个节点 node.labels.datacenter=west
由于我们正在将任务分散到 datacenter 标签的值上,服务有 9 个副本,所以每个 datacenter 将结束 3 个副本。与 east 值关联的有三个节点,所以每一个都会得到为这个值预留的三个副本中的一个。南方有两个值的节点,这个值的三个副本将在他们之间分配,其中一个接收两个副本,另一个接收一个。最后,west 有一个单独的节点,将得到所有为 west 预留的三个副本。
如果在一类中的节点(例如,那些带有 node.labels.datacenter=south
的节点)由于约束或资源限制无法处理他们应得的任务,额外的任务将会分配给其他的节点,如果可能的话。
引擎标签和节点标签都受放置偏好支持。上面的例子使用了一个节点标签,因为标签是通过 node.labels.datacenter
引用的。要在引擎标签的值上进行分布,使用 --placement-pref spread=engine.labels
。
可以向服务添加多个放置偏好。这建立了偏好的层次结构,使得任务首先在一个类别中分割,然后在其他类别中进一步分割。这可能在将任务公平地分配到数据中心,然后在每个数据中心内部按机架选择划分任务时很有用。要添加多个放置偏好,可以多次指定 --placement-pref
标志。顺序很重要,当做出调度决策时,将按照给定的顺序应用放置偏好。
以下示例设置了具有多个放置偏好的服务。任务首先在各个数据中心之间分散,然后在机架上分散(如相应的标签所示):
docker service create \ --replicas 9 \ --name redis_2 \ --placement-pref 'spread=node.labels.datacenter' \ --placement-pref 'spread=node.labels.rack' \ redis:3.0.6
使用 docker service update
更新服务时,--placement-pref-add
在所有现有放置偏好之后追加新的放置偏好。--placement-pref-rm
移除与参数匹配的现有放置偏好。
指定服务的内存要求和约束 (--reserve-memory 和 --limit-memory)
如果您的服务需要最小的内存量才能正确运行,您可以使用 --reserve-memory
来指定只有在有这么多可用内存可预留的节点上才调度该服务。如果没有可用的满足条件的节点,任务不会被调度,但会保持在待处理状态。
以下示例要求在调度服务在该节点上运行之前,该节点必须有 4GB 的内存可用并可预留。
docker service create --reserve-memory=4GB --name=too-big nginx:alpine
管理器不会将一组容器调度到单个节点上,如果这些容器的总预留超过了该节点可用的内存。
任务被调度并运行后,--reserve-memory 不强制执行内存限制。使用 --limit-memory 确保任务在节点上使用的内存不超过给定的量。此示例将任务使用的内存量限制在 4GB。即使你的每个节点只有 2GB 的内存,任务也会被调度,因为 --limit-memory 是上限。
docker service create --limit-memory=4GB --name=too-big nginx:alpine
使用 --reserve-memory
和 --limit-memory
并不能保证 Docker 不会在你的主机上使用超过你希望的更多的内存。例如,你可以创建许多服务,它们的内存使用之和可能会耗尽可用的内存。
通过考虑主机上运行的其他(非容器化)软件,你可以防止这种情况耗尽可用的内存。如果 --reserve-memory
大于或等于--limit-memory
,Docker 就不会在没有足够内存的主机上调度服务。--limit-memory
将限制服务的内存在该限制内,所以如果每个服务都设置了内存预留和限制,Docker 服务就不太可能饱和主机。在 Docker 主机上直接运行的其他非服务容器或应用程序仍然可能耗尽内存。
这种方法也有一个缺点。预留内存也意味着你可能无法最优地使用节点上可用的内存。考虑一个服务,在正常情况下使用 100MB 的内存,但取决于负载,可以“峰值”在 500MB。为该服务预留 500MB(以保证在“峰值”时可以有 500MB)将导致大部分时间内有 400MB 的内存被浪费。
简单来说,你可以采取更保守或更灵活的方法:
保守:预留 500MB,限制为 500MB。基本上你现在把服务容器当作虚拟机对待,可能会失去容器的一个大优点,即每个主机的服务密度更大。
灵活:限制为 500MB,假设如果服务需要超过 500MB,它就是故障。预留介于 100MB 的“正常”要求和 500MB 的“峰值”要求之间的一些东西。这假设当这个服务处于“峰值”时,其他服务或非容器工作负载可能不会。
你采取的方法在很大程度上取决于你的工作负载的内存使用模式。在正常和峰值条件下测试后,你应该在一个方法上做出决定。
在 Linux 上,你还可以使用 cgroups 或其他相关的操作系统工具,限制服务在给定主机上的总内存占用。
16)指定每个节点的最大副本数 (--replicas-max-per-node)
使用 --replicas-max-per-node 标志设置可以在一个节点上运行的副本任务的最大数量。下面的命令创建了一个 nginx 服务,它有 2 个副本任务,但每个节点只有一个副本任务。
这在一些应用中非常有用,例如在需要在每个节点上运行单个副本的应用程序中,或者需要在一个节点上限制运行多个任务以防止资源竞争的情况。
docker service create \ --name nginx \ --replicas 2 \ --replicas-max-per-node 1 \ --placement-pref 'spread=node.labels.datacenter' \ nginx
使用 docker service update 更新服务时,可以使用 --replicas-max-per-node-add
和 --replicas-max-per-node-rm
修改此设置。
17)将服务附加到现有网络 (--network)
可以使用 overlay 网络在 swarm 内部连接一个或多个服务。
首先,在管理节点上使用 docker network create 命令创建一个 overlay 网络:
docker network create --driver overlay my-network etjpu59cykrptrgw0z0hk5snf
在 swarm 模式下创建了 overlay 网络后,所有管理节点都可以访问这个网络。
当你创建服务并传递 --network
标志以将服务附加到 overlay 网络时:
docker service create \ --replicas 3 \ --network my-network \ --name my-web \ nginx 716thylsndqma81j6kkkb5aus
Swarm 将 my-network 扩展到运行该服务的每个节点。
同一网络上的容器可以使用服务发现来互相访问。
--network 的长格式语法允许指定别名和驱动选项的列表:--network name=my-network,alias=web1,driver-opt=field1=value1
18)在 swarm 外部发布服务端口 (-p, --publish)
可以使用 --publish 标志发布服务端口,使它们在 swarm 外部可用。 --publish 标志可以采用两种不同风格的参数。短版本是位置参数,允许你指定发布的端口和目标端口,用冒号 (:) 分隔。
docker service create --name my_web --replicas 3 --publish 8080:80 nginx
还有一个长格式,更易于阅读,允许你指定更多的选项。优先使用长格式。在使用短格式时,你无法指定服务的模式。下面是使用长格式创建与上面相同的服务的示例:
docker service create --name my_web --replicas 3 --publish published=8080,target=80 nginx
可以指定的选项有:
选项 | 短语法 | 长语法 | 描述 |
发布的和目标的端口 | --publish 8080:80 | --publish published=8080,target=80 | 容器内的目标端口和映射到节点上的端口, 可以使用路由网格(ingress)或主机级别的网络。 这个表格后面有更多选项。 首选键值语法,因为它有一定的自我解释性。 |
模式 | 短语法无法设置 | --publish published=8080,target=80,mode=host | 用于绑定端口的模式, 可以是 ingress 或 host。 默认为 ingress,使用路由网格。 |
协议 | --publish 8080:80/tcp | --publish published=8080,target=80,protocol=tcp | 使用的协议,可以是 tcp, udp, 或 sctp。 默认为 tcp。 如果要绑定一个端口到两种协议, 需要指定两次 -p 或 --publish 标志。 |
当你使用ingress模式发布一个服务端口时,swarm路由网格使得每个节点上的发布端口都可以访问服务,无论该节点上是否运行着服务的任务。如果你使用host模式,端口只会在运行服务的节点上绑定,每个节点上的特定端口只能绑定一次。你只能使用长语法设置发布模式。有关更多信息,请参考使用swarm模式路由网格。
为托管服务帐户提供凭据规范 (--credential-spec
)此选项只用于使用Windows容器的服务。--credential-spec
必须是file://
或registry://
的格式。
当使用file://
格式时,引用的文件必须存在于docker数据目录的CredentialSpecs子目录中,默认为Windows上的C:\ProgramData\Docker\
。例如,指定file://spec.json
将加载C:\ProgramData\Docker\CredentialSpecs\spec.json
。
当使用registry://
格式时,凭据规范从守护进程主机的Windows注册表中读取。指定的注册表值必须位于:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs
使用模板创建服务你可以使用Go的text/template包提供的语法为service create的某些标志使用模板。
支持的标志如下:
--hostname--mount--envGo
模板的有效占位符如下:
(在原文中,你可能有一个表格或者列表需要翻译,但在你的文本中这部分内容没有包含,所以我无法为你提供具体的翻译。如果你需要这个列表的翻译,你可以把这个列表包含在你的文本中。)
位符 | 描述 |
.Service.ID | 服务 ID |
.Service.Name | 服务名称 |
.Service.Labels | 服务标签 |
.Node.ID | 节点 ID |
.Node.Hostname | 节点主机名 |
.Task.ID | 任务 ID |
.Task.Name | 任务名称 |
.Task.Slot | 任务插槽 |
19)模板示例
在此示例中,我们将根据服务的名称、所在节点的 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
20)在 Windows 上指定隔离模式 (--isolation)
默认情况下,调度到 Windows 节点上的任务将使用该节点配置的默认隔离模式。要强制使用特定的隔离模式,可以使用 --isolation 标志:
docker service create --name myservice --isolation=process microsoft/nanoserver
Windows 上支持的隔离模式包括:
default:使用运行任务的节点上指定的默认设置process:使用进程隔离(仅限 Windows 服务器)hyperv:使用 Hyper-V 隔离
21)创建请求通用资源的服务 (--generic-resources)
可以通过使用 --generic-resource
标志来限制任务可以降落的节点类型(如果节点宣告了这些资源):
docker service create \ --name cuda \ --generic-resource "NVIDIA-GPU=2" \ --generic-resource "SSD=1" \ nvidia/cuda
22)作为工作运行
工作是一种特殊的服务,设计为运行到完成后停止的操作,而不是运行长时间运行的守护进程。当属于工作的任务成功退出(返回值为 0)时,该任务被标记为“已完成”,并且不会再次运行。
通过使用两种模式之一,replicated-job 或 global-job 来启动作业:
docker service create --name myjob \ --mode replicated-job \ bash "true"
此命令将运行一个任务,该任务将使用 bash 镜像执行命令 true,该命令将返回 0,然后退出。
尽管作业最终是一种不同类型的服务,但与其他服务相比,它们有几点需要注意:
所有的更新或回滚配置选项都无效。作业可以被更新,但不能被展开或回滚,使这些配置选项变得无关紧要。在达到完成状态后,作业永远不会重启。这意味着对于工作,将 --restart-condition 设置为 any 和将其设置为 on-failure 是相同的。作业在复制模式和全局模式中都可用。
复制的作业复制的作业就像复制的服务。设置 --replicas 标志将指定要执行的作业的总迭代次数。
默认情况下,复制作业的所有副本都会立即启动。要控制同时执行的副本总数,可以使用 --max-concurrent 标志:
docker service create \ --name mythrottledjob \ --mode replicated-job \ --replicas 10 \ --max-concurrent 2 \ bash "true"
以上命令将执行总共 10 个任务,但在任何给定时间只会运行 2 个。
全局作业全局作业就像全局服务,每个匹配放置约束的节点上都会执行一次任务。全局作业由模式 global-job 表示。
请注意,创建全局作业后,添加到集群的任何新节点都将启动该作业的任务。全局作业整体没有“完成”状态,除非每个满足作业约束的节点都有一个已完成的任务。
4、命令选项
参数名 | 默认值 | 描述 |
--cap-add | 添加 Linux 权限 | |
--cap-drop | 移除 Linux 权限 | |
--config | 指定要暴露给服务的配置 | |
--constraint | 放置约束条件 | |
--container-label | 容器标签 | |
--credential-spec | 管理的服务账户的凭据规范(仅适用于 Windows) | |
--detach, -d | 立即退出而不等待服务收敛 | |
--dns | 设置自定义 DNS 服务器 | |
--dns-option | 设置 DNS 选项 | |
--dns-search | 设置自定义 DNS 搜索域 | |
--endpoint-mode | vip | 端点模式(vip 或 dnsrr) |
--entrypoint | 覆盖镜像的默认 ENTRYPOINT | |
--env, -e | 设置环境变量 | |
--env-file | 读取环境变量文件 | |
--generic-resource | 用户定义的资源 | |
--group | 为容器设置一个或多个附加用户组 | |
--health-cmd | 运行用于检查健康状态的命令 | |
--health-interval | 运行检查之间的时间间隔(毫秒 | |
--health-retries | 报告不健康所需的连续失败次数 | |
--health-start-period | 容器初始化之前启动周期,用于计算不稳定重试次数(毫秒 | |
--health-timeout | 允许单个检查运行的最长时间(毫秒 | |
--host | 设置一个或多个自定义主机到 IP 的映射(host:ip) | |
--hostname | 容器主机名 | |
--init | 在每个服务容器内部使用 init,用于转发信号和清理进程 | |
--isolation | 服务容器的隔离模式 | |
--label, -l | 服务标签 | |
--limit-cpu | 限制 CPU | |
--limit-memory | 限制内存 | |
--limit-pids | 限制进程的最大数量(默认为0,表示无限制) | |
--log-driver | 服务的日志驱动程序 | |
--log-opt | 日志驱动程序选项 | |
--max-concurrent | 并发运行的任务数(默认等于 --replicas) | |
--mode | replicated | 服务模式(replicated、global、replicated-job、global-job) |
--mount | 将文件系统挂载到服务 | |
--name | 服务名称 | |
--network | 网络附件 | |
--no-healthcheck | 禁用 | |
--no-resolve-image | 不查询注册表以解析镜像摘要和支持的平台 | |
--placement-pref | 添加放置偏好 | |
--publish, -p | 将端口发布为节点端口 | |
--quiet, -q | 抑制进度输出 | |
--read-only | 将容器的根文件系统挂载为只读 | |
--replicas | 任务数量 | |
--replicas-max-per-node | 每个节点的最大任务数(默认为0,表示无限制) | |
--reserve-cpu | 保留的 CPU 资源 | |
--reserve-memory | 保留的内存资源 | |
--restart-condition | any | 满足条件时重新启动(none、on-failure、any,默认为 any) |
--restart-delay | 5s | 重新启动尝试之间的延迟时间(纳秒 |
--restart-max-attempts | 在放弃之前的最大重新启动次数 | |
--restart-window | 用于评估重新启动策略的窗口时间(纳秒 | |
--rollback-delay | 0s | 任务回滚之间的延迟时间(纳秒 |
--rollback-failure-action | pause | 回滚失败时的操作(pause、continue,默认为 pause) |
--rollback-max-failure-ratio | 0 | 在回滚期间容忍的失败率(默认为 0) |
--rollback-monitor | 5s | 每个任务回滚后监视失败的持续时间(纳秒 |
--rollback-order | stop-first | 回滚顺序(start-first、stop-first,默认为 stop-first) |
--rollback-parallelism | 1 | 同时回滚的最大任务数(0 表示同时回滚所有任务) |
--secret | 指定要暴露给服务的机密 | |
--stop-grace-period | 10s | 强制杀死容器之前等待的时间(纳秒 |
--stop-signal | 停止容器的信号 | |
--sysctl | Sysctl 选项 | |
--tty, -t | 分配一个伪 TTY | |
--ulimit | Ulimit 选项 | |
--update-delay | 0s | 更新之间的延迟时间(纳秒) |
--update-failure-action | pause | 更新失败时的操作(pause、continue、rollback,默认为 pause) |
--update-max-failure-ratio | 0 | 在更新期间容忍的失败率(默认为 0) |
--update-monitor | 5s | 每个任务更新后监视失败的持续时间(纳秒 |
--update-order | stop-first | 更新顺序(start-first、stop-first,默认为 stop-first) |
--update-parallelism | 1 | 同时更新的最大任务数(0 表示同时更新所有任务) |
--user, -u | 用户名或 UID(格式: | |
--with-registry-auth | 将注册表身份验证详细信息发送给 Swarm 代理 | |
--workdir, -w | 容器内的工作目录 |
5、子命令
命令 | 描述 |
docker service create | 创建新的服务 |
docker service inspect | 显示一个或多个服务的详细信息 |
docker service logs | 获取一个服务或任务的日志 |
docker service ls | 列出服务 |
docker service ps | 列出一个或多个服务的任务 |
docker service rm | 删除一个或多个服务 |
docker service rollback | 恢复服务配置的更改 |
docker service scale | 缩放一个或多个复制的服务 |
docker service update | 更新一个服务的配置 |