docker swarm英文文档学习-8-在集群中部署服务

Deploy services to a swarm在集群中部署服务

集群服务使用声明式模型,这意味着你须要定义服务的所需状态,并依赖Docker来维护该状态。该状态包括如下信息(但不限于):

应该运行服务容器的镜像名称和标记
有多少容器参与服务
是否有任何端口暴露给集群以外的客户端
当Docker启动时,服务是否应该自动启动
重启服务时发生的特定行为(例如是否使用滚动重启)
服务能够运行的节点的特征(例如资源约束和位置首选项)
有关群模式的概述,请参见 Swarm mode key concepts。有关服务如何工做的概述,请参见How services workhtml

 

Create a service建立服务

要建立没有额外配置的单副本服务,只须要提供镜像名称。该命令使用随机生成的名称启动Nginx服务,没有发布端口。这是一个简单的示例,由于你没法与Nginx服务交互。node

$ docker service create nginx

服务被安排在一个可用的节点上。要确认服务已建立并成功启动,请使用docker service ls命令:nginx

$ docker service ls

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

建立的服务并不老是当即运行。若是服务的镜像不可用,若是没有节点知足你为服务配置的需求,或者其余缘由,则该服务可能处于pending挂起状态。有关更多信息,请参见 Pending services

要为你的服务提供名称,请使用--name标志:web

$ docker service create --name my_web nginx

与独立容器同样,你能够经过在镜像名称以后添加命令来指定服务容器应该运行的命令。这个例子启动了一个名为helloworld的服务,它使用alpine的镜像并运行命令ping docker.com:redis

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

你还能够为要使用的服务指定一个镜像标记。这个例子修改了前面的例子,使用alpine:3.6标记:算法

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

 

Create a service using an image on a private registry使用私有注册表上的镜像建立服务

若是你的镜像在须要登陆的私有注册中心上可用,请在登陆后使用docker service create的--with-registry-auth标志。若是你的镜像存储在registry.example.com上,这是一个私有注册中心,请使用以下命令:docker

$ docker login registry.example.com

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

这将使用加密的WAL日志将登陆令牌从本地客户机传递到部署服务的集群节点。有了这些信息,节点就能够登陆到注册中心并拉出镜像。json

 

Update a service更新服务

你可使用docker service update命令更改现有服务的几乎全部内容。更新服务时,Docker将中止其容器并使用新配置从新启动它们。

因为Nginx是一个web服务,若是你将端口80发布到集群以外的客户端,那么它的工做效果会更好。你能够在建立服务时使用-p或--publish标志指定这一点。更新现有服务时,标志为--publish-add。还有一个--publish-rm标志,用于删除先前发布的端口。

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

$ docker service update --publish-add 80 my_web

检查其是否工做,使用:数组

docker service ls

有关发布端口如何工做的更多信息,请参见publish ports

你几乎能够更新关于现有服务的全部配置细节,包括它运行的镜像名称和标记。参见Update a service’s image after creation

 

Remove a service移除服务

要删除服务,请使用docker service remove命令。你能够经过其ID或名称删除服务,如docker service ls命令的输出所示。下面的命令删除my_web服务。

$ docker service remove my_web

 

Service configuration details服务配置细节

下面几节提供关于服务配置的详细信息。本主题并不涵盖每一个标志或场景。在几乎全部能够在服务建立时定义配置的实例中,你还能够以相似的方式更新现有服务的配置。

请参阅docker service createdocker service update的命令行引用,或使用--help标志运行这些命令之一。

Configure the runtime environment配置运行环境

你能够为容器中的运行时环境配置如下选项:

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

如下服务的容器将环境变量$MYVAR设置为myvalue,从/tmp/目录运行,并做为my_user用户运行。

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

 

Update the command an existing service runs更新存在的服务运行的命令

要更新现有服务运行的命令,可使用--args标志。下面的示例更新一个名为helloworld的现有服务,使其运行ping docker.com命令,而不是之前运行的任何命令:

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

 

 

Specify the image version a service should use指定服务应该使用的镜像版本

当你建立一个服务而没有指定要使用的镜像版本的任何细节时,该服务将使用使用latest标记来标记的版本。根据指望的结果,你能够强制服务以几种不一样的方式使用镜像的特定版本。
一个镜像版本能够用几种不一样的方式表达:
1.若是指定一个标记,则管理器(若是使用content trust,则为Docker客户机)将该标记解析为摘要。当在工做节点上接收到建立容器任务的请求时,工做节点只会看到摘要,而不会看到标记。

