Docker Swarm 进阶:服务管理与动态伸缩

在 Docker Swarm 集群中,“服务 (Service)” 是我们部署和管理应用的核心概念。你可以把服务看作是运行在集群中的一组容器的定义。Swarm 会确保指定数量的服务实例(称为“任务”或“副本”)始终在运行,并且可以轻松地对服务进行伸缩和更新。

这篇实验手册将引导你学习如何在 Swarm 集群中部署、管理和更新服务。

操作前提
请确保你已经拥有一个初始化完成的 Docker Swarm 集群,并且当前操作是在管理节点 (manager node) 上执行,除非特别说明。

让我们部署一个简单的 alpine 容器服务,它会持续 ping baidu.com

服务命名规范
请将命令中的 s0000 部分替换为你的学号后两位,例如 s25

bash

docker service create --replicas 1 --name s00 alpine ping baidu.com
  • docker service create: 创建新服务的命令。
  • --replicas 1: 指定服务需要运行 1 个实例(副本)。
  • --name s00: 为服务指定一个名称。
  • alpine: 使用的 Docker 镜像。
  • ping baidu.com: 在容器内执行的命令。

部署服务后,我们可以查看当前 Swarm 集群中所有服务的列表。

bash

docker service ls

你会看到类似下面的输出,其中包含了服务的 ID、名称、模式(默认为 replicated)、副本数(REPLICAS)、镜像和端口等信息。

一个服务由一个或多个“任务 (Task)”组成,每个任务就是一个运行中的容器实例。

bash

docker service ps s00

这个命令会列出名为 s00 的服务包含的所有任务,以及它们的状态(例如 Running)、所在的节点等。

Swarm 的一大优势就是可以轻松地对服务进行扩容或缩容。现在,我们将 s00 服务的副本数量增加到 3 个。

bash

docker service scale s00=3

Swarm 会自动在集群中调度并启动新的任务,直到达到指定的副本数量。

再次查看服务列表和任务列表,确认服务的副本数和任务状态。

bash

docker service ls

bash

docker service ps s00

你会发现 s00 服务现在有 3 个正在运行的任务了。

Swarm 会将服务的任务(容器)分布到集群中的不同节点上以实现负载均衡和高可用。你可以在不同的节点(包括管理节点和工作节点)上执行 docker ps 来查看本地正在运行的容器。

在某个节点上执行:

bash

docker ps

你会看到该节点上可能运行着 s00 服务的一个或多个任务实例。

如果不再需要某个服务,可以将其从 Swarm 集群中删除。

bash

docker service rm s00

删除服务后,Swarm 会停止并移除与该服务相关的所有任务(容器)。

验证:

在管理节点上执行 docker service ls,确认 s00 服务已不存在。

在各个节点上执行 docker ps,确认之前运行的 s00 服务的容器也已经被清除了。

滚动更新是 Swarm 提供的强大功能,可以在不中断服务的情况下,平滑地将服务升级到新的版本。

首先,我们部署一个 redis:4.0 服务。这次我们使用 --mode global 参数,这意味着每个集群节点上都会运行一个该服务的实例。

服务命名规范
请将命令中的 redis0000 部分替换为你的学号后两位,例如 redis25

bash

docker service create --mode global --name redis00 redis:4.0
  • --mode global: 指定服务为全局模式。与之对应的是 replicated 模式(默认),可以指定副本数量。

查看 redis00 服务的任务列表。

bash

docker service ps redis00

你会发现任务的数量与集群中活动节点的数量一致,每个节点上都有一个 redis00 的任务在运行。

现在,我们将 redis00 服务从 redis:4.0 版本升级到 redis:5.0 版本。

bash

docker service update redis00 --image redis:5.0
  • docker service update redis00: 指定要更新的服务名称。
  • --image redis:5.0: 指定新的镜像版本。

Swarm 会逐个节点地停止旧版本的任务,并启动新版本的任务,以确保服务的连续性。

在更新过程中或更新完成后,查看服务的任务列表。

bash

docker service ps redis00

你可能会观察到一些任务正在关闭 (Shutdown),而另一些新版本的任务正在启动 (Running)。最终,所有任务都会更新到 redis:5.0 版本。

为了进一步熟悉滚动更新的过程,让我们将服务再次升级到 redis:6.0

bash

docker service update redis00 --image redis:6.0

bash

docker service ps redis00

确认所有任务都已成功更新到 redis:6.0

滚动更新完成
通过滚动更新,你可以平滑地升级你的应用版本,而用户几乎不会察觉到服务的任何中断。

尝试将 Portainer (一个 Docker 图形化管理工具) 作为一个服务部署到你的 Swarm 集群中。思考一下,Portainer 应该部署为全局服务还是副本服务呢?