docker service

  1. he container

按指定参数所述创建服务。这个命令必须运行在manager节点上。

示例

创建一个服务

  1. $ docker service create --name redis redis:3.0.6
  2. dmu1ept4cxcfe8k8lhtux3ro3
  3.  
  4. $ docker service ls
  5. ID            NAME   REPLICAS  IMAGE        COMMAND
  6. dmu1ept4cxcf  redis  1/1       redis:3.0.6

创建一个5个副本任务的服务(–replicas)

使用–replicas参数设置副本服务的副本任务数。下面的命令创建一个5个副本任务的redis服务:

  1. $ docker service create --name redis --replicas=5 redis:3.0.6
  2. 4cdgfyky7ozwh3htjfw0d12qv

上面的命令设置了服务期望的任务数。虽然命令立即返回了,实际上完成服务部署需要一定的时间。REPLICAS列显示了实际上部署的和期望部署的副本任务数。

下面的示例中期望的副本数是5,不过副本运行的任务数是3:

  1. $ docker service ls
  2. ID            NAME    REPLICAS  IMAGE        COMMAND
  3. 4cdgfyky7ozw  redis   3/5       redis:3.0.7

一旦创建了所有的任务且为RUNNING状态,任务的实际数量就等于期望的数量:

  1. $ docker service ls
  2. ID            NAME    REPLICAS  IMAGE        COMMAND
  3. 4cdgfyky7ozw  redis   5/5       redis:3.0.7

指定滚动更新策略创建一个服务

  1. $ docker service create \
  2.   --replicas 10 \
  3.   --name redis \
  4.   --update-delay 10s \
  5.   --update-parallelism 2 \
  6.   redis:3.0.6

当执行上面的service update命令时,调度器同时更新最大2个任务,间隔更新时间为10s。

设置环境变量(-e,–env)

为在一个服务中的所有任务设置环境变量。例如:

  1. $ docker service create --name redis_2 --replicas 5 --env MYVAR=foo redis:3.0.6

设置服务的metadata(-l,–label)

一个label是key=value键值对应用到服务的元数据。要为服务设置两个labels,执行:

  1. $ docker service create \
  2.   --name redis_2 \
  3.   --label com.example.foo="bar"
  4.   --label bar=baz \
  5.   redis:3.0.6

添加bind-mounts或volumes

docker支持两种不同的挂载,允许容器从其他容器或主机操作系统上的文件或目录读取或写入。这些类型是data volumes和bind-mounts。

bind-mount容器可以直接操作主机上的文件。bind-mount可以是只读或读写。例如,一个容器可能通过绑定挂载主机的/etc/resolv.conf来共享主机的DNS信息或一个容器可能写入日志到主机的/var/log/myContainerLogs目录。如果使用了bind-mounts且你的主机与容器有不同的权限概念,访问控制或其它这样的信息,你可能会遇到可移植性的问题。

一个命名数据卷是从用于创建容器的镜像和主机分离出容器所需的持久化数据的一个机制。命名数据卷由docker创建和管理,即使当没有容器使用它时,一个命名数据卷仍然会存在。在命名数据卷的数据可以在容器和主机之间共享,也可以在多个容器之间共享。docker使用一个数据卷驱动来创建,管理和挂载数据卷。可以使用docker的相关命令备份或恢复数据卷。

考虑这样一个情景,你有一个镜像是用来启动一个轻量级的web server的,然后你用这个镜像作为base镜像,把网站的HTML文件复制到这个镜像。每个网站有更新时,你需要更新这个镜像并重新部署容器。一个更好的解决方案是把网站存储到一个命名数据卷中,当容器启动时这个数据卷就会附着到你的web server。要更新这个网站,只需要更新命名数据卷。

下面的表格是应用到bind-mounts和named volumes的选项:

选项 必要 描述
type   mount的类型,可以是volume或bind。如果不指定type,默认是volume。