注意:

标记即ubuntu:16.04

摘要即对应的sha256:35bc48a1ca97c3971611dc4662d08d131869daa692acb281c7e9e052924e38b1

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

一些标签表示独立的版本,好比ubuntu:16.04。随着时间的推移,这样的标记几乎老是解析为一个稳定的摘要。若是可能的话,建议你使用这种标记。
其余类型的标记,如latest或nightly,可能常常解析为新的摘要,这取决于镜像的做者更新标记的频率。不建议使用频繁更新的标记运行服务,以防止不一样的服务复制任务使用不一样的镜像版本。


2.若是根本不指定版本,则按照约定将镜像的latest标记解析为摘要。工做人员在建立服务任务时使用此摘要中的镜像。
所以,如下两个命令是等价的:

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

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

 

3.若是直接指定摘要,则在建立服务任务时老是使用镜像的准确版本。

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

在建立服务时,镜像的标记被解析为服务建立时标记所指向的特定摘要。除非服务被显式更新,不然该服务的工做节点将永远使用该特定摘要。若是你确实使用常常更改的标记(如最新),则此功能尤为重要,由于它确保全部服务任务使用相同版本的镜像。

注意:若是启用了内容可信(content trust),客户端实际上会在联系集群管理器以前将镜像的标记解析为摘要,以验证镜像是否已签名。所以,若是你使用内容可信,集群管理器将接收预先解析的请求。在这种状况下,若是客户机没法将镜像解析为摘要,则请求将失败。

若是管理器不能将标记解析为摘要,则每一个工做节点负责将标记解析为摘要,不一样的节点可能使用不一样版本的镜像。若是发生这种状况,将记录以下所示的警告,用占位符替换实际信息。

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

要查看图像的当前摘要,发出命令docker inspect <IMAGE>:<TAG>并查找RepoDigests行。如下是ubuntu:latest当前的摘要,在编写此内容时是最新的。为了清晰起见,输出被截断。

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

建立服务以后,除非你使用--image标记显式地运行docker service update,不然它的镜像永远不会更新,以下所述。其余更新操做(如扩展服务、添加或删除网络或卷、重命名服务或任何其余类型的更新操做)不更新服务的镜像。

 

Update a service’s image after creation建立后更新服务的镜像

每一个标记表示一个摘要,相似于Git散列。有些标记(如latest)常常更新以指向新的摘要。其余的,好比ubuntu:16.04,表明了一个已经发布的软件版本,不须要常常更新以指向一个新的摘要。在Docker 1.13及更高版本中,当你建立服务时,它被限制为使用镜像的特定摘要来建立任务,直到你使用--image标志的service update来更新服务为止。若是使用旧版本的Docker引擎,则必须删除并从新建立服务以更新其镜像。

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

注意:若是使用内容可信content trust,Docker客户机解析镜像,swarm manager接收镜像和摘要,而不是标记。
一般,管理器能够将标记解析为新的摘要和服务更新,从新部署每一个任务以使用新镜像。若是管理器没法解决标记或出现其余问题,则接下来的两个部分将概述将会发生的状况。

IF THE MANAGER RESOLVES THE TAG若是管理器解析标记

若是集群管理器能够将镜像标记解析为摘要,它将指示工做节点从新部署任务并在摘要中使用镜像。

  • 若是工做人员在该摘要中缓存了镜像,则使用它。
  • 若是不是,则尝试从Docker Hub或私有注册中心提取镜像:
  1. 若是成功,则使用新镜像部署任务。
  2. 若是worker没法拉出镜像,则服务没法在该worker节点上部署。Docker再次尝试部署任务,多是在不一样的工做节点上。

IF THE MANAGER CANNOT RESOLVE THE TAG若是管理器不能解析标记

若是集群管理器不能将镜像解析为摘要,那么一切都不会丢失:

  • 管理器指示工做节点使用标记处的镜像从新部署任务。
  • 若是worker有一个本地缓存的镜像,该镜像将解析到该标记,那么它将使用该镜像。
  • 若是worker没有解析到标记的本地缓存镜像,则该worker将尝试链接到Docker Hub或私有注册中心以从该标记提取镜像。
  1. 若是成功,工做人员将使用该镜像。
  2. 若是失败,任务将没法部署,管理员将再次尝试部署任务,多是在不一样的工做节点上。

 

Publish ports发布端口

