管理和维护大量的Docker引擎

预计阅读时间:16分钟

当运行Docker Engine群时,管理器节点是用于管理群和存储群状态的关键组件。重要的是要了解管理器节点的一些关键功能,以正确部署和维护集群。

请参阅节点的工作方式 ,以简要概述Docker Swarm模式以及管理者节点和工作节点之间的区别。

大量操作管理器节点

群管理器节点使用筏共识算法来管理群状态。您只需要了解Raft的一些一般概念即可管理群体。

管理器节点的数量没有限制。关于要实现多少个管理器节点的决定是性能和容错之间的权衡。将管理器节点添加到群集可以使群集具有更高的容错能力。但是,额外的管理器节点会降低写入性能,因为更多的节点必须确认提议以更新群集状态。这意味着更多的网络往返流量。

Raft要求大多数管理者(也称为法定人数)就群集的提议更新达成共识,例如增加或删除节点。成员资格操作受与状态复制相同的约束。

维持管理者的法定人数

如果群集失去了管理者的法定人数,则群集将无法执行管理任务。如果您的团队有多个管理者,则总是要有两个以上。为了维持法定人数,必须有大多数经理。建议使用奇数个管理器,因为下一个偶数不会使仲裁更容易保持。例如,无论您有3位经理还是4位经理,您仍然只能失去1位经理并维持法定人数。如果您有5或6名经理,您仍然只能丢掉2名。

即使群集失去了管理者的法定人数,现有工作节点上的群集任务仍会继续运行。但是,无法添加,更新或删除群集节点,并且无法启动,停止,移动或更新新任务或现有任务。

如果您确实丢失了管理者的法定人数,请参阅从失去法定人数中恢复以获取故障排除步骤。

配置管理器以在静态IP地址上发布

启动集群时,必须指定--advertise-addr标志以将地址发布给集群中的其他管理器节点。有关更多信息,请参阅以swarm模式运行Docker Engine。由于管理器节点是基础架构的稳定组件,因此应将固定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个节点的集群中,如果丢失3个节点,则没有法定人数。因此,只有在恢复不可用的管理器节点之一或使用灾难恢复命令恢复群集之前,才能添加或删除节点。请参阅从灾难中恢复

尽管可以将群缩小到单个管理器节点,但无法降级最后一个管理器节点。这样可以确保您保持对群集的访问,并且群集仍可以处理请求。缩减到单个管理器是不安全的操作,不建议这样做。如果在降级操作期间最后一个节点意外离开群集,则群集将不可用,直到您重新启动节点或使用重启为止 --force-new-cluster

您可以使用docker swarmdocker node 子系统管理群体成员资格。请参阅将节点添加到群集以获取有关如何添加工作程序节点并将工作程序节点提升为管理员的更多信息。

分配管理器节点

除了维护奇数个管理器节点外,放置管理器时还应注意数据中心拓扑。为了获得最佳的容错能力,请在至少3个可用区中分布管理器节点,以支持整个计算机组或常见维护方案的故障。如果您在这些区域中的任何一个区域均遇到故障,则群集应维持可用于处理请求和重新平衡工作负载的管理器节点的法定人数。

