一个Swarm是一组Docker引擎或节点的集群,并在这个集群之上部署服务和应用。我们可以使用Docker命令行工具或者API管理集群中的节点,并且还可以通过Swarm部署和编排相应的服务。当我们没有使用Swarm模式的时候,我们只是简单地对容器进行操作;而在Swarm模式下,我们就可以对服务进行编排。值得注意的是,在同一个Docker实例上既可以运行Swarm的服务,也可以运行独立的容器。

本文目录:

服务更新与回滚

Docker Swarm集群管理中支持服务的版本更新及回滚操作,具体演示如下:

所使用的系统环境环境如下:

  • 三个节点(manager, worker1, worker2)均为Ubuntu16.04,即xenial64系统
  • 节点的IP分布,manager(172.28.128.3), worker1(172.28.128.4), worker2(172.28.128.5)

首先,我们将Redis 3.0.6版本部署到Swarm集群中,并指定10s的更新时延。

# 在manger节点上
$ docker service create --replicas 3 --name redis --update-delay 10s redis:3.0.6

# --update-delay参数配置服务任务或任务集的更新的时延
# 其格式为T1hT2mT3s,即T1小时T2分钟T3秒
# 默认情况下,更新调度程序一次更新一个任务。但是,可以配置--update-parallelism参数指定同时更新的最大服务任数
# 默认情况下,当一个任务更新并返回RUNNING状态后,更新调度程序才调度另一个任务进行更新,直到所有的任务更新完成。
# 如果某个任务更新返回FAILED状态,更新调度程序则停止更新。
# 当然,也可以通过配置--update-failure-action参数指定服务创建和更新,例如:
# --update-failure-action docker service create
# --update-failure-action docker service update

# 接下来,我们更新redis的镜像
$ docker service update --image redis:3.0.7 redis

如前所述,默认情况下,更新主要包括以下几个流程:

  • 停止第一个任务
  • 调度器更新已经停止的任务
  • 为更新过的任务启动容器
  • 若任务更新返回RUNNING状态,则等待设定的时延,并进行下一个任务的更新
  • 若任务更新返回FAILED状态,则停止更新

更新结束后,我们看到如下状态:

$ docker service ps redis
ID            NAME         IMAGE        NODE           DESIRED STATE  CURRENT STATE                ERROR  PORTS
i9c6xvbopko2  redis.1      redis:3.0.7  ubuntu-xenial  Running        Running 5 seconds ago
mnw258z0j5hg   \_ redis.1  redis:3.0.6  ubuntu-xenial  Shutdown       Shutdown 5 seconds ago
iu7yjb7nm345  redis.2      redis:3.0.7  ubuntu-xenial  Running        Running 53 seconds ago
fmgyoq4vladx   \_ redis.2  redis:3.0.6  ubuntu-xenial  Shutdown       Shutdown 54 seconds ago
zsliph02ycsf  redis.3      redis:3.0.7  ubuntu-xenial  Running        Running about a minute ago
8j75vwiunh49   \_ redis.3  redis:3.0.6  ubuntu-xenial  Shutdown       Shutdown about a minute ago

由此我们可以判断,在服务/任务更新的过程中,实质上是 创建了一批新的容器来满足我们的更新时所指定的新的需求

路由网格

Docker Swarm模式下可以轻松地配置PublishedPort,使外部可以访问到Swarm集群中的资源。所有的节点都参与到入口路由网格。路由网格使得Swarm集群中的每个节点能够接受已发布端口上的任何服务,即使节点上没有正在运行的任务。路由网格将所有传入请求路由到可用节点的已发布端口的活动容器上

为了保证在Swarm中使用入口网络,在启用Swarm模式时需要打开以下端口:

  • Port 7946[TCP/UDP]用于容器网络的发现
  • Port 4789[UDP]用于容器入口网络

当然,还必须打开Swarm集群节点和任何需要访问外部资源之间已发布的端口。

# --publish参数用于指定服务端口,--publish <PublishedPort>:<TARGET-PORT>
# <TARGET-PORT>是容器监听的端口
# <PublishedPort>是Swarm对外服务的端口
$ docker service create --name myweb --publish 8080:80 --replicas 2 nginx

默认情况下,当我们发布一个端口时,默认指定为TCP端口。但是,有时我们需要仅指定TCP端口或UDP端口,可进行如下设置。

# 仅指定TCP端口
$ docker service create --name dns-cache -p 53:53 dns-cache
$ docker service create --name dns-cache -p 53:53/tcp dns-cache
# 以上两个命令是等价的,因为默认情况下即为TCP端口

# 同时指定TCP和UDP端口
$ docker service create --name dns-cache -p 53:53/tcp -p 53:53/udp dns-cache

# 仅指定UDP端口
$ docker service create --name dns-cache -p 53:53/udp dns-cache