Docker-管理设计模式-四-

152 阅读13分钟

Docker 管理设计模式(四)

原文:Docker Management Design Patterns

协议:CC BY-NC-SA 4.0

十二、负载均衡

Docker 群模式服务提供了一种可以跨节点集群扩展的分布式应用。群模式基于服务的 DNS 名称在群中的不同服务之间提供内部负载均衡。如果服务在主机端口上发布,群模式还在服务的不同任务之间提供入口负载均衡。此外,可以使用放置约束在特定节点上调度服务任务。

服务发现

一个群有一个嵌入其中的 DNS 服务器。服务发现基于 DNS 名称。群管理器为群中的每个服务分配一个唯一的 DNS 名称条目。Swarm manager 使用内部负载均衡,根据服务的 DNS 名称为群中的不同服务分配请求。

自定义计划

默认情况下,服务副本使用分散调度策略在集群中的节点上进行调度。用户可以为服务配置放置约束,以便在特定节点上调度副本。第六章讨论了使用约束的调度。

入口负载均衡

默认情况下,在发布的端口上为外部访问公开的每个服务都被添加到ingress覆盖网络中。用户可以使用--publish-p选项指定任何可用的端口来公开服务。--publish ( -p)选项的语法是--publish <PublishedPort>:<TargetPort>,其中<PublishedPort>变量用于主机上发布的端口,<TargetPort>变量用于容器端口。如果--publish-p选项没有指定<PublishedPort>端口来在群上发布服务,管理器自动在从范围 30000-32767 中选择的发布端口上公开服务。

问题

入口负载均衡用于在服务任务之间分配负载,即使群由单个节点组成也要使用。图 12-1 显示了多节点集群的入口负载均衡。客户端可以访问群中的任何节点,无论该节点是否调度了服务任务,并且使用入口负载均衡将客户端请求转发到服务任务之一。

A454123_1_En_12_Fig1_HTML.gif

图 12-1。

Ingress load balancing

单个客户端访问单个节点,结果,在跨群节点分布外部客户端负载方面,群未被充分利用。客户端负载在群节点之间并不均衡。单个节点不提供任何容错。如果该节点出现故障,访问该节点服务的外部客户端将无法使用该服务。

解决方案

AWS 弹性负载均衡器(ELB)用于在多个 EC2 实例之间分配客户端负载。当用于 Docker 群模式时,AWS 弹性负载均衡器将客户端负载分布在托管群节点的不同 EC2 实例上。外部负载均衡器使用 LB 监听器访问(监听)群中运行的服务的发布端口处的每个 EC2 实例上的群。每个 LB 侦听器都有一个 LB 端口映射到每个 EC2 实例上的一个实例端口(服务的发布端口)。蜂群中的 ELB 如图 12-2 所示。

A454123_1_En_12_Fig2_HTML.gif

图 12-2。

External load balancer

由于即使单个节点停机或变得不可用,客户端也不访问单个主机上的服务,所以群不会变得不可用,因为外部负载均衡器将客户端请求定向到群中的不同节点。即使所有节点都可用,客户端流量也会分布在不同的节点上。例如,客户端可能在特定时间从一个节点接受服务,此后不久从另一个节点接受服务。因此,外部负载均衡器提供两种功能:负载均衡和容错。此外,托管群的云提供商可以提供额外的功能,如安全和灵活的外部负载均衡。AWS 弹性负载均衡器提供的弹性负载均衡根据客户端流量来调整请求处理能力。

本章讨论 CoreOS 上用户创建的 Swarm 的负载均衡。它还讨论了 Docker 上为 AWS 托管服务自动提供的弹性负载均衡器。

设置环境

启动三个 CoreOS 实例——一个用于管理节点,两个用于工作节点——如图 12-3 所示。从 EC2 仪表板中获取 manager 实例的公共 IP 地址,如图 12-3 所示。

A454123_1_En_12_Fig3_HTML.jpg

图 12-3。

CoreOS instances on EC2 for a manager and two worker nodes

SSH 登录到管理器节点以启动群组模式。在第二章中讨论了在 CoreOS 上初始化一个群组模式以及将工人节点加入群组。复制docker swarm join命令输出,将工作者节点加入到群中。用docker node ls命令列出群节点。

core@ip-10-0-0-226 ∼ $ docker node ls
ID                          HOSTNAME                    STATUS  AVAILABILITY  MANAGER STATUS
9iqh5tg7hxy8u43tlifd1ri0q   ip-10-0-0-203.ec2.internal  Ready   Active        
aoe1b2623qj03852mrc5cax97   ip-10-0-0-198.ec2.internal  Ready   Active        
dsyo3b6553ueishozhfb1apad * ip-10-0-0-226.ec2.internal  Ready   Active        Leader

创建 Hello World 服务

接下来,用docker service create命令创建一个 hello world 服务。使用--publish选项在端口 8080 公开服务。使用--publish-p发布服务的语法如下。

docker service create \
  --name <SERVICE-NAME> \
  --publish <PUBLISHED-PORT>:<TARGET-PORT> \
  <IMAGE>

<PUBLISHED-PORT>是主机上公开的端口,而<TARGET-PORT>是 Docker 容器公开服务的端口。使用tutum/hello-world Docker 映像、<PUBLISHED-PORT>作为 8080、<TARGET-PORT>作为 80、<SERVICE-NAME>作为hello-world,运行下面的命令来创建服务。

core@ip-10-0-0-226 ∼ $ docker service create \

>   --name hello-world \

>   --publish 8080:80 \

>   --replicas 3 \

>   tutum/hello-world
0gk3wom7z91fpm5o9e6optmb5

服务被添加到入口覆盖网络,并且服务被展示在群上的每个节点处,无论服务任务是否正在该节点上运行。hello-world服务列出了 3/3 的副本。

core@ip-10-0-0-226 ∼ $ docker service ls
ID            NAME         REPLICAS  IMAGE              COMMAND
0gk3wom7z91f  hello-world  3/3       tutum/hello-world  

使用docker service ps hello-world命令列出服务任务,三个任务按计划列出,每个节点一个。

core@ip-10-0-0-226 ∼ $ docker service ps hello-world
ID                         NAME           IMAGE              NODE                        DESIRED STATE  CURRENT STATE           ERROR
di5oilh96jmr6fd5haevkkkt2  hello-world.1  tutum/hello-world  ip-10-0-0-198.ec2.internal  Running        Running 24 seconds ago  
5g5d075yib2td8466mh7c01cz  hello-world.2  tutum/hello-world  ip-10-0-0-226.ec2.internal  Running        Running 24 seconds ago  
5saarf4ngju3xr7uh7ninho0o  hello-world.3  tutum/hello-world  ip-10-0-0-203.ec2.internal  Running        Running 23 seconds ago  

一个 Docker 容器正在 manager 节点上运行。

core@ip-10-0-0-226 ∼ $ docker ps
CONTAINER ID   IMAGE                      COMMAND                  CREATED             STATUS              PORTS               NAMES
b73cbcd0c37e   tutum/hello-world:latest   "/bin/sh -c 'php-fpm "   34 seconds ago      Up 32 seconds       80/tcp              hello-world.2.5g5d075yib2td8466mh7c01cz

一个 Docker 容器正在一个 worker 节点上运行。

core@ip-10-0-0-198 ∼ $ docker ps
CONTAINER ID   IMAGE                      COMMAND                  CREATED             STATUS              PORTS               NAMES
8bf11f2df213   tutum/hello-world:latest   "/bin/sh -c 'php-fpm "   38 seconds ago      Up 36 seconds       80/tcp              hello-world.1.di5oilh96jmr6fd5haevkkkt2

第三个 Docker 容器运行在另一个工作节点上。

core@ip-10-0-0-203 ∼ $ docker ps
CONTAINER ID   IMAGE                      COMMAND                  CREATED             STATUS              PORTS               NAMES
a461bfc8d4f9   tutum/hello-world:latest   "/bin/sh -c 'php-fpm "   40 seconds ago      Up 38 seconds       80/tcp              hello-world.3.5saarf4ngju3xr7uh7ninho0o

调用 Hello World 服务

在没有外部负载均衡器的情况下,可以在发布端口的每个节点处建立入口连接。要调用管理器节点的服务,从 EC2 控制台获取 Swarm manager 实例的公共 DNS,如图 12-3 所示。

在 web 浏览器中调用位于<PublicDNS>:<PublishedPort> URL 的服务,如图 12-4 所示。

A454123_1_En_12_Fig4_HTML.jpg

图 12-4。

Invoking the service in a browser

类似地,要在 worker 节点调用服务,从 EC2 控制台获取 worker 实例的公共 DNS,并在 web 浏览器的<PublicDNS>:<PublishedPort> URL 调用服务,如图 12-5 所示。

A454123_1_En_12_Fig5_HTML.jpg

图 12-5。

Invoking the service at a worker node

类似地,要在另一个 worker 节点调用服务,从 EC2 控制台获取 worker 实例的公共 DNS,并在 web 浏览器中的<PublicDNS>:<PublishedPort> URL 调用服务,如图 12-6 所示。

A454123_1_En_12_Fig6_HTML.jpg

图 12-6。

Invoking the service at the other worker node

外部 AWS 弹性负载均衡器在 EC2 实例之间分配负载,而入口负载均衡器在服务任务之间分配负载。在前面的例子中,当在群管理器实例和群工作器实例调用服务时,调用相同的服务任务,如相同的主机名所示(图 12-4 和 12-6 )。这演示了入口负载均衡。

如果在同一主机上调用服务,则可能会调用不同的服务任务。例如,再次调用 Swarm manager 实例上的服务。服务于不同的服务任务,如图 12-7 中不同的主机名所示。这与之前在图 12-4 中提供的主机名进行了比较,再次证明了入口负载均衡。

A454123_1_En_12_Fig7_HTML.jpg

图 12-7。

Different hostname served when invoking the service at the manager node again

创建外部弹性负载均衡器

在本节中,我们将在 AWS 云上创建一个外部弹性负载均衡器。单击 EC2 仪表板中的负载均衡器。然后点击 Create Load Balancer 创建一个新的负载均衡器,如图 12-8 所示。