volume: 挂载一个数据卷到容器中。bind: 从主机绑定挂载一个目录或文件到容器中。
src或source 用在当type=bind时 type=volume: src是指定数据卷名称的可选的一种方式(例如,src=my-volume)。如果命名数据卷不存在,则docker会自动创建它。如果没有指定src,则分配一个随机的名称给数据卷,并保证这个名称在主机上是唯一的,不过可能在集群范围不是唯一的。一个随机命名数据卷与容器有相同的生命周期,当容器被销毁时此数据卷也将销毁(销毁取决于service update或当scaling或重新负载均衡服务时)。type=bind: src是必须的,并需要指定文件或目录的绝对路径(例如src=/path/on/host/)。如果文件或目录不存在将会报错。
dst 或 destination 或 target 容器内挂载的路径。例如/some/path/in/container/。如果在容器文件系统不存在这个路径,engine将在挂载数据卷或绑定挂载之前先创建这个目录。
readonly 或 ro   Engine挂载绑定和数据卷默认是读写的,除非设置了readonly选项。

true或1或no:挂载绑定或数据卷只读。false或0: 挂载绑定或数据卷读写。

绑定传播(Bind Propagation)

绑定传播指的是在给定的绑定挂载或命名数据卷内创建的挂载是否可以传播到那个挂载的副本。如一个挂载点/mnt,也挂载到/tmp上。传播设置控制在/tmp/a的挂载是否也挂载到/mnt/a。每个传播设置具有递归对应点。在递归情况下,假设/tmp/a也挂载为/foo。传播设置控制/mnt/a和/或/tmp/a是否存在。

bind-mounts和volume mounts的bind-propagation选项的默认值为rprivate,并只能对bind-mounts可设置。换句话说,命名数据卷不支持绑定传播。

shared: 原始挂载的子挂载暴露给副本挂载,副本挂载的子挂载也传播到原始挂载。 slave:与shared挂载类似,不过只有一个方向。如果原始挂载暴露一个子挂载,副本挂载可以看到。不过,如果副本挂载暴露一个子挂载,原始挂载无法看到。 private:挂载是私有的。在它之内的子挂载不暴露给副本挂载,且副本挂载的子挂载不暴露给原始挂载。 rshared:与shared一样,但传播也扩展到嵌套在任何原始或复制挂载点内的挂载点。 rslave:与slave相同,但是传播也延伸到嵌套在任何原始或复制挂载点内的挂载点。 rprivate:默认值。与private相同,意味着原始或复制挂载点内任何地方的任何挂载点都不会在任一方向传播。

更多信息请查看sharedsubtree。

命名数据卷选项

下面的选项只能用于命名数据卷(type=volume)。

选项 描述
volume-driver 数据卷所使用的数据卷驱动插件名称。默认为local,使用local数据卷驱动时当数据卷不存在时会自动创建。
volume-label 创建数据卷时应用给它的一个或多个自定义元数据(“labels”)。例如,volume-label=mylabel=hello-world,my-other-label=hello-mars。
volume-nocopy 默认下,如果附着一个空的数据卷到一个容器,在容器的挂载路径已经存在的文件或目录,Engine将复制这些文件和目录到数据卷中。设置vloume-nocopy将禁止从容器的文件系统复制文件到挂载的空数据卷。
值是可选的:

true或1: 这是默认值。禁止复制。
false或0: 启用复制。 volume-opt 给定数据卷驱动的特定选项,当创建数据卷时将传递给驱动。选项格式为以逗号分隔的键/值对列表,例如volume-opt=some-option=some-value,some-other-option=some-other-value。

“–mount”和”–volume”的异同

–mount选项支持docker run的-v或–volume的大多数选项。除了一些重要的例外:

–mount标志可以为每一个数据卷指定一个数据卷驱动及其选项,而不需要提供创建好数据卷。相比之一,docker run使用–volume-driver指定一个用于所有数据卷的数据卷驱动。 –mount标志允许你在数据卷创建前为数据卷指定自定义的元数据(“labels”) 当–mount和type=bind一起使用时,host-path必须对应到一个主机上存在的路径。不会为你自动创建路径且当路径不存在时服务创建将失败。 –mount标志不允许使用Z或z重新label数据卷,因为这个已经用于selinux了。

使用一个命名数据卷创建服务

下面的示例使用一个命名数据卷来创建服务:

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

对于服务的每一个副本,engine从部署任务上的默认的”local”数据卷驱动请求一个名称为”my-volume”的数据卷。如果数据卷不存在,engine就创建一个新的并应用”color”和”shape” labels。

