1. Devops/

管理和维护集群的Docker Engine

·264 字·2 分钟· loading
docker devops
demo007x
作者
demo007x

管理和维护集群的Docker Engine
#

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

在集群中操作管理器节点
#

集群管理器节点使用筏raft来管理集群状态。你只需要了解raft的一些一般概念,就能管理集群。

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

Raft要求大多数manager(也称为法定人数)就群的拟议更新达成一致,例如节点添加或删除。会员操作受到与状态复制相同的约束。

保持manager节点的数量
#

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

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

如果您确实失去了manager的法定数量,请参阅从教程,以了解故障排除步骤。

配置管理器
#

启动集群时,我们必须指定--advertise-addr标志,以将我们的地址广播给集群中的其他管理器节点。由于管理器节点应该是基础设施的稳定组件,因此我们应该使用固定的IP地址作为广播地址,以防止群在机器重新启动时变得不稳定。

如果整个集群重新启动,并且每个管理器节点随后获得一个新的IP地址,则任何节点都无法跟现有管理器通信。因此,当节点试图在旧的IP地址上相互联系时,集群会被阻塞。

动态IP地址适用于工作节点。

添加容错管理器节点
#

我们应该在集群中保持奇数的manager,以支持manager节点故障。拥有奇数的manager可以确保在网络分区期间,如果网络被划分为两组,则有更高的机会保留法定人数来处理请求。如果遇到两个以上的网络分区,则不能保证保持法定人数。参考如下:

集群大小 多数 容错
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子系统管理swarm成员。

分发管理器节点
#

除了维护奇数的manager节点外,在放置manager时还要注意数据中心拓扑。为了获得最佳的容错,将管理器节点分布在至少3个可用区域,以支持整套机器的故障或常见的维护场景。如果在其中任何区域出现故障,集群应保持可用于处理请求和重新平衡工作量的manager节点的法定人数。

群管理器节点 重新分区(在3个可用区域)
3 1-1-1
5 2-2-1
7 3-2-2
9 3-3-3

运行仅限管理器的节点
#

默认情况下,管理器节点也充当工作节点。这意味着调度器可以将任务分配给管理器节点。对于小型和非关键的集群,只要我们使用CPU内存资源约束来安排服务,就将任务分配给manager的风险相对较低。

然而,由于管理器节点使用Raft共识算法以一致的方式复制数据,它们对资源匮乏很敏感。所以应该将集群中的manager与可能阻止集群行动(如集群心跳或领导人选举)的过程隔离开来。

为了避免干扰管理器节点操作,我们可以耗尽管理器节点,使其作为工作节点不可用:

 docker node update --availability drain <NODE>

当耗尽节点时,调度器会将节点上运行的任何任务重新分配给群中其他可用的工作节点。它还阻止调度程序将任务分配给节点。

添加工作节点进行负载平衡
#

只要工作节点与服务的要求相匹配,复制的服务任务就会随着时间的推移尽可能均匀地分布在群中。当限制服务仅在特定类型的节点上运行时,例如具有特定CPU数量或内存量的节点,不符合这些要求的工作节点无法运行这些任务。

监测群体健康
#

我们可以通过查询docker nodes API 以 JSON格式通过/nodes HTTP端点来监视管理节点的健康状况。

从命令行运行docker node inspect <id-node>来查询节点。例如,要查询节点作为管理器的可访问性:

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

要查询节点作为接受任务的工作的状态:

 docker node inspect manager1 --format "{{ .Status.State }}"