A454123_1_En_12_Fig8_HTML.jpg

图 12-8。

Creating a new load balancer

AWS 弹性负载均衡提供两种类型的负载均衡器——经典负载均衡器和应用负载均衡器。传统负载均衡器基于应用或网络级别的信息路由流量,而应用负载均衡器基于高级应用级别的信息路由流量。经典的负载均衡器应该能够满足对多个 EC2 实例的流量进行最简单的负载均衡,并且是我们用于 Docker Swarm 实例的负载均衡器。选择经典负载均衡器,然后点击继续,如图 12-9 所示。

A454123_1_En_12_Fig9_HTML.jpg

图 12-9。

Selecting the classic load balancer option

在定义负载均衡器对话框中,指定一个负载均衡器名称(HelloWorldLoadBalancer),并选择一个 VPC 在其中创建负载均衡器,如图 12-10 所示。VPC 必须在创建负载均衡器之前存在,并且必须是创建要进行负载均衡的 EC2 实例的位置。默认情况下,负载均衡器协议是 HTTP,实例协议也是。保留 HTTP 协议的默认设置,将负载均衡器端口和实例端口指定为 8080,因为 Hello World 服务在端口 8080 公开。

A454123_1_En_12_Fig10_HTML.jpg

图 12-10。

Selecting the load balancer protocol

在选择子网选项卡中,单击可用子网表中列出的一个或多个子网。子网被添加到选中的子网中,如图 12-11 所示。点击下一步。要提供高可用性,请在不同的可用性区域中至少选择两个子网。

A454123_1_En_12_Fig11_HTML.jpg

图 12-11。

Selecting subnets

在分配安全组选项卡中,选择创建新的安全组,如图 12-12 所示。在类型中,选择自定义 TCP 规则。选择 TCP 协议和端口范围 8080。选择任意位置作为源,其值为 0.0.0.0/0。点击下一步。

A454123_1_En_12_Fig12_HTML.jpg

图 12-12。

Assigning security groups

单击“配置安全设置”中的“下一步”,因为我们没有使用 HTTPS 或 SSL 协议。在配置运行状况检查选项卡中,为 ping 协议选择 HTTP,为 ping 端口选择 8080。指定 ping 路径为/,如图 12-13 所示。在“高级详细信息”区域保留默认值,然后单击“下一步”。

A454123_1_En_12_Fig13_HTML.jpg

图 12-13。

Configuring a health check

选择列出的三个 Swarm 实例,如图 12-14 所示。另外,选择启用跨区域负载均衡,这将在所有可用性区域中的所有后端实例之间平均分配流量。点击下一步。

A454123_1_En_12_Fig14_HTML.jpg

图 12-14。

Adding EC2 instances

在“添加标签”选项卡中,不需要添加任何标签。在审核选项卡中,点击创建,如图 12-15 所示。如上所述,负载均衡器是面向互联网的类型。

A454123_1_En_12_Fig15_HTML.jpg

图 12-15。

Review your settings then create the load balancer

负载均衡器创建完成,如图 12-16 所示。

A454123_1_En_12_Fig16_HTML.jpg

图 12-16。

The load balancer has been created

从 EC2 控制台获取负载均衡器的 DNS 名称,如图 12-17 所示。最初,状态将是“3 个实例中的 0 个在服务中”,因为注册仍在进行中。

A454123_1_En_12_Fig17_HTML.jpg

图 12-17。

Obtaining the DNS name of the load balancer

过一会儿,状态应该变成“3 个实例中的 3 个在服务中”,所有实例都应该在服务中,如图 12-18 所示。

A454123_1_En_12_Fig18_HTML.jpg

图 12-18。

Status indicates three of three instances InService

Hello World 服务可以从 web 浏览器中的<DNSname>:<LoadBalancerPort> URL 调用,如图 12-19 所示。

A454123_1_En_12_Fig19_HTML.jpg

图 12-19。

Invoking the Hello World service

外部弹性负载均衡器平衡集群中 EC2 实例之间的负载。因为入口负载均衡器在不同的服务任务之间平衡负载,如果在 ELB DNS 名称上再次调用服务,则可能会调用不同的服务任务,如图 12-20 所示。

A454123_1_En_12_Fig20_HTML.jpg

图 12-20。

Different service task served

AWS Docker 中的负载均衡

虽然在使用命令行创建 Docker 群组时必须创建外部弹性负载均衡器(首先启动群组模式,然后将工作节点加入群组),但在第三章中介绍的 AWS 托管服务 Docker 会自动创建弹性负载均衡器。

使用 Docker for AWS 创建一个有三个管理器节点和五个工作者节点的 Swarm(之前创建的 Swarm 可能会被更新),如图 12-21 所示。如图 12-21 中的资源选项卡所示,创建一个外部弹性负载均衡器作为群资源之一。

A454123_1_En_12_Fig21_HTML.jpg

图 12-21。

CloudFormation stack for a Docker Swarm

创建一个面向互联网的弹性负载均衡器,如图 12-22 所示。负载均衡器的公共 DNS 可以用于访问群,如后面所讨论的。

A454123_1_En_12_Fig22_HTML.jpg

图 12-22。

Load balancer for the Swarm created with Docker for AWS

选择“实例”选项卡。列出了群中的所有实例,经理或工人。所有的实例都应处于使用状态,如图 12-23 所示。

A454123_1_En_12_Fig23_HTML.jpg

图 12-23。

Instances status is InService

更新 listeners 选项卡中的负载均衡器侦听器,添加/修改一个侦听器,其负载均衡器端口设置为 8080,实例端口设置为 8080,这是我们创建的 Hello World 服务的发布端口,如图 12-24 所示。

A454123_1_En_12_Fig24_HTML.jpg

图 12-24。

The Listeners tab

从 EC2 控制台获取其中一个管理器节点的公共 IP 地址。

SSH 登录到管理器节点。

[root@localhost ∼]# ssh -i "docker.pem" docker@34.205.43.53
Welcome to Docker!

列出群体节点。

∼ $ docker node ls
ID                          HOSTNAME                      STATUS AVAILABILITY MANAGER STATUS
8d0qv1epqu8xop4o2f94i8j40   ip-172-31-8-4.ec2.internal    Ready  Active             
8eckb0twpbuoslfr58lbibplh   ip-172-31-32-133.ec2.internal Ready  Active              
b6f18h4f3o44gkf5dhkzavoy3   ip-172-31-2-148.ec2.internal  Ready  Active              
k9nl2zcmjzobbqu5c5bkd829g   ip-172-31-21-41.ec2.internal  Ready  Active              
p0d70jwh5vpjwximc1cpjfjkp * ip-172-31-1-130.ec2.internal  Ready  Active       Leader
r02ftwtp3n4m0cl7v2llw4gi8   ip-172-31-44-8.ec2.internal   Ready  Active              
rd8d0kksuts3aa07orhgkri3i   ip-172-31-41-86.ec2.internal  Ready  Active       Reachable
xks3sw6qgwbcuacyypemfbxyj   ip-172-31-31-117.ec2.internal Ready  Active       Reachable

创建一个 Hello World 服务,并在端口 8080(发布端口)公开该服务。

∼ $ docker service create \

>   --name hello-world \

>   --publish 8080:80 \

>   --replicas 10 \

>   tutum/hello-world
n4hmfognhjrasf5nhukr55krb

服务任务在整个群体中进行调度。

∼ $ docker service ps hello-world
ID               NAME              IMAGE                      NODE                    DESIRED STATE       CURRENT STATE            ERROR               PORTS
y1fetn3kpwwn     hello-world.1     tutum/hello-world:latest   ip-172-31-2-148.ec2.internalRunning             Running 15 seconds ago                       
5i15zl9dickd     hello-world.2     tutum/hello-world:latest   ip-172-31-44-8.ec2.internalRunning             Running 17 seconds ago                       
k9glaavn0gzg     hello-world.3     tutum/hello-world:latest   ip-172-31-8-4.ec2.internalRunning             Running 17 seconds ago                       
n83f89ijlokn     hello-world.4     tutum/hello-world:latest   ip-172-31-41-86.ec2.internalRunning             Running 17 seconds ago                       
nelf275h9tp1     hello-world.5     tutum/hello-world:latest   ip-172-31-8-4.ec2.internalRunning             Running 16 seconds ago                       
w4c8zcvlq5v7     hello-world.6     tutum/hello-world:latest   ip-172-31-32-133.ec2.internalRunning             Running 17 seconds ago                       
b5qvbbgkrpd5     hello-world.7     tutum/hello-world:latest   ip-172-31-21-41.ec2.internalRunning             Running 16 seconds ago                       
qlm8dt9fuv92     hello-world.8     tutum/hello-world:latest   ip-172-31-31-117.ec2.internalRunning             Running 17 seconds ago                       
t3tenhpahh7g     hello-world.9     tutum/hello-world:latest   ip-172-31-44-8.ec2.internalRunning             Running 17 seconds ago                       
up64ekxqeftk     hello-world.10    tutum/hello-world:latest   ip-172-31-1-130.ec2.internalRunning             Running 17 seconds ago                       

可以在不明确指定发布端口的情况下创建hello-world服务。

∼ $ docker service create \

>   --name hello-world \

>   --publish 80 \

>   --replicas 3 \

>   tutum/hello-world

群组管理器自动分配 30000-32767 范围内的公布端口;默认端口是 30000(如果可用的话)。AWS Swarm Docker 的负载均衡器中的监听器可能需要修改,以便为LoadBalancerPort:ServiceInstancePort添加映射,比如 30000:30000。

获取自动创建的弹性负载均衡器的公共 DNS,如图 12-25 所示。

A454123_1_En_12_Fig25_HTML.jpg

图 12-25。

Obtaining the public DNS of the ELB

在 web 浏览器中访问<PublicDNS>:<PublishedPort>处的服务,如图 12-26 所示。该请求被转发到群中的一个实例上的入口负载均衡器。外部请求转发到的实例不一定要承载服务任务。寻找服务任务是入口负载均衡器的工作。

A454123_1_En_12_Fig26_HTML.jpg

图 12-26。