在建立集群服务时,能够经过两种方式将该服务的端口发布到集群以外的主机:

  • 你能够依赖路由网格。当你发布一个服务端口时,集群使服务在每一个节点上的目标端口均可以访问,而无论在该节点上运行的服务是否有任务。这并不复杂,并且对于许多类型的服务来讲都是正确的选择。
  • 你能够将服务任务的端口直接发布到运行该服务的集群节点上。该特性在Docker 1.13及更高版本中可用。这绕过了路由网格,并提供了最大的灵活性,包括开发本身的路由框架的能力。可是,你负责跟踪每一个任务的运行位置,并将请求路由到任务,以及跨节点的负载平衡。

1.PUBLISH A SERVICE’S PORTS USING THE ROUTING MESH使用路由网格发布服务端口

要向集群外部发布服务的端口,使用--publish <PUBLISHED-PORT>:<SERVICE-PORT>。集群使得服务能够在每一个集群节点上的已发布端口上访问。若是外部主机链接到任何集群节点上的该端口,则路由网格将其路由到一个任务。外部主机不须要知道与服务交互的服务任务的IP地址或内部使用的端口。当用户或流程链接到服务时,运行服务任务的任何工做节点均可能响应。有关集群服务网络的详细信息,请参见Manage swarm service networks

Example: Run a three-task Nginx service on 10-node swarm 例子:在10个节点集群中运行三个任务的Ngnix服务

想象你有10个节点的集群,而后你部署了一个Ngnix服务在10个节点上运行三个任务:

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

三个任务最多在三个节点上运行。你不须要知道哪些节点正在运行任务;在这10个节点中,链接到端口8080能够将你链接到三个nginx任务之一。你能够用curl来测试。下面的示例假设localhost是集群节点之一。若是不是这种状况,或者本地主机没有解析到你的主机上的IP地址,则替换主机的IP地址或可解析的主机名。

HTML输出被截断:

$ curl localhost:8080

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

后续链接能够路由到相同或不一样的群集节点。

 

PUBLISH A SERVICE’S PORTS DIRECTLY ON THE SWARM NODE直接在集群节点中发布服务端口

若是须要根据应用程序的状态进行路由决策,或者须要彻底控制将请求路由到服务任务的流程,那么使用路由网格可能不是应用程序的正确选择。要将服务的端口直接发布到其运行的节点上,请使用--publish标志的mode=host选项。

注意:若是你使用mode=host在swarm节点上直接发布一个服务的端口,而且还设置published=<PORT>,这就形成了一个隐含的限制,即你只能在给定的swarm节点上为该服务运行一个任务。你能够经过在没有端口定义的状况下指定published来解决这个问题,这会致使Docker为每一个任务分配一个随机端口。

此外,若是你使用mode=host而不使用docker service create上的--mode=global标志,那么很难知道哪些节点正在运行服务来将工做路由到它们。

 

Example: Run an nginx web server service on every swarm node 例子:在每一个集群节点上运行nginx web服务器服务

nginx是一个开源的反向代理、负载平衡器、HTTP缓存和web服务器。若是你使用路由网格将nginx做为服务运行,那么链接到任何集群节点上的nginx端口都会显示(有效地)运行该服务的随机集群节点的web页面。

下面的示例将nginx做为服务在集群中的每一个节点上运行,并在每一个集群节点上本地公开nginx端口。

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

你能够在每一个集群节点的端口8080上访问nginx服务器。若是向集群中添加一个节点,就会启动nginx任务。你不能在任何绑定到端口8080的集群节点上启动另外一个服务或容器。

注意:这是一个简单的例子。为多层服务建立应用层路由框架很是复杂,超出了本主题的范围。

 

Connect the service to an overlay network链接服务到覆盖网络

你可使用覆盖网络来链接群中的一个或多个服务。
首先,使用docker network create命令和--driver overlay标记在管理器节点上建立覆盖网络。

$ docker network create --driver overlay my-network

在集群模式下建立覆盖网络以后,全部管理器节点均可以访问该网络。
你能够建立一个新的服务,并传递--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

要从网络断开正在运行的服务,请使用--network-rm标志。

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

 

Grant a service access to secrets授予服务对机密的访问权

要建立对docker管理的机密内容有访问权限的服务,请使用--secret标志。有关更多信息,请参见Manage sensitive strings (secrets) for Docker services

Customize a service’s isolation mode自定义服务的隔离模式