当任务启动后,数据卷挂载到容器内的/path/in/container。

要注意那个默认的”local”数据卷是本地范围的数据卷驱动。意思是使用哪里的驱动取决于任务部署的位置。如果运行在容器内的软件没有设计为写入数据到相同位置的并发进程,那么多个容器同时写入单个共享数据卷可能会损坏数据。同时也要考虑容器可能会被swarm编排器重新调度并部署到一个不同的节点。

使用匿名数据卷创建服务

下面的命令使用一个挂载到/path/in/container的匿名数据卷创建一个3个副本的服务:

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

在这个示例中,没有为数据卷指定[source],所以每个任务将创建一个新的数据卷。这保证了每个任务能得到它自己的数据卷且不会与其它任务共享数据卷。当任务被删除时,匿名数据卷同样将被删除。

使用绑定挂载(bind-mounted)主机目录创建服务

下面的示例在容器内的/path/in/container绑定挂载主机的目录/path/on/host:

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

设置服务模式

服务模式决定着这是副本服务还是全局服务。一个副本服务指定数量的任务,而全局服务在集群中的每个活跃节点都运行任务。
下面的命令创建了一个全局服务:

  1. $ docker service create \
  2.  --name redis_2 \
  3.  --mode global \
  4.  redis:3.0.6

指定服务约束(–constraint)

可以通过定义约束表达式来限制可用于任务调度的节点。多个约束查找节点时,需要满足每个表达式(AND匹配)。 约束可以匹配节点或docker engine的labels,如下:

节点属性 匹配 示例
node.id 节点ID node.id == 2ivku8v2gvtg4
node.hostname 节点主机名 node.hostname != node-2
node.role 节点角色:manager node.role == manager
node.labels 用户定义节点labels node.labels.security == high
engine.labels Docker Engine的labels engine.labels.operatingsystem == ubuntu 14.04

engine.labels匹配docker engine的lables,如操作系统,驱动等。集群管理员通过使用docker node update命令来添加node.labels以更好使用节点。

例如,下面的示例限制redis服务的任务只能部署到那么节点的label type等于queue的节点:

  1. $ docker service create \
  2.   --name redis_2 \
  3.   --constraint 'node.labels.type == queue' \
  4.   redis:3.0.6

添加一个服务到一个现有的网络(–network)

可以使用overlay网络在集群内连接一个或多个服务。

首先在manager节点上执行docker network create命令创建一个overlay网络:

  1. $ docker network create --driver overlay my-network
  2.  
  3. etjpu59cykrptrgw0z0hk5snf

当在swarm模式中创建了一个overlay网络,那么所有的manager节点都已经在这个网络中的。

当创建一个服务然后传递–network参数来添加服务到这个overlay网络:

  1. $ docker service create \
  2.   --replicas 3 \
  3.   --network my-network \
  4.   --name my-web \
  5.   nginx
  6.  
  7. 716thylsndqma81j6kkkb5aus

swarm则扩展my-network到运行着这个服务的每一个节点。

发布服务端口到集群外部(-p,–publish)

可以使用–publish参数来把服务端口发布到集群外部:

  1. $ docker service create --publish : nginx

例如:

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

当发布一个服务端口时,集群路由网使服务在每个节点的目标端口可访问,不管这个运行中的节点是否有服务的任务。

只发布一个TCP端口或UDP端口

默认下,当发布一个端口时,它是一个TCP端口。可以指定发布一个UDP端口,而不是或额外的TCP端口。当发布TCP和UDP两个端口时,Docker 1.12.2或之前的版本需要为TCP端口添加前缀/tcp。否则它是可选的。

TCP only

下面两个命令是等同的。

  1. $ docker service create --name dns-cache -p 53:53 dns-cache
  2.  
  3. $ docker service create --name dns-cache -p 53:53/tcp dns-cache

TCP和UDP

  1. $ docker service create --name dns-cache -p 53:53/tcp -p 53:53/udp dns-cache

UDP only

  1. $ docker service create --name dns-cache -p 53:53/udp dns-cache

你可能感兴趣的:(docker)