Accessing a Docker service at the elastic load balancer DNS

摘要

本章讨论了群模式下的负载均衡。入口负载均衡器用于在服务的任务之间分配负载。群中的每个服务被分配一个 DNS 名称,内部负载均衡器基于 DNS 名称在服务之间平衡服务请求。我们还为 AWS EC2 实例创建了一个外部负载均衡器,以便在 EC2 实例之间分配负载。Docker for AWS 会在 AWS 上自动创建一个外部负载均衡器。在下一章,我们将讨论开发一个基于 Docker Swarm 的高可用性网站。

十三、开发高可用性网站

网站的高可用性是指网站持续可用,没有服务中断。通过在 Docker Swarm 应用中提供容错功能,网站变得高度可用。高可用性在不同的级别上提供。入口负载均衡器在多个服务任务之间平衡传入的客户端请求,并在任务级别提供容错。如果一个服务任务失败,客户端流量将被路由到另一个服务任务。为跨多个可用性区域托管的 Docker 群使用外部负载均衡器是提供高可用性的另一种方法。外部负载均衡器在节点级别提供容错。如果一个节点出现故障,客户端流量将被路由到另一个节点上的群节点。

问题

使用外部负载均衡器(如 AWS 弹性负载均衡器)可以在 AWS 区域的多个可用性区域中提供容错能力。客户端主机可以通过其 DNS 名称访问弹性负载均衡器,如图 13-1 所示。Swarm 的可用性不高,因为单个 AWS 区域的故障会导致网站不可用。

A454123_1_En_13_Fig1_HTML.gif

图 13-1。

The elastic load balancer may be accessed at its DNS name by a client host

解决方案

Amazon Route 53 通过各种 DNS 故障转移选项提供高可用性,包括使用别名资源记录集的主动-主动和主动-被动故障转移。Amazon Route 53 提供跨地理上分散的 AWS 区域的 DNS 故障转移,如图 13-2 所示。我们使用 Amazon Route 53 主动-被动故障转移配置,该配置基于负载均衡器 DNS 的主-从架构模式。

A454123_1_En_13_Fig2_HTML.gif

图 13-2。

Amazon Route 53 provides DNS failover across AWS regions

本章涵盖以下主题:

  • 设置环境
  • 创建多个停靠站群
  • 部署 Docker 群服务
  • 创建 AWS 路线 53
  • 创建托管区域
  • 配置名称服务器
  • 创建记录集
  • 测试高可用性
  • 删除托管区域

设置环境

我们使用两个 Docker for AWS 托管集群,为主动-被动 DNS 故障转移配置提供两个 DNS。路由 53 为两个 DNS 提供了主-从架构模式。唯一的先决条件是一个 AWS 帐户,可以在 https://aws.amazon.com/resources/create-account/ 创建。创建一个密钥对(Swarm ),用于 SSH 登录到 Swarm manager 节点,如图 13-3 所示。仅由所有者使用chmod 400 swarm.pem命令将密钥对的权限设置为只读。

A454123_1_En_13_Fig3_HTML.jpg

图 13-3。

Key pair

必须注册域名才能用于创建 Amazon Route 53 托管区域。

创建多个停靠站群

https://docs.docker.com/docker-for-aws/ 使用 AWS 托管服务的 Docker 创建两个 Docker 群组。这两个 Docker 集群必须位于两个不同的 AWS 区域,才能使用地理上分布的 AWS 区域提供的高可用性。创建一个 Docker Swarm Oregon 地区作为例子,如图 13-4 所示。

A454123_1_En_13_Fig4_HTML.jpg

图 13-4。

CloudFormation stack for Docker Swarm

每个 Docker 群都有分布在 AWS 区域中的 AWS 可用性区域的管理器和工作者节点。管理节点的公共 IP 可以从 EC2 控制台获取,如图 13-5 所示。

A454123_1_En_13_Fig5_HTML.jpg

图 13-5。

Obtaining the public IP of the Swarm manager node

使用第一个停靠站群中管理节点的公共 IP 地址,SSH 登录到管理节点 EC2 实例。

[root@localhost ∼]# ssh -i "swarm.pem" docker@54\. 149.86.148

Welcome to Docker!

∼$

以俄亥俄州 AWS 地区创建其他 Docker Swarm 为例,如图 13-6 所示。对于不同的用户,区域可能是不同的。

A454123_1_En_13_Fig6_HTML.jpg

图 13-6。

CloudFormation stack for the Docker Swarm in one region

第二停靠站群的群节点 EC2 实例也分布在第二 AWS 区域中的 AWS 可用性区域,如图 13-7 所示。获取管理器节点的公共 IP。

A454123_1_En_13_Fig7_HTML.jpg

图 13-7。

The Availability Zone column lists multiple zones

SSH 登录到实例。

[root@1oca1.host —]# ssh -i “docker.pem” docker@52.14.23.163
Welcome to Docker!
∼$

用 Docker 节点列出 Docker 群中的群节点。

∼ $ docker node ls

ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS

fncv7ducej3ind4u2sy9xtwi7 ip-172-31-34-223.us-east-2.compute.internal. Ready Active Reachable
grdeu2x49yi2fmvuy9lmoogqg ip-172-31-43-174.us-east-2.compute.internal Ready Active
keOd75qef9bg8t22eqv9spdpm ip-172-31-30-180.us-east-2.compute.internal. Ready Active Reachable
m2mmifbrnjbdriub5r36zxyjc * ip-172-31-8-11.us-east-2.compute.internal Ready Active Leader
qenbfrmsOxv7wom6wpw9yspw4 ip-172-31-27-178.us-east-2.compute.ìnternal Ready Active
tipzy29hgh3m6og5bzkgsego8 ip-172-31-12-37.us-east-2.compute.internal Ready Active
v4xdl4jvthovrzsamujoxy3ju ip-172-31-7-219.us-east-2.compute.internal Ready Active
vuq68yex58vzgx3audj3sm23a ip-172-31-28-182.us-east-2.compute.internal Ready Active

部署 Docker 群服务

接下来,我们部署一个 Hello World 服务,它将被托管在一个网站上。在管理器实例上为DockerSwarm-1 Swarm 运行以下命令,创建一个tutum/hello-world服务,在主机节点的端口 8080 公开两个副本。

docker service create \
  --name hello-world \
  --publish 8080:80 \
  --replicas 2 \
  tutum/hello-world

创建了一个具有两个服务任务的 Docker 服务。

∼ $ docker service create \

> --name hello-world \

> --publish 8080:80 \

> -- replicas 2 \

> tutum/hello-world

vn5fl8h7t65sjwk54dwcoklhu

∼ $ docker service 1s

ID NAME MODE REPLICAS IMAGE

vn5tl8h7t65s hello-world replicated 2/2 tutum/hello-world:latest

∼ $ docker service ps hello-world

ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS

ac9ks5y9duni2 hello-world.l tutum/hello-wor1d:latest ip-172-31-19-220.us-west-2.compute.internal Running Running 13 seconds ago
8s6r48wUui9 hello-world.2 tutum/hello-world:latest ip-172-31-24-250.us-west-2.compute.internal Running Running 13 seconds ago

Scale the service to 10 replicas to provide load distribution. Subsequently, list the services to list 10/10 replicas as running.∼ $ docker service scale hello-world=10

hello-world scaled to 10

∼ $ docker service ls

ID NAME MODE REPLICAS IMAGE

vn5U8h7t65s hello-world replicated 10/10 tutum/hello-world:latest

∼ $

10 个服务任务副本跨群节点进行调度,如图 13-8 所示。

A454123_1_En_13_Fig8_HTML.jpg

图 13-8。

Service tasks scheduled across the Swarm nodes

从 EC2 仪表板获取第一个 Docker 群组的负载均衡器 DNS,如图 13-9 所示。

A454123_1_En_13_Fig9_HTML.jpg

图 13-9。

Docker Swarm load balancer

在 web 浏览器中访问<DNS>:<LoadBalancerPort>处的服务,如图 13-10 所示;负载均衡器端口设置为 8080,该端口用于公开服务。

A454123_1_En_13_Fig10_HTML.jpg

图 13-10。

Accessing the service in a browser

类似地,对于第二个 Docker Swarm,创建一个tutum/hello-world服务,将发布端口设置为 8080。将服务扩展到 10 个副本,以便在整个集群中分配负载。

S docker service create \

> --name hello-world \

> --publish 8080:80 \

,> --replicas 2 \

> tutum/hello-world

woqx2ltuibv53ctmuvssrsq8j

∼ $ docker service ls

ID NAME MODE REPLICAS IMAGE

woqx2ltuibv5 hello-world replicated 2/2 tutum/hello-world:latest

∼ $ docker service ps hello-world

NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS

ny9ermdgb7a4 hello-world.1 tutum/hello-world:latest ip-172-31-34-223.us-east-2.compute.internal Running Running 15 seconds ago

5w3thlgleinme hello-world.2 tutum/hello-world:latest ip-172-31-30-180.us-east-2.compute.internal Running Running 15 seconds ago

∼ $ docker service scale hello-world=10

hello-world scaled to 10

服务副本分布在群节点上,如图 13-11 所示。

A454123_1_En_13_Fig11_HTML.jpg

图 13-11。

Service replicas distributed across the Swarm

获取第二个集群的弹性负载均衡器的 DNS,如图 13-12 所示。

A454123_1_En_13_Fig12_HTML.jpg

图 13-12。

Obtaining the DNS name for the Swarm ELB

在 web 浏览器中访问<DNS>:<LoadBalancerPort>处的服务,如图 13-13 所示。

A454123_1_En_13_Fig13_HTML.jpg

图 13-13。

Accessing the service in a browser

创建亚马逊路线 53

Amazon Route 53 是一个高度可用和可扩展的云域名服务(DNS ) web 服务,它将用户请求连接到运行在 AWS 上的基础设施,包括 Amazon EC2 实例、负载均衡器和 Amazon S3 存储桶。我们已经使用 Docker AWS 托管服务创建了两个托管相同 Docker 服务的 Docker 群组,该服务会自动为每个 Docker 群组创建一个 AWS ELB。