群管理器节点 分区(在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通过/nodesHTTP端点以JSON格式查询docker API来监视管理器节点的运行状况。 有关更多信息,请参考 节点API文档

在命令行中,运行docker node inspect <id-node>以查询节点。例如,要查询节点作为管理者的可达性:

docker node inspect manager1 --format "{{ .ManagerStatus.Reachability }}"
reachable

要查询节点作为接受任务的工作器的状态,请执行以下操作:

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来加入群集。节点ID空间应该是全局唯一的。

要将管理器节点完全重新加入集群,请执行以下操作:

  1. 要将节点降级为工作线程,请运行docker node demote <NODE>
  2. 要从群集中删除节点,请运行docker node rm <NODE>
  3. 使用,以新的状态将节点重新加入群集docker swarm join

有关将管理器节点加入群集的更多信息,请参阅将 节点加入群集

强制删除节点

在大多数情况下,您应该先关闭节点,然后再使用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管理器节点将群集状态存储在管理器日志中 /var/lib/docker/swarm/。此数据包括用于加密Raft日志的密钥。没有这些密钥,您将无法还原群集。

您可以使用任何管理器备份群集。使用以下步骤。

  1. 如果群集已启用自动锁定,则需要解锁密钥才能从备份中还原群集。如有必要,取回解锁钥匙,并将其存放在安全的地方。如果不确定,请阅读 锁定群以保护其加密密钥

  2. 在备份数据之前,请在管理器上停止Docker,以便在备份期间不更改任何数据。可以在管理器运行时进行备份(“热”备份),但是不建议这样做,并且还原时结果的可预测性较差。当管理器关闭时,其他节点继续生成不属于此备份的群集数据。

    笔记

    确保维持群体管理者的法定人数。在关闭管理器的时间内,如果丢失更多节点,您的集群更容易丢失仲裁。您所管理的经理人数是一个折衷方案。如果您定期关闭管理器以进行备份,请考虑运行五个管理器群,以便在运行备份时可以失去一个额外的管理器,而不会中断您的服务。

  3. 备份整个/var/lib/docker/swarm目录。

  4. 重新启动管理器。

要还原,请参阅从备份还原

从灾难中恢复

从备份还原

按照“备份群集”中的说明 备份群集之后,请使用以下过程将数据还原到新的群集中。

  1. 关闭目标主机上的Docker,以获取已恢复的群集。

  2. 删除/var/lib/docker/swarm新群集上目录的内容。

  3. /var/lib/docker/swarm使用备份内容还原目录。

    笔记

    新节点使用与旧节点相同的磁盘上加密密钥。目前无法更改磁盘上的存储加密密钥。

    在启用了自动锁定的群集的情况下,解锁密钥也与旧群集上的密钥相同,并且需要使用解锁密钥来还原群集。

  4. 在新节点上启动Docker。如有必要,解锁群组。使用以下命令重新初始化群集,以使该节点不会尝试连接到旧群集中的节点,并且可能不再存在。

    $ docker swarm init --force-new-cluster
    
  5. 验证群集的状态是否符合预期。这可能包括特定于应用程序的测试或仅检查输出 docker service ls以确保所有预期的服务都存在。

  6. 如果您使用自动锁定,请 旋转解锁键

  7. 添加管理器节点和辅助节点,以使您的新群集发挥最大的操作能力。

  8. 在新群集上恢复以前的备份方案。

从丢失仲裁中恢复

群集可以对故障进行恢复,并且群集可以从任何数量的临时节点故障(计算机重新启动或因重新启动而崩溃)或其他临时错误中恢复。但是,如果群失去定额,则无法自动恢复。现有工作节点上的任务继续运行,但是管理任务是不可能的,包括扩展或更新服务以及从群集中加入或删除节点。最好的恢复方法是使丢失的管理器节点重新联机。如果无法做到这一点,请继续阅读一些有关恢复群的选项。

在成群的N管理器中,一定数量(多数)的管理器节点必须始终可用。例如,在一个由五名管理人员组成的团队中,至少有三名必须是可操作的并且彼此通信。换句话说,群集可以忍受(N-1)/2永久性故障,超过这些永久性故障将无法处理涉及群集管理的请求。这些类型的故障包括数据损坏或硬件故障。

如果您失去了管理者的法定人数,则无法管理这些群体。如果丢失了仲裁,并且尝试对群集执行任何管理操作,则会发生错误:

Error response from daemon: rpc error: code = 4 desc = context deadline exceeded

从丢失仲裁中恢复的最佳方法是使发生故障的节点重新联机。如果不能这样做,从此状态中恢复的唯一方法是使用--force-new-cluster管理器节点中的操作。这将除去所有运行命令的管理器以外的管理器。之所以达到法定人数,是因为现在只有一名经理。提升节点成为管理员,直到拥有所需数量的管理员为止。

# From the node to recover
docker swarm init --force-new-cluster --advertise-addr node01:2377

docker swarm init使用带有--force-new-cluster 标志的命令运行命令时,运行命令的Docker引擎将成为能够管理和运行服务的单节点集群的管理器节点。管理器具有有关服务和任务的所有先前信息,工作节点仍然是群集的一部分,并且服务仍在运行。您需要添加或重新添加管理器节点以实现以前的任务分配,并确保您有足够的管理器来维持高可用性并防止丢失仲裁。

迫使群重新平衡

通常,您不需要强制群集重新平衡其任务。在将新节点添加到群集时,或者在一段时间不可用之后节点重新连接到群集时,群集不会自动将工作负载分配给空闲节点。这是设计决定。如果为了平衡起见,群集会定期将任务转移到其他节点,则使用这些任务的客户端将受到干扰。目的是避免为了平衡整个集群而中断正在运行的服务。当新任务开始时,或者当具有正在运行的任务的节点不可用时,这些任务将分配给不那么繁忙的节点。目标是最终实现平衡,同时最大程度地减少对最终用户的干扰。

您可以在命令中使用--force-f标志,docker service update以强制服务在可用的工作节点上重新分配其任务。这将导致服务任务重新启动。客户端应用程序可能会中断。如果已配置它,那么您的服务将使用滚动更新

如果您使用的是较早版本,并且希望在各个工作人员之间实现平均负载平衡,并且不介意中断正在运行的任务,则可以通过临时向上扩展服务来强制您的群集重新平衡。使用 docker service inspect --pretty <servicename>看服务的配置比例。使用时docker service scale,任务数量最少的节点将用于接收新的工作负载。群中可能有多个负载不足的节点。您可能需要几次以适度的增量扩展服务,以在所有节点上实现所需的平衡。

当负载达到您的满意平衡时,您可以将服务缩减到原始规模。您可以docker service ps用来评估跨节点的当前服务平衡。

另请参阅 docker service scaledocker service ps

码头工人集装箱经理