Docker 17.12 CE及更高版本容许你指定集群服务的隔离模式。此设置仅适用于Windows主机,对于Linux主机则忽略此设置。隔离模式能够是如下模式之一:

  • default:使用为Docker主机配置的默认隔离模式,如daemon.json中的-exec-opt标志或exec-opts数组所配置的那样。若是守护进程没有指定隔离技术,则process是Windows服务器的默认设置,而hyperv是Windows 10的默认(且惟一)选择。
  • process:将服务任务做为独立的进程在主机上运行。

    注意:process隔离模式仅在Windows服务器上受支持。Windows 10只支持hyperv隔离模式。

  • hyperv:将服务任务做为独立的hyperv任务运行。这增长了开销,但提供了更多的隔离。

在使用--isolation标志建立或更新新服务时,能够指定隔离模式。

 

Control service placement控制服务位置

群服务为你提供了几种不一样的方法来控制不一样节点上服务的规模和位置。

  • 你能够指定服务须要运行特定数量的副本,仍是应该在每一个工做节点上全局运行。参见Replicated or global services
  • 你能够配置服务的CPU或内存需求,而且服务只在知足这些需求的节点上运行。
  • 位置约束容许你将服务配置为仅在具备特定(任意)元数据集的节点上运行,若是不存在适当的节点,则会致使部署失败。例如,你能够指定你的服务只能在任意标签pci_compatible设置为true的节点上运行。
  • 位置首选项让你能够对每一个节点应用具备一系列值的任意标签,并使用算法将服务的任务分散到这些节点上。目前,惟一受支持的算法是spread,它试图将它们平均放置。例如,若是你标记每一个节点带着一个值从1到10的标签rack,而后指定一个位置首选项值标签rack,而后在其余位置限制,位置偏好,和其余特定于节点的限制后,服务任务将尽量均匀地放置在全部带着标签rack的节点,。

与约束不一样,位置首选项是最有效的,若是没有节点可以知足首选项,服务不会失败部署。若是你指定了服务的位置首选项,那么当集群管理器决定哪些节点应该运行服务任务时,与该首选项匹配的节点的排名会更高。其余因素,如服务的高可用性,也会影响到计划在其中运行服务任务的节点。举个例子,若是你有N个节点带着标签(还有一些其余人),和你的服务配置是要运行N + 1副本,首先将会降N个任务放置到带有rack标签的节点上,而后+ 1将调度到一个并无服务在上面的节点,若是这个节点存在,不管该节点带有rack标签或不带有。

 

REPLICATED OR GLOBAL SERVICES复制或全局服务

集群模式有两种服务类型:复制replicated服务和全局global服务。对于复制的服务,你能够为swarm manager指定要调度到可用节点上的复制任务的数量。对于全局服务,调度器在知足服务的位置约束和资源需求的每一个可用节点上放置一个任务。
使用--mode标志控制服务的类型。若是不指定模式,则服务默认为复制。对于复制的服务,指定要开始使用--replicas标志的复制任务的数量。例如,使用3个复制任务启动一个复制的nginx服务:

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

要在每一个可用节点上启动全局服务,请将--mode global传递给docker service create。每当新节点可用时,调度器将全局服务的任务放置在新节点上。例如,启动一个在群中的每一个节点上运行alpine的服务:

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

服务约束容许你在调度程序将服务部署到节点以前为节点设置要知足的条件。你能够基于节点属性和元数据或引擎元数据对服务应用约束。有关约束的更多信息,请参阅docker service create CLI reference

 

RESERVE MEMORY OR CPUS FOR A SERVICE为服务保留内存或cpu

若要为服务保留给定的内存或cpu数量,请使--reserve-memory或--reserve-cpu标志。若是没有可用的节点能够知足需求(例如,若是你请求4个cpu,而集群中没有节点有4个cpu),则服务将保持挂起状态,直到有合适的节点能够运行其任务为止。

Out Of Memory Exceptions (OOME)

若是你的服务试图使用比群集节点可用的内存更多的内存,那么你可能会遇到内存不足异常(OOME),内核OOM杀手可能会杀死容器或Docker守护进程。要防止这种状况发生,请确保你的应用程序在具备足够内存的主机上运行,查看 Understand the risks of running out of memory.
Swarm服务容许你使用资源约束、位置首选项和标签来确保你的服务被部署到适当的Swarm节点。

 

PLACEMENT CONSTRAINTS位置约束

使用位置约束来控制能够分配给服务的节点。在下面的示例中,服务仅在标签region设置为east的节点上运行。若是没有适当标记的节点可用,任务将在Pending中等待,直到它们可用为止。--constraint标志使用一个等式运算符(== or !=)。对于复制的服务,可能全部服务都运行在相同的节点上,或者每一个节点只运行一个副本,或者一些节点不运行任何副本。对于全局服务,服务在知足位置约束和任何资源需求的每一个节点上运行。

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