在本节中,我们创建一个 Amazon Route 53,将用户对nosqlsearch.com域的请求路由到两个 Docker 集群的弹性负载均衡器。在 Amazon Route 53 中,我们创建了两个资源记录集,指向为故障转移配置的两个不同的 elb,其中一个 elb 是主资源记录集,另一个是辅助资源记录集。

当在 web 浏览器中打开nosqlsearch.com域时,路由 53 将请求路由到主资源记录集。如果主记录集失败,Route 53 将用户请求路由到辅助记录集,实际上提供了托管在nosqlsearch.com域上的 Hello World Docker 服务的高可用性。要创建 AWS 路线 53,从 AWS 服务中选择路线 53,如图 13-14 所示。

A454123_1_En_13_Fig14_HTML.jpg

图 13-14。

Selecting the Amazon Route 53 service

创建托管区域

托管区域是一种配置,用于确定如何路由互联网上某个域的流量。要创建托管区域,在网页浏览器中打开 https://console.aws.amazon.com/route53/ ,在 DNS 管理中点击创建托管区域,如图 13-15 所示。

A454123_1_En_13_Fig15_HTML.jpg

图 13-15。

Creating the hosted zone

或者,选择托管区域或在浏览器中打开 https://console.aws.amazon.com/route53/home#hosted-zones ,点击创建托管区域,如图 13-16 所示。

A454123_1_En_13_Fig16_HTML.jpg

图 13-16。

Creating a hosted zone

再次点击创建托管区域,如图 13-17 所示。

A454123_1_En_13_Fig17_HTML.jpg

图 13-17。

Creating a hosted zone

在创建托管区域对话框中,指定域名(nosqlsearch.com)。域名必须向用户注册。类型选择公共托管区域,如图 13-18 所示。

A454123_1_En_13_Fig18_HTML.jpg

图 13-18。

Configuring the hosted zone

创建一个新的公共托管区域,如图 13-19 所示。托管区域的名称服务器(默认情况下有四个)已分配。

A454123_1_En_13_Fig19_HTML.jpg

图 13-19。

The new public hosted zone

配置名称服务器

接下来,我们需要通过域名注册机构来配置域名服务器。不同的域名注册商配置域名服务器的程序是不同的,但是应该提供一个为域名添加区域记录的选项。

将记录类型指定为名称服务器,如图 13-20 所示。将主机指定为@。每个区域记录应该指向一个名称服务器,该服务器可以从我们之前创建的公共托管区域获得。

A454123_1_En_13_Fig20_HTML.jpg

图 13-20。

Adding a name server record

为要创建托管区域的域添加四台名称服务器(统称为委托集),如图 13-21 所示。

A454123_1_En_13_Fig21_HTML.jpg

图 13-21。

Name servers configured on a domain

创建资源记录集

创建和配置托管区域后,创建一个或多个资源记录集。资源记录集是用于将流量路由到域的域名系统(DNS)配置。点击创建记录集,创建一个资源记录集,如图 13-22 所示。

A454123_1_En_13_Fig22_HTML.jpg

图 13-22。

Creating a record set

在创建记录集选项卡中,类型应设置为–IP v4 地址,如图 13-23 所示。每个记录集的名称都以域名结尾。为别名选择是。

A454123_1_En_13_Fig23_HTML.jpg

图 13-23。

Configuring a record set

接下来,选择别名目标作为其中一个 Docker 集群的 AWS 弹性负载均衡器 DNS,如图 13-24 所示。

A454123_1_En_13_Fig24_HTML.jpg

图 13-24。

Selecting an alias target

接下来,选择路由策略,如图 13-25 所示。

A454123_1_En_13_Fig25_HTML.jpg

图 13-25。

Selecting a routing policy

为路由策略选择故障转移。这将配置 DNS 故障转移,如图 13-26 所示。选择故障转移记录类型为主记录类型。

A454123_1_En_13_Fig26_HTML.jpg

图 13-26。

Selecting failover record type

对于评估目标健康,选择是,如图 13-27 所示。

A454123_1_En_13_Fig27_HTML.jpg

图 13-27。

Selecting the Evaluate Target Health option

对于关联健康检查,选择否,点击创建,如图 13-28 所示。

A454123_1_En_13_Fig28_HTML.jpg

图 13-28。

Creating a record set

创建一个主记录集,如图 13-29 所示;“主要”意味着网站流量将首先被路由到记录集。

A454123_1_En_13_Fig29_HTML.jpg

图 13-29。

Primary record set

要创建辅助记录集,再次点击创建记录集,如图 13-30 所示。

A454123_1_En_13_Fig30_HTML.jpg

图 13-30。

Creating another record set

选择类型为–IP v4 地址,并为别名选择是。选择别名目标作为第二个 ELB DNS,如图 13-31 所示。

A454123_1_En_13_Fig31_HTML.jpg

图 13-31。

Selecting an alias target

选择故障转移路由策略和辅助故障转移记录类型,如图 13-32 所示。

A454123_1_En_13_Fig32_HTML.jpg

图 13-32。

Selecting failover record type as secondary

为评估目标健康状况选择是,为与健康状况检查关联选择否。点击创建,如图 13-33 所示。

A454123_1_En_13_Fig33_HTML.jpg

图 13-33。

Creating a secondary record set

创建辅助记录集;“次要”意味着如果主要记录集出现故障,流量将被路由到该记录集,如图 13-34 所示。点击返回托管区域。

A454123_1_En_13_Fig34_HTML.jpg

图 13-34。

Secondary record set is created

域(nosqlsearch.com)配置了四个记录集,如图 13-35 所示。

A454123_1_En_13_Fig35_HTML.jpg

图 13-35。

Hosted zone created

测试高可用性

接下来,我们测试我们配置的高可用性。在 web 浏览器中打开域,包括服务发布端口(nosqlsearch.com:8080),如图 13-36 所示。应该会显示 Docker 服务输出。

A454123_1_En_13_Fig36_HTML.jpg

图 13-36。

Invoking a service in a browser

为了测试高可用性,删除与主记录集关联的 Docker Swarm 的 CloudFormation 栈,如图 13-37 所示。

A454123_1_En_13_Fig37_HTML.jpg

图 13-37。

Deleting a stack

在删除栈对话框中单击是,删除。栈应该开始被删除,如图 13-38 中的DELETE_IN_PROGRESS状态所示。

A454123_1_En_13_Fig38_HTML.jpg

图 13-38。

The delete is in progress

DNS 故障转移到二级资源记录集,域继续服务 Docker 服务,如图 13-39 所示。

A454123_1_En_13_Fig39_HTML.jpg

图 13-39。

Domain continues to serve

如果请求被转发到不同的服务任务副本,浏览器中的主机名可能会变得不同,如图 13-40 所示。但是无论是否启动了故障转移,主机名也可能变得不同,因为入口负载均衡器在不同的服务副本之间分配流量。

A454123_1_En_13_Fig40_HTML.jpg

图 13-40。

Different hostname

删除托管区域

在删除托管区域之前,必须删除与托管区域关联的所有资源记录集。选择要删除的资源记录集,点击【删除记录集】,如图 13-41 所示。

A454123_1_En_13_Fig41_HTML.jpg

图 13-41。

Deleting the record sets

在确认对话框中点击确认,如图 13-42 所示。

A454123_1_En_13_Fig42_HTML.jpg

图 13-42。

Confirmation dialog

点击返回托管区域,如图 13-43 所示。

A454123_1_En_13_Fig43_HTML.jpg

图 13-43。

Going back to the hosted zones

选择要删除的托管区域,点击删除托管区域,如图 13-44 所示。

A454123_1_En_13_Fig44_HTML.jpg

图 13-44。

Deleting a hosted zone

在确认对话框中点击确认,如图 13-45 所示。

A454123_1_En_13_Fig45_HTML.jpg

图 13-45。

Confirmation dialog for deleting a hosted zone

托管区域被删除。

摘要

本章使用 Amazon Route 53 托管区域开发了一个高度可用的网站。首先,我们使用 Docker for AWS 托管服务创建了两个 Docker 群组,并在每个群组上部署了相同的 Docker 服务。每个 Docker 群服务可以使用由 Docker for AWS 自动创建的 Docker 群的 AWS 弹性负载均衡器来访问。路由 53 托管区域将为域创建一个托管区域,以将流量路由到在主/辅助故障转移模式中配置的 DNS。随后,我们测试了如果主记录集的 Docker Swarm 关闭,网站仍然可用,因为托管区域会将流量路由到辅助 ELB DNS。在下一章,我们将讨论在 Docker Cloud 中使用 Docker Swarm 模式。

十四、在 Docker Cloud 中使用 Swarm 模式

Docker for AWS 是 Docker Swarm 基于定制 Linux 发行版的托管服务,托管在 AWS 上,具有与 AWS 云平台集成的所有固有优势,如 CloudWatch 的集中式日志记录、定制调试、自动扩展组、弹性负载均衡和 DynamoDB 数据库。

问题

虽然 AWS 是一个托管云平台,但它本身不是 Docker 容器、映像和服务的托管服务。Docker 的构建和测试仍然需要集成。

解决方案

Docker Cloud 是一项托管服务,用于测试代码和构建 Docker 映像,并在 Docker Cloud 注册表中创建和管理 Docker 映像库。Docker Cloud 还管理 Docker 容器、服务、栈、节点和节点集群。栈是服务的集合,而服务是容器的集合。Docker Cloud 是一个集成的云服务,可以管理构建和映像、基础架构、节点和应用。

Docker Cloud 还引入了 Swarm 模式来管理 Docker Swarms。在 Swarm 模式下,Docker Cloud 与 Docker for AWS 集成。因此,Docker 云群模式是两种托管服务的集成——Docker for AWS 和 Docker Cloud。

Docker Cloud 提供了一些 Docker 映像,用于在 Docker 群和 Docker 主机客户端之间进行交互,如表 14-1 中所述。

表 14-1。

Docker Images for Docker Swarm

