管理和维护大量 Docker 引擎
当您运行 Docker 引擎 swarm 时,管理器节点是管理 swarm 和存储 swarm 状态的关键组件。了解管理器节点的一些关键功能对于正确部署和维护集群非常重要。
请参阅 节点如何工作, 以简要概述 Docker Swarm 模式以及管理节点和工作节点之间的区别。
操作集群中的管理节点
Swarm 管理节点使用 Raft 共识算法来管理 Swarm 状态。您只需要了解 Raft 的一些一般概念即可管理 swarm。
管理节点的数量没有限制。关于实施多少个管理器节点的决定是性能和容错性之间的权衡。将管理节点添加到集群中可以使集群具有更高的容错能力。然而,额外的管理节点会降低写入性能,因为更多的节点必须确认更新集群状态的建议。这意味着更多的网络往返流量。
Raft 需要大多数管理者(也称为法定人数)就集群的拟议更新达成一致,例如节点添加或删除。成员资格操作受到与状态复制相同的约束。
维持管理人员的法定人数
如果集群失go了管理者的法定人数,集群就无法执行管理任务。如果您的群体有多个管理者,则始终有两个以上。为了维持法定人数,大多数经理必须有空。建议使用奇数数量的管理器,因为下一个偶数数量不会使法定人数更容易保持。例如,无论您有 3 名还是 4 名经理,您仍然只能失go 1 名经理并维持法定人数。如果你有 5 或 6 名经理,你仍然只能失go两名。
即使 Swarm 失go了法定数量的管理器,现有工作节点上的 Swarm 任务也会继续运行。但是,无法添加、更新或删除 Swarm 节点,并且无法启动、停止、移动或更新新的或现有的任务。
请参阅 从失go法定人数中恢复,了解在失go管理员法定人数时的故障排除步骤。
配置管理器以在静态 IP 地址上进行通告
启动 Swarm 时,您必须指定--advertise-addr
标志以将您的地址通告给 Swarm 中的其他管理节点。有关更多信息,请参阅
以集群模式运行 Docker 引擎。由于管理器节点是基础设施的稳定组件,因此您应该使用固定的 IP 地址作为广告地址,以防止集群在计算机重新启动时变得不稳定。
如果整个群重新启动并且每个管理器节点随后获得新的 IP 地址,则任何节点都无法联系现有管理器。因此,当节点尝试使用旧 IP 地址相互联系时,集群会挂起。
动态 IP 地址适用于工作节点。
添加管理节点以实现容错
您应该在群中维护奇数个管理器以支持管理器节点故障。拥有奇数个管理器可确保在网络分区期间,如果网络被分区为两组,则仲裁仍然可用于处理请求的机会更高。如果遇到两个以上的网络分区,则无法保证保持法定人数。
群体规模 | 多数 | 容错能力 |
---|---|---|
1 | 1 | 0 |
2 | 2 | 0 |
3 | 2 | 1 |
4 | 3 | 1 |
5 | 3 | 2 |
6 | 4 | 2 |
7 | 4 | 3 |
8 | 5 | 3 |
9 | 5 | 4 |
例如,在具有5 个节点的 swarm 中,如果丢失3 个节点,则您没有法定人数。因此,在恢复不可用的管理器节点之一或使用灾难恢复命令恢复集群之前,您无法添加或删除节点。请参阅 从灾难中恢复。
虽然可以将集群缩减为单个管理器节点,但不可能降级最后一个管理器节点。这可确保您保持对 Swarm 的访问,并且 Swarm 仍然可以处理请求。缩减到单个管理器是不安全的操作,不建议这样做。如果最后一个节点在降级操作期间意外离开 swarm,则 swarm 将变得不可用,直到您重新启动该节点或使用 重新启动
--force-new-cluster
。
您可以使用docker swarm
和docker node
子系统管理集群成员资格。有关如何添加工作节点以及如何将工作节点提升为管理器的更多信息,请参阅
将节点添加到集群。
分配管理节点
除了维护奇数个管理器节点外,在放置管理器时还要注意数据中心拓扑。为了获得最佳的容错能力,请将管理器节点分布在至少 3 个可用区域中,以支持整组机器的故障或常见维护场景。如果这些区域中的任何一个发生故障,集群应该维持可用于处理请求和重新平衡工作负载的管理器节点的法定数量。
Swarm 管理节点 | 重新分区(在 3 个可用区上) |
---|---|
3 | 1-1-1 |
5 | 2-2-1 |
7 | 3-2-2 |
9 | 3-3-3 |
运行仅限管理器的节点
默认情况下,管理节点也充当工作节点。这意味着调度程序可以将任务分配给管理节点。对于小型和非关键群体,只要您使用 CPU 和内存资源限制来调度服务,将任务分配给管理器的风险相对较低。
然而,由于管理节点使用Raft共识算法以一致的方式复制数据,因此它们对资源匮乏很敏感。您应该将集群中的管理器与可能阻止集群操作(例如集群心跳或领导者选举)的进程隔离开来。
为了避免干扰管理节点操作,您可以耗尽管理节点以使其不可用作工作节点:
$ docker node update --availability drain <NODE>
当您耗尽节点时,调度程序会将在该节点上运行的任何任务重新分配给集群中的其他可用工作节点。它还阻止调度程序将任务分配给节点。
添加工作节点以实现负载均衡
向集群添加节点以平衡集群的负载。只要工作节点与服务的要求相匹配,复制的服务任务就会随着时间的推移尽可能均匀地分布在集群中。当限制服务仅在特定类型的节点(例如具有特定 CPU 数量或内存量的节点)上运行时,请记住,不满足这些要求的工作节点无法运行这些任务。
监控群体健康状况
nodes
您可以通过 HTTP 端点查询 JSON 格式的docker API 来监控管理器节点的运行状况/nodes
。
有关更多信息,请参阅
节点 API 文档。
从命令行运行docker node inspect <id-node>
以查询节点。例如,查询作为管理器的节点的可达性:
$ docker node inspect manager1 --format "{{ .ManagerStatus.Reachability }}"
reachable
查询节点作为接受任务的worker的状态:
$ docker node inspect manager1 --format "{{ .Status.State }}"
ready
从这些命令中我们可以看出,他既处于管理者的manager1
状态
,又处于工人的状态。reachable
ready
健康unreachable
状态意味着该特定管理器节点无法从其他管理器节点访问。在这种情况下,您需要采取措施恢复无法访问的管理器:
- 重新启动守护程序并查看管理器是否恢复为可访问。
- 重新启动机器。
- 如果重启或重启都不起作用,则应添加另一个管理节点或将工作节点提升为管理节点。您还需要使用
docker node demote <NODE>
和从管理器集中彻底删除失败的节点条目docker node rm <id-node>
。
或者,您还可以使用以下命令从管理器节点获取集群运行状况的概述docker node ls
:
$ docker node ls
ID HOSTNAME MEMBERSHIP STATUS AVAILABILITY MANAGER STATUS
1mhtdwhvsgr3c26xxbnzdc3yp node05 Accepted Ready Active
516pacagkqp2xc3fk9t1dhjor node02 Accepted Ready Active Reachable
9ifojw8of78kkusuc4a6c23fx * node01 Accepted Ready Active Leader
ax11wdpwrrb6db3mfjydscgk7 node04 Accepted Ready Active
bb1nrq2cswhtbg4mrsqnlx1ck node03 Accepted Ready Active Reachable
di9wxgz8dtuh9d2hn089ecqkf node06 Accepted Ready Active
管理节点故障排除
raft
您永远不应该通过从另一个节点复制目录来重新启动管理器节点。数据目录对于节点ID来说是唯一的。一个节点只能使用一次节点 ID 来加入 Swarm。节点ID空间应该是全局唯一的。
要将管理器节点干净地重新加入集群:
- 使用 将该节点降级为工作节点
docker node demote <NODE>
。 - 使用 从群中删除节点
docker node rm <NODE>
。 - 使用 重新将节点加入到新状态的集群中
docker swarm join
。
有关将管理器节点加入 swarm 的更多信息,请参阅 将节点加入 swarm。
强行删除节点
在大多数情况下,您应该先关闭节点,然后再使用该docker node rm
命令将其从集群中删除。如果节点变得无法访问、无响应或受到威胁,您可以通过传递标志来强制删除该节点,而无需将其关闭--force
。例如,如果node9
受到威胁:
$ docker node rm node9
Error response from daemon: rpc error: code = 9 desc = node node9 is not down and can't be removed
$ docker node rm --force node9
Node node9 removed from swarm
在强制删除管理节点之前,必须先将其降级为工作角色。如果降级或删除管理器,请确保管理器节点的数量始终为奇数。
备份集群
Docker 管理器节点将 swarm 状态和管理器日志存储在该
/var/lib/docker/swarm/
目录中。该数据包括用于加密 Raft 日志的密钥。如果没有这些密钥,您将无法恢复 swarm。
您可以使用任何管理器备份集群。使用以下过程。
如果 Swarm 启用了自动锁定,您需要解锁密钥才能从备份恢复 Swarm。如有必要,取回解锁钥匙并将其存放在安全的位置。如果您不确定,请阅读 锁定集群以保护其加密密钥。
在备份数据之前,请停止管理器上的 Docker,以便备份期间不会更改任何数据。可以在管理器运行时进行备份(“热”备份),但不建议这样做,并且恢复时结果不太可预测。当管理器关闭时,其他节点会继续生成不属于此备份一部分的集群数据。
笔记
确保维持群体管理者的法定人数。在管理器关闭期间,如果丢失更多节点,您的集群更容易失go法定人数。你管理的经理的数量是一个权衡。如果您定期删除管理器进行备份,请考虑运行五个管理器群,这样您就可以在备份运行时失go额外的管理器,而不会中断您的服务。
备份整个
/var/lib/docker/swarm
目录。重新启动管理器。
要恢复,请参阅 从备份恢复。
从灾难中恢复
从备份恢复
按照备份 swarm中所述备份 swarm 后 ,使用以下过程将数据恢复到新 swarm。
为恢复的 Swarm 关闭目标主机上的 Docker。
/var/lib/docker/swarm
删除新 swarm 上的目录内容。/var/lib/docker/swarm
使用备份的内容恢复目录。笔记
新节点使用与旧节点相同的加密密钥进行磁盘存储。目前无法更改磁盘存储加密密钥。
对于启用了自动锁定的 Swarm,解锁密钥也与旧 Swarm 上的相同,并且需要解锁密钥来恢复 Swarm。
在新节点上启动 Docker。如有必要,解锁群体。使用以下命令重新初始化 swarm,以便该节点不会尝试连接到属于旧 swarm 的节点,并且可能不再存在。
$ docker swarm init --force-new-cluster
验证集群的状态是否符合预期。这可能包括特定于应用程序的测试或简单地检查输出以
docker service ls
确保所有预期的服务都存在。如果使用自动锁定, 请旋转解锁钥匙。
添加管理器和工作节点以使新集群达到运行容量。
在新群上恢复之前的备份方案。
从失go法定人数中恢复
Swarm 对故障具有弹性,可以从任意数量的临时节点故障(机器重新启动或重新启动时崩溃)或其他暂时性错误中恢复。但是,如果集群失go法定人数,则无法自动恢复。现有工作节点上的任务继续运行,但无法执行管理任务,包括扩展或更新服务以及从集群中加入或删除节点。最好的恢复方法是将丢失的管理器节点重新联机。如果这是不可能的,请继续阅读一些恢复集群的选项。
在管理器群中N
,法定数量(大多数)管理器节点必须始终可用。例如,在拥有五名管理人员的集群中,至少三名管理人员必须处于运行状态并相互通信。换句话说,集群最多可以容忍(N-1)/2
永久性故障,超过该故障则无法处理涉及集群管理的请求。这些类型的故障包括数据损坏或硬件故障。
如果您失go了管理者的法定人数,您就无法管理集群。如果您失go了仲裁并且尝试对 swarm 执行任何管理操作,则会出现错误:
Error response from daemon: rpc error: code = 4 desc = context deadline exceeded
从丢失仲裁中恢复的最佳方法是将发生故障的节点重新联机。如果您无法做到这一点,从该状态恢复的唯一方法是使用--force-new-cluster
管理器节点的操作。这将删除除运行命令的管理器之外的所有管理器。达到法定人数是因为现在只有一名经理。将节点提升为管理者,直到拥有所需数量的管理者。
从要恢复的节点运行:
$ docker swarm init --force-new-cluster --advertise-addr node01:2377
当您docker swarm init
使用该标志运行命令时--force-new-cluster
,运行该命令的 Docker 引擎将成为单节点群的管理节点,能够管理和运行服务。管理器拥有有关服务和任务的所有先前信息,工作节点仍然是集群的一部分,并且服务仍在运行。您需要添加或重新添加管理节点来实现之前的任务分配,并确保您有足够的管理节点来维持高可用性并防止丢失仲裁。
迫使群体重新平衡
通常,您不需要强制集群重新平衡其任务。当您向 swarm 添加新节点,或者某个节点在一段时间不可用后重新连接到 swarm 时,swarm 不会自动将工作负载分配给空闲节点。这是一个设计决定。如果集群为了平衡而定期将任务转移到不同的节点,那么使用这些任务的客户端就会受到干扰。目标是避免中断正在运行的服务,以实现集群之间的平衡。当新任务开始时,或者当正在运行任务的节点变得不可用时,这些任务将被分配给不太繁忙的节点。目标是最终平衡,将对最终用户的干扰降至最低。
您可以在命令中使用--force
或-f
标志docker service update
来强制服务在可用工作节点之间重新分配其任务。这会导致服务任务重新启动。客户端应用程序可能会中断。如果您已配置它,您的服务将使用
滚动更新。
如果您使用早期版本,并且希望在工作人员之间实现负载均衡,并且不介意中断正在运行的任务,则可以通过暂时向上扩展服务来强制集群重新平衡。用于
docker service inspect --pretty <servicename>
查看服务的配置规模。当您使用 时docker service scale
,任务数最少的节点将作为接收新工作负载的目标。您的集群中可能存在多个负载不足的节点。您可能需要通过适度的增量来扩展服务几次,以在所有节点之间实现您想要的平衡。
当负载平衡到您满意的程度时,您可以将服务缩小到原始规模。您可以用来docker service ps
评估节点间服务的当前平衡情况。