从这些命令中,我们可以看到manager1既处于reachable作为manager的状态,又作为工作ready`。

unreachable的健康状态意味着这个特定的管理器节点无法从其他管理器节点访问。在这种情况下,我们需要采取行动来恢复无法访问的管理器:

  • 重新启动守护进程,看看manager是否恢复可访问。
  • 重新启动机器。
  • 如果重新启动或重新启动都不起作用,应该添加另一个管理器节点或将worker提升为管理器节点。您还需要从带有docker node demote <NODE>docker node rm <id-node>的管理器设置中清除失败的节点条目。

或者,您还可以从具有docker node ls的管理器节点获得群健康概述:

 docker node ls

对管理器节点进行故障排除
#

永远不应该通过从另一个节点复制raft目录来重新启动管理器节点。数据目录是节点ID的唯一。节点只能使用一次节点ID加入集群。节点ID空间应该是全局唯一的。

要干净地将管理器节点重新加入集群:

  1. 使用docker node demote <NODE>将节点降级为worker。
  2. 使用docker node rm <NODE>从群中删除节点。
  3. 使用docker swarm join将节点重新加入到具有新状态的群中。

强行删除一个节点
#

在大多数情况下,我们应该先关闭节点,然后再使用docker node rm命令将其从群中移除。如果节点无法访问、无响应或被破坏,您可以通过传递--force标志来强制删除节点,而无需关闭它。例如,如果node2被泄露:

$ docker node rm node2

Error response from daemon: rpc error: code =  desc = node node2 is not down and can't be removed

$ docker node rm --force node2

Node node2 removed from swarm

在强制删除管理器节点之前,您必须首先将其降级到工作角色。如果您降级或删除manager,请确保您始终有奇数的manager节点。

集群备份
#

Docker管理器节点将群状态和管理器日志存储在/var/lib/docker/swarm/目录中。这些数据包括用于加密Raft日志的密钥。没有这些文件,我们就无法恢复集群。

我们可以使用任何管理器备份集群。使用以下程序。

  1. 如果集群启用了自动锁定,需要解锁密钥才能从备份中恢复集群。如有必要,检索解锁密钥并将其存储在安全的位置。

  2. 在备份数据之前,在管理器上停止Docker,这样在备份期间就不会更改数据。可以在manager运行时进行备份(“热”备份),但不建议这样做,并且在恢复时您的结果更难预测。当管理器停机时,其他节点继续生成不属于此备份一部分的群数据。

    注意:

    一定要保持集群manager的法定人数。在manager关闭期间,如果丢失更多节点,您的集群更容易失去法定人数。你管理的manager数量是一种取舍。如果定期删除manager进行备份,请考虑运行五个manager群,这样就可以在备份运行时失去另一个manager,而不会中断服务。

  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. 添加管理器和工作节点,使我们的新集群达到可接受服务请求 s。

  8. 在新集群上恢复我们之前的备份数据。

恢复管理节点的数量
#

Swarm对故障有弹性,可以从任何数量的临时节点故障(机器重新启动或重新启动时崩溃)或其他瞬态错误中恢复。然而,如果群体失去法定人数,它就无法自动恢复。现有工作节点上的任务继续运行,但无法执行管理任务,包括扩展或更新服务以及从集群中加入或删除节点。恢复的最佳方法是将丢失的管理器节点重新联机。

在集群manager中,必须始终有法定人数(大多数)的manager节点。例如,在有五名manager的集群中,至少有三名manager必须处于运通信状态并互联互通。换句话说,集群可以容忍高达(N-1)/2的永久故障,超过这些故障,涉及集群管理的请求无法处理。这些类型的故障包括数据损坏或硬件故障。

如果你失去了manager 的法定人数,就无法管理集群。如果失去了法定人数,并且尝试对集群执行任何管理操作,则会发生错误:

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

从失去法定人数中恢复过来的最好方法是让失败的节点重新上线。如果我们无法做到这一点,从此状态中恢复的唯一方法是使用来自管理器节点的--force-new-cluster操作。这将删除运行命令的manager以外的所有manager。达到法定人数是因为现在只有一位manager。将节点提升为manager,直到拥有所需的manager人数。

从要恢复的节点,运行:

 docker swarm init --force-new-cluster --advertise-addr node01:2377

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

让集群重新负载均衡
#

一般来说,我们不需要强迫集群重新平衡其任务。当向群添加新节点时,或者节点在一段时间不可用后重新连接到集群时,集群不会自动给空闲节点提供工作负载, Docker swarm 就是这么设计的,如果为了实现平衡,集群定期将任务转移到不同的节点,则使用这些任务的客户端将被中断。为了整个集群的平衡,目标是避免中断运行服务。当新任务开始时,或者当具有运行任务的节点不可用时,这些任务将提供给不太繁忙的节点。目标是最终平衡,尽量减少对最终用户的干扰。

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

参考:
#

https://docs.docker.com/engine/swarm/admin_guide/#recover-from-losing-the-quorum

https://docs.docker.com/engine/swarm/admin_guide/#recover-from-disaster

Related

管理集群服务网络
docker devops
管理集群服务网络
锁定集群以保护加密文件
docker devops
锁定集群以保护加密文件
使用Docker secret 管理敏感数据
docker devops
使用Docker secret 管理敏感数据