| Docker 映像 | 描述 | | --- | --- | | `dockercloud/client` | 在客户端使用 Docker ID 凭证启动交互式 shell 以连接到远程 docker Swarm 集群。 | | `dockercloud/client-proxy` | 在客户端使用,通过在每个请求上注入 Docker ID 授权信息,将本地 docker API 调用转发到远程群集群。 | | `dockercloud/server-proxy` | 验证和授权传入的 Docker API 调用,并将它们转发到本地 Docker 引擎。 | | `dockercloud/registration` | 向 Docker Cloud 注册一个群集群并启动一个服务器代理。 |

在本章中,我们将讨论 Docker 云群模式,以向 Docker 云群提供 AWS 上托管的基础架构。本章涵盖以下主题:

  • 设置环境
  • 创建 IAM 角色
  • 在 Docker 云中创建 Docker 群
  • 从 Docker 主机连接到 Docker 群组
  • 从群组管理器连接到 Docker 群组
  • 将蜂群带入 Docker 云

设置环境

由于 Docker Cloud 是一项托管服务,因此所需要的只是一个帐户,该帐户可以在 https://cloud.docker.com/ 创建。AWS 帐户也是必需的,可以在 https://aws.amazon.com/resources/create-account/ 创建。还要在 Docker Swarm 的 EC2 实例将要运行的区域中创建一个密钥对,如图 14-1 所示。

A454123_1_En_14_Fig1_HTML.jpg

图 14-1。

Creating a key pair on AWS EC2

创建 IAM 角色

Docker 云群模式需要一个具有新策略的 AWS 角色,这是 Docker for AWS 的嵌入式策略。要创建 IAM 角色,请在 web 浏览器中导航至 https://console.aws.amazon.com/iam/home?#roles 。点击新建角色,如图 14-2 所示。

A454123_1_En_14_Fig2_HTML.jpg

图 14-2。

Creating a new role

指定一个角色名称(dockercloud-swarm-role),如图 14-3 ,点击下一步。

A454123_1_En_14_Fig3_HTML.jpg

图 14-3。

Specifying a role name

显示选择角色类型页面,如图 14-4 所示。由于我们链接了两个服务——Docker Cloud 和 Docker for AWS——我们不需要选择 AWS 服务角色。

A454123_1_En_14_Fig4_HTML.jpg

图 14-4。

Select the role type

选择跨账户访问的角色,如图 14-5 所示,并使用选择按钮选择名为“在您的 AWS 账户和第三方 AWS 账户之间提供访问”的子选项。

A454123_1_En_14_Fig5_HTML.jpg

图 14-5。

Role for cross-account access

接下来,指定 IAM 用户将访问 AWS 帐户的第三方 AWS 帐户的帐户 ID。已经为 Docker 云服务设置了一个第三方 AWS 帐户,其帐户 ID 为689684103426,任何人(AWS 用户)都可以将 Docker 云服务链接到其 AWS 帐户。指定账户 ID 为689684103426,如图 14-6 所示。外部 ID 是在 https://cloud.docker.com/ 创建的 Docker 云服务账户的用户 Docker ID。虽然每个人的帐户 ID 都是相同的(689684103426),但是不同用户的外部 ID 是不同的。保持要求 MFA 复选框未选中。点击下一步。

A454123_1_En_14_Fig6_HTML.jpg

图 14-6。

Specifying account and external IDs

由于我们正在嵌入自定义策略,因此不要从“Attach Policy”中列出的任何策略中进行选择。点击下一步,如图 14-7 所示。

A454123_1_En_14_Fig7_HTML.jpg

图 14-7。

Do not select a policy

在审核页面,点击创建角色,如图 14-8 所示。

A454123_1_En_14_Fig8_HTML.jpg

图 14-8。

Creating a role

一个名为dockercloud-swarm-role的新 AWS IAM 角色被创建,如图 14-9 所示。单击 dockercloud-swarm-role 角色名称。

A454123_1_En_14_Fig9_HTML.jpg

图 14-9。

New role

接下来,我们将添加一个嵌入式(也称为内联)策略。默认情况下,应选择“权限”选项卡。点击 v 图标,展开内嵌策略部分,如图 14-10 所示。

A454123_1_En_14_Fig10_HTML.jpg

图 14-10。

Expanding the inline policies

首先,没有列出内联策略。点击点击此处链接,添加一个内嵌策略,如图 14-11 所示。

A454123_1_En_14_Fig11_HTML.jpg

图 14-11。

Click on the Click Here link to add an inline policy

在设置权限界面,使用选择按钮选择自定义策略,如图 14-12 所示。

A454123_1_En_14_Fig12_HTML.jpg

图 14-12。

Selecting a custom policy

策略文档列出了一些权限,IAM 角色使用 Docker for AWS 的策略文档可从 https://docs.docker.com/docker-for-aws/iam-permissions/ 获得。点击【验证策略】对策略进行验证,如图 14-13 所示。

A454123_1_En_14_Fig13_HTML.jpg

图 14-13。

Validating the policy

点击应用策略,如图 14-14 所示。

A454123_1_En_14_Fig14_HTML.jpg

图 14-14。

Applying the policy

dockercloud-swarm-role角色添加了一个新的内联策略,如图 14-15 所示。

A454123_1_En_14_Fig15_HTML.jpg

图 14-15。

The new inline policy is added

复制图 14-16 中列出的角色 ARN 字符串,因为我们需要 ARN 字符串从 Docker Cloud 连接到 AWS 云提供商。

A454123_1_En_14_Fig16_HTML.jpg

图 14-16。

Role ARN

在 Docker 云中创建 Docker 群

在本节中,我们将从 Docker 云服务中创建一个 Docker Swarm。在 https://cloud.docker.com/ 登录 Docker 云服务。云注册表页面应该显示在 https://cloud.docker.com/app/dvohra/dashboard/onboarding/cloud-registry 。空白处有一个群组模式选项,默认关闭,如图 14-17 所示。

A454123_1_En_14_Fig17_HTML.jpg

图 14-17。

The Swarm Mode slider

点击 Swarm 模式滑块;应启用群组模式,如图 14-18 所示。

A454123_1_En_14_Fig18_HTML.jpg

图 14-18。

Switching to Swarm mode

增加一个群组工具栏选项,如图 14-19 所示。

A454123_1_En_14_Fig19_HTML.jpg

图 14-19。

Swarms toolbar option

有两种选择——带上你自己的蜂群或者创建一个新的蜂群。点击创建创建一个新的蜂群,如图 14-20 所示。

A454123_1_En_14_Fig20_HTML.jpg

图 14-20。

Creating a new Swarm

接下来,我们将配置群组,包括指定群组名称、选择云提供商和选择云提供商选项。支持两个云服务提供商:Amazon Web Services (AWS)和 Microsoft Azure(尚不可用)。我们在本章中使用 AWS。我们需要用之前复制的 ARN 字符串来配置 AWS 的云设置。云设置可以通过以下两个选项之一进行配置。一种选择是从账户中选择云设置,如图 14-21 所示。

A454123_1_En_14_Fig21_HTML.jpg

图 14-21。

Cloud settings

在云设置页面,点击表示亚马逊网络服务提供商 Connect Provider 的插件图标,如图 14-22 所示。

A454123_1_En_14_Fig22_HTML.jpg

图 14-22。

Connecting the provider

显示添加 AWS 凭证对话框,如图 14-23 所示。

A454123_1_En_14_Fig23_HTML.jpg

图 14-23。

Adding AWS credentials

配置云设置的另一个选项是单击 Amazon Web Service 服务提供商图标,如图 14-24 所示,这也会显示添加 AWS 凭证对话框。

A454123_1_En_14_Fig24_HTML.jpg

图 14-24。

Connecting to an Amazon web services provider

指定之前从添加 AWS 凭证对话框中复制的 ARN 字符串并点击保存,如图 14-25 所示。

A454123_1_En_14_Fig25_HTML.jpg

图 14-25。

Saving the AWS credentials

无论选择哪种方式,服务提供商 Amazon Web Services 都应该连接,如连接提供商图标变为已连接所示,如图 14-26 所示。

A454123_1_En_14_Fig26_HTML.jpg

图 14-26。

Amazon Web Services provider in connected mode

亚马逊网络服务选项应该显示connected,如图 14-27 所示。

A454123_1_En_14_Fig27_HTML.jpg

图 14-27。

Amazon Web Services provider connected

指定群组名称。该名称不得包含除“,”、,-_之外的任何空格、大写字母或特殊字符,如图 14-28 所示。

A454123_1_En_14_Fig28_HTML.jpg

图 14-28。

Specifying a Swarm name

指定一个有效的群名称(docker-cloud-swarm),选择已经连接好的 Amazon Web Services 服务提供商,点击创建,如图 14-29 所示。

A454123_1_En_14_Fig29_HTML.jpg

图 14-29。

Creating a Docker Swarm using the AWS service provider

在区域中,选择一个区域(us-east-2)、群管理器数量(3)、群工作器数量(5)、群管理器实例类型(t2.micro)、代理工作器实例类型(t2.micro)和 SSH 密钥。点击创建,如图 14-30 所示。

A454123_1_En_14_Fig30_HTML.jpg

图 14-30。

Configuring and creating a Swarm

蜂群应该开始部署,如图 14-31 中的DEPLOYING消息所示。

A454123_1_En_14_Fig31_HTML.jpg

图 14-31。

Deploying a Swarm

当蜂群部署完毕后,消息变成Deployed,如图 14-32 所示。

A454123_1_En_14_Fig32_HTML.jpg

图 14-32。

The Swarm is now deployed

为 Swarm 创建和配置 AWS 基础设施。生成一个云状栈,如图 14-33 所示。

A454123_1_En_14_Fig33_HTML.jpg

图 14-33。

CloudFormation stack for the created Swarm

为群组添加了一个新的代理 AWS IAM 角色,如图 14-34 所示。

A454123_1_En_14_Fig34_HTML.jpg

图 14-34。

Proxy role and Docker Cloud Swarm AWS role

启动群管理器和工作节点的 EC2 实例。每个 EC2 实例都以自动创建的代理 IAM 角色启动,如图 14-35 中的管理节点所示。

A454123_1_En_14_Fig35_HTML.jpg

图 14-35。

IAM role for EC2 instances