你还能够在docker-compose.yml文件中使用constraint服务级别键。
若是指定多个放置约束,则服务只部署到全部节点都知足的节点上。下面的示例将服务限制为在全部节点上运行,其中region设置为east, type设置为devel:

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

还能够将位置约束与位置首选项和CPU/内存约束结合使用。注意不要使用不可能完成的设置。
有关约束的更多信息,请参阅docker service create CLI reference

 

PLACEMENT PREFERENCES位置首选项

虽然位置约束限制了服务能够在其上运行的节点,可是位置首选项尝试以算法的方式将服务放置在适当的节点上(目前,仅平均分布)。例如,若是你为每一个节点分配一个rack标签,那么你能够设置一个位置首选项,经过值将服务均匀地分布到带有rack标签的节点上。这样,若是你丢失了一个rack,服务仍然在其余rack上的节点上运行。
位置首选项不严格执行。若是没有节点具备你在首选项中指定的标签,则会像未设置首选项同样部署服务。
全局服务忽略位置首选项。
下面的示例设置了一个首选项,根据datacenter标签的值将部署分散到节点上。若是某些节点具备datacenter=us-east,而其余节点具备datacenter=us-west,则服务在这两组节点之间尽量均匀地部署。

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

⚠️Missing or null labels

缺乏用于扩展的标签的节点仍然接收任务分配。做为一个组,这些节点接收任务的比例与由特定标签值标识的任何其余组相同。从某种意义上说,缺失的标签等同于标签上附加了一个空null值。若是服务应该只在使用spread首选项的标签的节点上运行,则应该将首选项与约束结合起来。

你能够指定多个位置首选项,并按照遇到的顺序处理它们。下面的示例设置具备多个位置首选项的服务。任务首先分布在各个datacenters,而后分布在rack上(如各自的标签所示):

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

还能够将位置首选项与位置约束或CPU/内存约束结合使用。注意不要使用不可能完成的设置。
这个图表说明了如何放置首选项工做:

当使用docker service update更新服务时,--placater -pref-add在全部现有的放置首选项以后追加一个新的放置首选项。--placater-pref-rm删除与参数匹配的现有位置首选项。

 

Configure a service’s update behavior配置服务的更新行为

在建立服务时,能够指定一个滚动更新行为,说明在运行docker service update时集群应该如何将更改应用于服务。你还能够将这些标志指定为更新的一部分,做为docker service update的参数。
--update-delay标志配置服务任务或任务集更新之间的时间延迟。你能够将时间T描述为Ts秒数、Tm分钟数或Th小时数的组合。因此10m30s表示10分30秒的延迟。
默认状况下,调度程序每次更新一个任务。你能够传递--update-parallelism标志来配置调度程序同时更新的服务任务的最大数量。

当对单个任务的更新返回RUNNING的状态时,调度器将继续更新,方法是继续到另外一个任务,直到全部任务都被更新。若是在更新期间某个任务返回FAILED,调度程序将暂停更新。你可使用docker service create或docker service update的--update-failure-action标志来控制行为。

在下面的示例服务中,调度器每次最多应用两个副本的更新。当更新后的任务返回RUNNING或FAILED时,调度器将等待10秒后中止下一个任务更新:

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

--update-max-failure-ratio标志控制在整个更新被认为失败以前的更新过程当中有多少任务会失败。例如,使用--update-max-failure-ratio 0.1 --update-failure-action pause,在更新的任务中有10%失败后,更新将暂停。

若是任务没有启动,或者在--update-monitor标志指定的监视周期内中止运行,则认为单个任务更新失败。--update-monitor的默认值是30秒,这意味着在任务启动后的前30秒内失败的任务将计入服务更新失败阈值,而启动后的失败则不计入。

 

Roll back to the previous version of a service回滚到服务的上一个版本

若是服务的更新版本没有如预期那样发挥做用,可使用docker service update的--rollback标志手动回滚到服务的前一个版本。这将服务恢复到docker service update命令以前的配置。

其余选项能够与--rollback结合使用;例如--update-delay 0s执行回滚,任务之间不存在延迟:

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