每个 Docker 云帐户名称空间必须只与一个 AWS IAM 角色相关联。如果多个 Docker 云帐户要访问同一个 AWS 帐户,则必须为每个 Docker 云帐户或 Docker 云帐户名称空间创建多个角色。Docker Cloud 访问 AWS 的每个 AWS IAM 角色都与一个 ARN 字符串相关联。可以使用编辑端点链接编辑已部署群组的 ARN 字符串,如图 14-36 所示。

A454123_1_En_14_Fig36_HTML.jpg

图 14-36。

Edit Endpoint link

如果要修改群组端点,请在“编辑端点”对话框中指定新的 ARN 字符串(用于与不同 Docker 云名称空间关联的不同 IAM 角色)。点击保存,如图 14-37 所示。

A454123_1_En_14_Fig37_HTML.jpg

图 14-37。

Editing the endpoint

接下来,我们连接到 Docker 群。有两种方法可以做到:

  • 从任何 Docker 主机直接连接
  • 从 EC2 仪表板获取群管理器的公共 IP 地址,并通过 SSH 登录群管理器

我们讨论这些选项中的每一个。

从 Docker 主机连接到 Docker 群组

点击 Docker 云仪表盘中的 Docker Swarm。应显示带有docker run命令的连接对话框,如图 14-38 所示。复制docker run命令。

A454123_1_En_14_Fig38_HTML.jpg

图 14-38。

Listing and copying the docker run command to connect to the Swarm

用预装 Docker 的 CoreOS AMI 启动一个 EC2 实例,如图 14-39 所示。

A454123_1_En_14_Fig39_HTML.jpg

图 14-39。

Creating an EC2 instance with CoreOS AMI

从 EC2 控制台获取 CoreOS 实例的公共 IP 地址,如图 14-40 所示。

A454123_1_En_14_Fig40_HTML.jpg

图 14-40。

Displaying EC2 instance detail

SSH 登录到 CoreOS 实例。

ssh -i "coreos.pem" core@34.207.220.127

运行之前复制的命令来连接 Docker Swarm。

docker run --rm -ti -v /var/run/docker.sock:/var/run/docker.sock -e DOCKER_HOST dockercloud/client dvohra/docker-cloud-swarm

下载用于连接 Docker Cloud 的dockercloud/client Docker 映像。应该显示用户名和密码提示。指定创建群组的 Docker 云帐户的用户名和密码。

Container Linux by CoreOS stable (1298.5.0)

$ docker run --rm -ti -v /var/run/docker.sock:/var/run/docker.sock -e DOCKER_HOST dockercloud/client dvohra/docker-cloud-swarm
Unable to find image 'dockercloud/client:latest' locally
latest: Pulling from dockercloud/client
b7f33ccOb4Be: Pull complete
91b7430c5c68: Pull complete
b686674c0e39: Pull complete
l9aaa3õbba7a: Pull complete
Digest: sha2S6: 11d3cc5e1a62c7324]2a6e038]ccffi9]53tc91d0b1c69c8D1d3b68629337558a6
Status: Downloaded newer image for dockercloud/client:latest
Use your Docker ID credentials to authenticate:
Username: dvohra
Password:

输出一个export命令以连接到群。复制命令。

Use your Docker ID credentials to authenticate:
Username: dvohra
Password:
=> You can now start using the swarm dvohra/docker-cloud-swarm by executing:
export DOCKER_HOST=tcp://127.0.0.1:32768

运行命令。蜂群连接到 CoreOS Docker 主机。使用docker node ls命令列出群节点。

>export DOCKER_HOST=tcp://127.0.0.1:32768

>docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS

liuomlmb6n6xtq4apxayumsx3 ip-172-31-0-251.us-east-2.cornpute.internal. Ready Active
bchea5x85m82jtzoq336trn8y ip-172-31-47-61.us-east-2.compute.internat. Ready Active
e2bl785z5pqouakdceomdpsbi ip-172-31-42-130.us-east-2.compute.internal. Ready Active
hzxb8choml.7gylaqtrjrh6phx ip-172-31-26-90.us-east-2.compute.internal. Ready Active
pcnple9l29w88ueonhdwUcoc ip-172-31-27-18.us-east-2.compute.internal. Ready Active
rupjaojommfchjgcshffdobhf * ip-172-31-10-153.us-east-2.compute.internal Ready Active Leader
uyl5xv7mhb6c8jam5ofncplyh ip-172-31-25-137.us-east-2.compute.internal. Ready Active Reachable
wi6zurda4nawf9mgku3enf6io ip-172-31-34-33.us-east-2.cornpute.ìnternal Ready Active Reachable

从群组管理器连接到 Docker 群组

另一种选择是使用其公共 IP 地址连接到群管理器。首先,我们从 EC2 控制台获取一个群组管理器的公共 IP 地址,如图 14-41 所示。

A454123_1_En_14_Fig41_HTML.jpg

图 14-41。

Obtaining the public IP of a Swarm manager

SSH 登录到 Swarm manager。

ssh -i "docker.pem" docker@52.14.146.223

群组管理器登录,并显示群组命令提示符。

[root@1ocathost —]# ssh -i "docker.pem" docker@52.14.146.223
The authenticity of host 52.14.146.223 (52.14.146.223)1 cant be established.
RSA key fingerprint is e9:7f:d2:3c:de:6d:5d:94:06:e2:09:56:b7:2a:c6:9a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '52.14.146.223 (RSA) to the list of known hosts.
Welcome to Docker!

使用docker node ls命令列出群节点。

Welcome to Docker!

∼ $ docker node l.s

ID HOSTNAME STATUS

AVAILABILITY MANAGER STATUS

liuomlmb6n6xtq4apxayumsx3 ip-172-31-O-251.us-east-2.compute.internal Ready Active

bchea5x85m82jtzoq336trn8y ip-172-31-47-61.us-east-2.cornpute.internal Ready Active

e2bl785z5pqouakdceonìdpsbi ip-172-31-42-130.us-east-2.compute.internal Ready Active

hzxb8chomt7gyl.aqtrj rh6phx ip-172-31-26-90.us-east-2.compute.interna1 Ready Active

pcnple9l29w88ueenhdwflcoc ip-172-31-27-18.us-east-2.compute.internal Ready Active

rupjaejommfchjgcshffdobhf * ip-172-31-1O-153.us-east-2.compute.internal. Ready Active Leader

uyl5xv7mhb6c8jain5ofncplyh ip-172-31-25-137.us-east-2.compute.internal. Ready Active Reachable

wi6zurda4nawf9mgku3enf6ie ip-172-31-34-33.us-east-2.compute.internal Ready Active Reachab1e

使用docker service create命令创建一个服务,并用docker service ls列出该服务。

docker service create \
  --name hello-world \
  --publish 8080:80 \
  --replicas 1 \
  tutum/hello-world

创建了hello-world服务。还列出了 Docker 云服务器代理服务。

∼ $ docker service create \


> --name hello-world \


> --publish 8080:80 \


> - - replicas 1 \


> tutum/hello-world

hbiejbua8u5øskabun3dzkxk4

∼ $ docker service 1s

ID NAME MODE REPLICAS IMAGE

0gzua3p56myx dockerdoud-server-proxy global 3/3 dockercioud/server-proxy:latest

hbiejbua8u50 hello-world replicated 1/1 tutum/hello-world:latest

将蜂群带入 Docker 云

Docker Cloud Swarm 模式还可以将现有的 Swarm 导入 Docker Cloud。要导入的群必须具备以下先决条件:

  • 基于 Docker 引擎 1.13 或更高版本的节点
  • 群管理器传入端口 2376 已解除阻塞

在本节中,我们创建一个群,并将该群导入 Docker Cloud。首先,运行docker --version命令来确定 Docker 主机版本是否是 1.13 或更高版本。Docker 为 AWS 提供的 EC2 实例之一可用于创建和导入群,因为定制 Linux 发行版上的 Docker 版本是>Docker 1.13;在创建新的群之前,必须使节点离开群。使用 EC2 实例的私有 IP 地址,启动一个新的群。

docker swarm init --advertise-addr 172.31.23.196

复制docker swarm join命令输出以加入工作节点。

∼ $ docker --version

Docker version 17.03.0-ce, build 60ccb22

∼ $ docker swarm init --advertise-addr 172.31.23.196

Swarm initialized: current node (ylzc3h3slxO5ztbujtl3yf86p) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join \

--token SWMTKN-1-23snf1iuieafnyd1zzgf37ucwuz1.khg9atqsmysmvv6iw1.arw0-do29n83jptkkdwss5fjsd3rt \

172.31.23.196:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

使用 Docker 1.13 或更高版本在另一个 EC2 实例上加入一个 worker 节点。

docker swarm join \
    --token SWMTKN-1-61gcsgkr1ildxz580ftdl3rq0s9p7h30n12byktgvbd6y3dk7r-cpes7ofdsq8abhxtznh92tjrz \
    10.0.0.176:2377

工作者节点加入群体。

创建了一个有两个节点的群,如在群管理器节点上运行的docker node ls命令的输出中所列。

∼$ docker node 1s

HOSTNAME STATUS

AVAILABILITY MANAGER STATUS

trgb2t4ehs2gp3cjbrnqhs7a5 ip-172-31-6-64.us-east-2.compute.internal. Ready Active

yl.ic3h3stxo5ztbujtl3yf86p ip-172-31-23-196.us-east-2.compute.internal Ready Active Leader

∼$

接下来,将 Swarm 导入 Docker Cloud。从群组管理器节点,运行以下命令。

docker run -ti --rm -v /var/run/docker.sock:/var/run/docker.sock dockercloud/registration

在用户名提示符下指定 Docker ID,在密码提示符下指定密码。

∼ S docker run -ti --rm -v /var/run/docker.sock:/var/run/docker.sock dockercloud/registration
Unable to find image dockercloud/registration:latest’ locally
latest: Pulling from dockercloud/registration
b7f33ccOb48e: Pull complete
b52875cf8fd4: Pull complete
23f82c866468: Pull complete
Digest: sha256: a3f39de96d2763b957e7bel22ce99b8lfbbaO3fbd6b2e54bd6O7lcafbelcabcl
Status: Downloaded newer image for dockercloud/registratìon:latest
Use your Docker ID credentials to authenticate:
Username: dvohra
Password:

为导入 Docker Cloud 的群组指定一个集群名称,或使用默认名称。将集群指定为dvohra/dockercloudswarm。蜂群在 Docker Cloud 注册。至于在 Docker 云群模式中创建的群,可以从输出命令的任何 Docker 主机访问该群。

Enter name for the new cluster [dvohra/wkhøtlq8cw5u44x22qp6r4eau]: dvohra/dockercloudswarm

You can now access this cluster using the following command in any Docker Engine

docker run -rm -ti -v /var/run/docker.sock:/var/run/docker.sock -e DOCKER HOST dockerctoud/client dvohra/dockerctoudswarm

要将蜂群带入 Docker Cloud,在蜂群模式下点击自带蜂群按钮,如图 14-42 所示。

A454123_1_En_14_Fig42_HTML.jpg

图 14-42。

Bring your own Swarm

向 Docker Cloud 注册的群被添加到 Docker Cloud 群中,如图 14-43 所示。

A454123_1_En_14_Fig43_HTML.jpg

图 14-43。

Docker Cloud Swarms , including the imported Swarm

摘要

本章介绍了 Docker Cloud Swarm 模式,这是一种托管服务,用于将 Docker Cloud 托管服务链接到 AWS 服务提供商帐户,并从 Docker Cloud 供应 Swarm。在命令行上创建的 Swarm 可以导入 Docker Cloud。在下一章,我们将讨论 Docker 服务栈。

十五、使用服务栈

Docker Swarm 模式是 Docker 1.12 版的 Docker 原生模式,用于为开发 Docker 应用创建分布式和可扩展的服务。

问题

虽然单个 Docker 映像应用也很常用,但绝大多数 Docker 企业应用都由多个映像组成,这些映像之间存在依赖关系。Docker Compose(在 v1 和 v2 中是独立的)可以通过使用linksdepends_on选项来声明微服务之间的依赖关系,但是 Compose(独立的)是过时的,不同于在群模式服务的上下文中定义服务的格式。

解决方案