在Docker 17.04及更高版本中,能够配置服务,以便在服务更新部署失败时自动回滚。参见Automatically roll back if an update fails
与新的自动回滚特性相关的是,在Docker 17.04及更高版本中,若是守护进程运行Docker 17.04或更高版本,则手动回滚将在服务器端处理,而不是在客户端处理。这容许手动启动的回滚尊从新的回滚参数。客户机是版本敏感的,所以它仍然对较旧的守护进程使用旧方法。
最后,在Docker 17.04及更高版本中,--rollback不能与Docker服务更新的其余标志一块儿使用。

 

Automatically roll back if an update fails若是更新失败则自动回滚

你能够这样配置服务:若是对服务的更新致使从新部署失败,服务能够自动回滚到上一个配置。这有助于保护服务可用性。你能够在服务建立或更新时设置如下一个或多个标志。若是没有设置值,则使用默认值。

Flag Default Description
--rollback-delay 0s 指定在回滚一个任务以后等待的时间,而后再回滚下一个任务。值0表示在第一个回滚任务部署以后当即回滚第二个任务。
--rollback-failure-action pause 当一个任务没法回滚时,是暂停仍是继续尝试回滚其余任务。
--rollback-max-failure-ratio 0 回滚期间容忍的失败率,指定为0到1之间的浮点数。例如,给定5个任务,.2的失败率将容许一个任务(0.2*5=1)不能回滚。值为0表示不容许出现故障,值为1表示容许出现任意数量的故障。
--rollback-monitor 5s 每一个任务回滚后的持续时间,以监视失败状况。若是任务在此时间段结束以前中止,则认为回滚失败。
--rollback-parallelism 1 并行回滚的最大任务数。默认状况下,一次回滚一个任务。值0将致使并行回滚全部任务。

下面的示例将redis服务配置为在docker service update部署失败时自动回滚。两个任务能够并行回滚。在回滚以后,将对任务进行20秒的监视,以确保它们不退出,而且容许最大失败率为20%。默认值用于--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

 

Give a service access to volumes or bind mounts授予服务访问卷或绑定挂载的权限

为了得到最佳的性能和可移植性,应该避免将重要数据直接写入容器的可写层,而是使用数据量或绑定挂载。这个原则也适用于服务。

你能够为群集中的服务建立两种类型的挂载,volume挂载或bind挂载。不管使用哪一种类型的挂载,在建立服务时使用--mount标志配置它,在更新现有服务时使用--mount-add或--mount-rm标志配置它。若是不指定类型,默认值是一个数据卷。

DATA VOLUMES数据卷

数据卷是独立于容器存在的存储。集群服务下的数据量的生命周期相似于容器下的生命周期。卷的寿命比任务和服务长,所以它们的删除必须单独管理。能够在部署服务以前建立卷,或者在部署任务时,若是在特定主机上不存在卷,则根据服务上的卷规范自动建立卷。
要将现有数据卷与服务一块儿使用,请使用--mount标志:

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

若是在将任务调度到特定主机时,不存在具备相同<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>

有关如何建立数据卷和使用卷驱动程序的更多信息,请参见 Use volumes.

 

BIND MOUNTS绑定挂载

绑定挂载是来自调度程序为任务部署容器的主机的文件系统路径。Docker将路径装载到容器中。在集群初始化任务的容器以前,文件系统路径必须存在
下面的例子展现了绑定挂载语法:

  • 要挂载读写绑定:
$ 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>

重要提示:绑定挂载可能有用,但也可能致使问题。在大多数状况下,建议你对应用程序进行架构设计,以免从主机挂载路径。主要风险包括:

  • 若是将主机路径绑定到服务容器中,则该路径必须存在于每一个群集节点上。Docker群模式调度程序能够在任何知足资源可用性要求并知足你指定的全部约束和位置首选项的机器上调度容器。
  • 若是运行中的服务容器变得不健康或没法访问,Docker群模式调度程序可能会在任什么时候候从新调度它们。
  • 主机绑定安装是不可移植的。在使用绑定挂载时,不能保证应用程序在开发中以与在生产中相同的方式运行。

 

Create services using templates使用模版建立服务

你可使用Go的文本/模板包提供的语法,为service create的一些标志使用模板。
支持如下标志:

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

Go模板的有效占位符以下:

Placeholder Description
.Service.ID Service ID
.Service.Name Service name
.Service.Labels Service labels
.Node.ID Node ID
.Node.Hostname Node hostname
.Task.Name Task name
.Task.Slot Task slot

TEMPLATE EXAMPLE模版例子

这个示例根据服务的名称和运行容器的节点的ID设置建立的容器的模板:

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

要查看使用模板的结果,请使用docker service ps和docker 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
相关文章
相关标签/搜索