Docker Swarm mode 引入了服务栈来定义服务的集合(Swarm mode services ),这些服务彼此自动链接,以提供服务之间存在依赖关系的逻辑分组。栈使用的栈文件是 YAML 文件,其格式非常类似于docker-compose.yml格式。有一些不同之处,比如缺少了用于定义 Docker Compose (standalone)中微服务之间依赖关系的linksdepends_on选项。YAML ( http://www.yaml.org/ )是配置文件常用的一种数据序列化格式。

从 Docker v1.13 开始,已经引入了命令的docker stack子集来创建 Docker 栈。使用一个定义多个服务的栈文件,包括服务的配置,如环境变量、标签、容器数量和卷,一个docker stack deploy命令创建一个服务栈,如图 15-1 所示。这些服务会自动相互链接。

A454123_1_En_15_Fig1_HTML.gif

图 15-1。

Service stack created with the docker stack deploy command

Docker Compose v3.x 及更高版本完全兼容 Docker Swarm 模式,这意味着 Docker Compose v3.x docker-compose.yml文件可以用作栈文件,但栈文件中不支持的几个子选项(包括buildcontainer_nameexternal_linkslinks)除外。Docker Compose 3.x 仍然可以独立使用来开发非群模式服务,但这些微服务无法与 Docker 群模式docker service命令组一起使用或扩展。

要使用栈来管理群模式服务,必须满足以下要求。

  • Docker 版本必须是 1.13 或更高版本
  • 必须启用群组模式
  • 栈文件 YAML 格式必须基于 Docker Compose v3.x 文件格式

要使用服务栈,可以使用 Docker Compose 第 3 版 YAML 文件格式,但不需要安装 Docker Compose。

使用 Docker Swarm 模式时,对 Swarm 模式的 Docker 版本要求是 1.12 或更高版本。在开发管理群模式服务的栈之前,验证 Docker 版本至少是 1.13。本章使用的 Docker 版本是 17.0x。表 15-1 中列出的docker stack组命令在 Docker v1.13 和更高版本中可用。

表 15-1。

The docker stack Commands

| 命令 | 描述 | | `deploy` | 部署服务栈或更新现有栈 | | `ls` | 列出栈 | | `ps` | 列出栈中的群组模式任务 | | `rm` | 移除栈 | | `services` | 列出栈中的群组模式服务 |

运行docker --version命令列出 Docker 版本。要列出栈使用的命令,请运行docker stack命令。

[root@localhost ∼]# ssh -i "docker.pem" docker@34.205.43.53
Welcome to Docker!
∼ $ docker --version
Docker version 17.06.0-ce, build 02c1d87
∼ $ docker stack

Usage:    docker stack COMMAND

Manage Docker stacks

Options:
      --help   Print usage

Commands:
  deploy      Deploy a new stack or update an existing stack
  ls          List stacks
  ps          List the tasks in the stack
  rm          Remove one or more stacks
  services    List the services in the stack

要使用栈,请使用以下过程。

  1. 安装 Docker 版本 1.13 或更高版本(不是 Docker 版本 1.12,它在前面的几章中使用)。
  2. 启用 Swarm 模式。
  3. 使用 Docker Compose(3 . x 版)YAML 格式创建一个栈文件。
  4. 使用docker stack组命令创建和管理栈。

本章创建了一个由两个服务组成的服务栈,一个用于 WordPress 博客,另一个用于 MySQL 数据库,以存储 WordPress 博客中的数据。

设置环境

我们使用位于 https://docs.docker.com/docker-for-aws/ 的 Docker for AWS 来启动一个 Docker Swarm 模式的节点集群。Docker for AWS 使用 AWS CloudFormation 模板创建 Docker Swarm 模式集群。点击 Deploy Docker Community Edition(stable),如图 15-2 所示,启动 Create CloudFormation Stack 向导创建 Docker Swarm mode 集群。

A454123_1_En_15_Fig2_HTML.gif

图 15-2。

Deploying the Docker Community Edition for AWS (stable)

如第三章所述,使用创建栈向导配置一个群组。您可以指定群组管理器的数量为 1、3 或 5,群组工作节点的数量为 1-1000。我们使用了一个群管理器节点和两个群工作者节点,如图 15-3 所示。

A454123_1_En_15_Fig3_HTML.jpg

图 15-3。

Configuring a CloudFormation stack

云形成栈被创建,如图 15-4 所示。

A454123_1_En_15_Fig4_HTML.jpg

图 15-4。

CloudFormation Stack for Docker on AWS

启动三个 EC2 实例——一个用于 Docker Swarm manager 节点,两个用于 Swarm worker 节点,如图 15-5 所示。CloudFormation 栈使用的 Linux 发行版是莫比 Linux,如图 15-5 所示。

A454123_1_En_15_Fig5_HTML.jpg

图 15-5。

The Moby Linux AMI used for Docker on AWS

在能够在 AWS 上使用 Docker 之前,在 EC2 实例使用的安全组中启用 EC2 实例之间的所有入站/出站流量。在图 15-6 中显示了群管理器节点实例入站规则的安全组。

A454123_1_En_15_Fig6_HTML.jpg

图 15-6。

The security group inbound rules are enabled for all traffic

SSH 登录 Swarm manager EC2 实例,从 AWS 管理控制台获取公共 IP 地址,如图 15-7 所示。

A454123_1_En_15_Fig7_HTML.jpg

图 15-7。

Public IP address

使用用于创建云形成栈的密钥对 SSH 登录到 Swarm manager 实例。

ssh -i "docker.pem" docker@54.205.48.154

将显示群管理器节点的命令提示符。

[root@localhost ∼]# ssh -i "docker.pem" docker@54.205.48.154
Welcome to Docker!

列出 Swarm 模式中的节点。

docker node ls

列出了三个节点,一个经理和两个工人。

∼ $ docker node ls
ID                           HOSTNAME                       STATUS  AVAILABILITY  MANAGER STATUS
bf4ifhh86sivqp03ofzhk6c46    ip-172-31-21-175.ec2.internal  Ready   Active        
ozdhl0jtnricny1y95xbnhwtq    ip-172-31-37-108.ec2.internal  Ready   Active        
ud2js50r4livrqf3f4l30fv9r *  ip-172-31-19-138.ec2.internal  Ready   Active        Leader

通过创建并列出 Hello World 服务来测试 Swarm 模式。

docker service create --replicas 2 --name helloworld alpine ping docker.com

docker service ls

docker service命令输出表明 Docker Swarm 服务,因此它被创建并列出。

∼ $ docker service create --replicas 2 --name helloworld alpine ping docker.com
q05fef2a7cf98cv4r2ziyccnv

∼ $ docker service ls
ID             NAME           MODE           REPLICAS       IMAGE          PORTS
q05fef2a7cf9   helloworld     replicated     2/2            alpine:latest       
∼ $

配置服务栈

要创建由两个服务组成的服务栈,一个用于 WordPress 博客,另一个用于 MySQL 数据库,使用 Docker Compose 版本 3 YAML 格式( https://docs.docker.com/compose/compose-file/ )创建一个栈文件。创建一个docker-cloud.yml栈文件(文件名是任意的)来分别使用 Docker 映像wordpressmysql指定两个服务(webmysql)。为 Docker 映像设置环境变量。唯一需要设置的环境变量是mysql Docker 映像的MYSQL_ROOT_PASSWORDwordpress Docker 映像的WORDPRESS_DB_PASSWORD环境变量默认为MYSQL_ROOT_PASSWORD,但也可以明确设置为与MYSQL_ROOT_PASSWORD相同的值。表 15-2 中列出了wordpress Docker 映像使用的其他一些环境变量。

表 15-2。

Environment Variables for the Docker Image WordPress

| 环境变量 | 描述 | 缺省值 | | --- | --- | --- | | `WORDPRESS_DB_HOST` | 链接的数据库主机,默认情况下假定为 MySQL 数据库。 | 链接的`mysql` Docker 容器的 IP 和端口 | | `WORDPRESS_DB_USER` | 数据库用户。 | `root` | | `WORDPRESS_DB_PASSWORD` | 数据库密码。 | `MYSQL_ROOT_PASSWORD` | | `WORDPRESS_DB_NAME` | 数据库名称。如果数据库尚不存在,则创建该数据库。 | `wordpress` | | `WORDPRESS_TABLE_PREFIX` | 表格前缀。 | `“”` |

如果我们要用wordpressmysql图片和docker run命令创建一个 WordPress 博客,我们将为每个 Docker 图片分别创建 Docker 容器,并使用–link选项链接这些容器。如果我们要使用 Docker Compose(独立的),我们需要在 Docker Compose 文件中添加一个linksdepends_on子选项。

接下来,将 Docker 映像和环境变量指定到栈文件中,以创建服务栈。要将 Docker Compose YAML 文件格式用于群组模式栈,请将栈文件中的version指定为3或更高版本,如3.1。列出了docker-cloud.yml文件:

version: '3'
services:
 web:
  image: wordpress

  links:
   - mysql
  environment:
   - WORDPRESS_DB_PASSWORD="mysql"
  ports:
   - "8080:80"
 mysql:
  image: mysql:latest
  environment:
   - MYSQL_ROOT_PASSWORD="mysql"
   - MYSQL_DATABASE="mysqldb"

8080:80ports映射将 WordPress Docker 容器端口 80 映射到主机端口 8080。创建栈时,会忽略任何栈文件选项,例如前面列表中包含的docker stack deploy不支持的链接。将前面的清单作为docker-cloud.yml存储在 Swarm manager EC2 实例中。在 Swarm manager 中列出文件应该会列出docker-cloud.yml文件。

∼ $ ls -l
total 4
-rwxr-x---    1 docker   docker         265 Jun 17 00:07 docker-cloud.yml

配置了包含两个服务的栈文件后,接下来我们将创建一个服务栈。

创建栈

docker stack deploy命令用于创建和部署栈。它具有以下语法。

docker stack deploy [OPTIONS] STACK

表 15-3 中讨论了支持的选项。

表 15-3。

Options for the docker stack deploy Command

| [计]选项 | 描述 | 缺省值 | | --- | --- | --- | | `--bundle-file` | 分布式应用包文件的路径。从 Docker 合成文件创建应用包,就像从 Docker 文件创建 Docker 映像一样。应用包可用于创建栈。在开发本章时,应用包是一个试验性的特性,不在本章中讨论。 |   | | `--compose-file, -c` | 栈文件的路径。 |   | | `--with-registry-` `auth` | 是否向群代理发送注册认证信息。 | 错误的 |

使用栈文件docker-cloud.yml,用docker stack deploy命令创建一个名为mysql的 Docker 栈。

docker stack deploy --compose-file docker-cloud.yml mysql

会创建一个 Docker 栈,并忽略群组模式中不支持的links选项。除了网络mysql_default之外,还创建了两个群服务mysql_mysqlmysql_web

∼ $ docker stack deploy --compose-file docker-cloud.yml mysql
Ignoring unsupported options: links

Creating network mysql_default
Creating service mysql_mysql
Creating service mysql_web

列表栈

使用以下命令列出栈。

docker stack ls

列出了mysql栈。还列出了栈中的服务数量。

∼ $ docker stack ls
NAME   SERVICES

mysql  2

列表服务

使用docker stack services命令列出mysql栈中的服务,其语法如下。

docker stack services [OPTIONS] STACK

表 15-4 中列出了支持的选项。

表 15-4。

Options for the docker stack services Command

| [计]选项 | 描述 | 缺省值 | | --- | --- | --- | | `--filter, -f` | 基于提供的过滤器(或条件)过滤输出 |   | | `--quiet, -q` | 是否只显示服务的 id | `false` |

若要列出所有服务,请运行以下命令。

docker stack services  mysql

列出了两种服务— mysql_mysqlmysql_web

∼ $ docker stack services  mysql
ID            NAME         MODE        REPLICAS  IMAGE
ixv0ykhuo14c  mysql_mysql  replicated  1/1       mysql:latest
vl7ph81hfxan  mysql_web    replicated  1/1       wordpress:latest

要过滤服务,添加--filter选项。要过滤多个服务,添加多个--filter选项,如下面的命令所示。

docker stack services --filter name=mysql_web --filter name=mysql_mysql  mysql

将列出过滤后的栈服务。因为两个服务都是使用–filter指定的,所以两个服务都被列出。

∼ $ docker stack services --filter name=mysql_web --filter name=mysql_mysql mysql
l
ID            NAME         MODE        REPLICAS  IMAGE
ixv0ykhuo14c  mysql_mysql  replicated  1/1       mysql:latest
vl7ph81hfxan  mysql_web    replicated  1/1       wordpress:latest

栈创建的服务是群服务,也可以使用以下命令列出。

docker service ls

列出了相同的两种服务。

∼ $ docker service ls
ID            NAME         MODE        REPLICAS  IMAGE
ixv0ykhuo14c  mysql_mysql  replicated  1/1       mysql:latest
sl2jmsat30ex  helloworld   replicated  2/2       alpine:latest
vl7ph81hfxan  mysql_web    replicated  1/1       wordpress:latest

列出 Docker 容器

docker stack ps命令用于列出栈中的 Docker 容器,其语法如下:使用--help选项输出命令用法。

∼ $ docker stack ps --help
Usage:    docker stack ps [OPTIONS] STACK
List the tasks in the stack
Options:
  -f, --filter filter   Filter output based on conditions provided
      --help            Print usage
      --no-resolve      Do not map IDs to Names
      --no-trunc        Do not truncate output

要列出mysql栈中的所有 Docker 容器,运行以下命令。

docker stack ps mysql

默认情况下,为每个服务创建一个副本,因此为栈中的每个服务列出一个 Docker 容器。两个 Docker 容器都运行在一个 Swarm worker 节点上。

∼ $ docker stack ps mysql
ID             NAME            IMAGE              NODE                           DESIRED STATE   CURRENT STATE           ERROR   PORTS
n9oqwaikd61g   mysql_web.1     wordpress:latest   ip-172-31-37-108.ec2.internal  Running         Running 3 minutes ago         
infzi7kxg9g9   mysql_mysql.1   mysql:latest       ip-172-31-37-108.ec2.internal  Running         Running 3 minutes ago         

使用–f选项过滤 Docker 容器,只列出mysql_web.1容器。

∼ $ docker stack ps -f name=mysql_web.1 mysql
ID             NAME          IMAGE              NODE                           DESIRED STATE   CURRENT STATE           ERROR  PORTS
n9oqwaikd61g   mysql_web.1   wordpress:latest   ip-172-31-37-108.ec2.internal  Running         Running 9 minutes ago   

通过将desired-state过滤器设置为正在运行,列出所有正在运行的容器。

∼ $ docker stack ps -f desired-state=running mysql
ID             NAME            IMAGE              NODE                           DESIRED STATE   CURRENT STATE            ERROR   PORTS
n9oqwaikd61g   mysql_web.1     wordpress:latest   ip-172-31-37-108.ec2.internal  Running         Running 10 minutes ago         
infzi7kxg9g9   mysql_mysql.1   mysql:latest       ip-172-31-37-108.ec2.internal  Running         Running 10 minutes ago         

使用服务栈

接下来,我们使用这个栈来创建一个 WordPress 博客。可以在 Swarm manager 主机的端口8080上访问名为web的栈服务。获取群管理器节点 EC2 实例的公共 DNS,如图 15-8 所示。

A454123_1_En_15_Fig8_HTML.jpg

图 15-8。

Public DNS of Swarm manager

在浏览器中打开<public dns>:8080 URL。显示<public dns>:8080/wp-admin/install.php URL 来开始 WordPress 的安装。选择继续。指定副标题、用户名、密码、电子邮件以及是否阻止搜索引擎对网站进行索引。然后点击安装 WordPress,如图 15-9 所示。

A454123_1_En_15_Fig9_HTML.jpg

图 15-9。

Installing WordPress

安装好 WordPress,如图 15-10 所示。点击登录。

A454123_1_En_15_Fig10_HTML.jpg

图 15-10。

WordPress is installed

指定用户名和密码,点击登录,如图 15-11 所示。

A454123_1_En_15_Fig11_HTML.jpg

图 15-11。

Logging in

显示 WordPress 博客仪表盘,如图 15-12 所示。

A454123_1_En_15_Fig12_HTML.jpg

图 15-12。

The WordPress dashboard

要添加新帖子,请选择帖子并点击“添加新”,如图 15-13 所示。

A454123_1_En_15_Fig13_HTML.jpg

图 15-13。

Adding a new post

在“添加新文章”对话框中,指定标题并添加博客条目。点击发布,如图 15-14 所示。

A454123_1_En_15_Fig14_HTML.jpg

图 15-14。

Publishing a new post

新帖子已添加。点击查看帖子,如图 15-15 所示,显示帖子。

A454123_1_En_15_Fig15_HTML.jpg

图 15-15。

Viewing the new post

显示博文,如图 15-16 所示。

A454123_1_En_15_Fig16_HTML.jpg

图 15-16。

Displaying a blog post

向下滚动并添加注释,如图 15-17 所示。

A454123_1_En_15_Fig17_HTML.jpg

图 15-17。

Adding a comment

添加注释,如图 15-18 所示。

A454123_1_En_15_Fig18_HTML.jpg

图 15-18。

The comment has been added

移除栈

docker stack rm STACK命令用于移除栈。使用以下命令移除mysql栈。

docker stack rm  mysql

删除了mysql栈,并且docker stack service mysql命令没有列出栈,如该命令的输出所示。

∼$ docker stack rm mysql

Removing service mysql_mysql

Removing service mysql_web

Removing network mysql_default

∼$ docker stack services mysql

Nothing found in stack: mysql

摘要

本章介绍了 Docker 1.13 中添加的 Docker 原生特性 stacks。栈是相关服务的集合,使用栈文件创建,栈文件以类似于 Docker Compose v3.x YAML 语法的 YAML 格式定义。本章总结了这本书关于 Docker 管理设计模式的内容。随着 Docker 中新特性的加入,其他设计模式也可以用于开发 Docker 原生应用。