这是Nomad构建弹性基础架构系列文章的第四篇也是最后一篇(第1部分,第2部分,第3部分)。在本系列文章中,我们将探讨Nomad如何处理意外故障、停机和集群基础设施的常规维护,通常不需要操作员干预。
在这篇文章中,我们将探索Nomad的设计和使用Raft一致性算法来提供数据丢失的弹性,以及如何从停机中恢复。
我们将假设一个生产部署,建议最少使用3或5个Nomad服务器。有关在生产中部署Nomad集群的信息,请参阅引导Nomad集群。
您可以从本系列的第2篇文章中回忆起,Nomad集群是由运行Nomad代理的节点组成的,可以是server模式,也可以是client模式。客户端负责运行任务,而服务端负责管理集群。客户端节点占集群的大部分,并且非常轻量级,因为它们与服务端节点交互,并且维护自己的状态非常少。每个集群通常有3或5个sercer模式代理,而可能有数千个客户端代理。
Nomad将基础架构建模为区域(regions)和数据中心(datacenters)。一个区域可能包含多个数据中心。例如,“us”区域可能有一个“us-west”和“us-east”数据中心。Nomad服务端管理状态,并为分配它们的区域做出调度决策。
Nomad 和 Raft
Nomad使用基于Raft算法的一致性协议,为一个区域内跨服务器的节点提供数据一致性。Raft节点总是处于以下三种状态之一:follower、candidate或leader。所有节点一开始都是follower。在这种状态下,节点可以接受来自leader的日志条目并进行投票。如果在一段时间内没有收到条目,节点会自动提升到candidate状态。在candidate状态中,节点请求同伴的投票。如果一个candidate获得多数选票,那么他就会被提升为leader。leader必须接受新的日志条目,并复制到所有其他candidate。
在大多数节点可用的情况下,基于Raft的共识是容错的。否则,就不可能处理日志条目或考虑对等成员关系。
例如,由3个节点组成的Raft集群可以容忍1个节点故障,因为剩下的2个服务器构成了多数仲裁。一个由5个节点组成的集群可以容忍2个节点故障,等等。建议的配置是在每个区域运行3个或5个Nomad服务器。这可以在不牺牲性能的情况下最大化可用性。下面的部署表总结了可能的集群大小选项和每个选项的容错。
服务器 | 合法数 | 容忍失败 |
---|---|---|
1 | 1 | 0 |
2 | 2 | 0 |
3 | 2 | 1 |
4 | 3 | 1 |
5 | 3 | 2 |
6 | 4 | 2 |
7 | 4 | 3 |
Nomad的容错能力意味着您可能会遇到两种类型的中断:
- 区域内少数服务器的失败,不会导致仲裁的损失
- 区域内大多数服务器的失败,导致仲裁的损失
每个场景都有不同的恢复过程。
从少数服务器数量故障中恢复(不损失仲裁)
Nomad对Raft的使用意味着少数服务器的故障对客户端来说是透明的。集群操作将继续在客户端正常运行,服务端将继续调度作业并监视集群。
但是,为了防止在服务端节点出现进一步故障时数据丢失,应该通过修复或替换失败的服务端并将它们重新连接到集群来恢复集群的完全健康。这需要操作员的干预,但过程相当简单。
对于每个失败的服务器,首先尝试将失败的服务器重新联机,并让它以与以前相同的IP地址重新加入集群。如果您需要重新构建一个新服务器来替换失败的服务器,让新服务器使用与失败服务器相同的IP地址加入集群。一旦所有失败的服务器重新连接,这两种情况都将使集群恢复到完全健康的状态。
如果重新构建的服务器不能具有与其正在替换的服务器相同的IP地址,则需要从集群中删除失败的服务器。自动驾驶仪的一部分会自动进行服务器清理。操作员还可以使用 nomad server force-leave命令手动删除服务器。如果该命令无法删除服务器,请使用nomad operator raft remove-peer 命令在没有停机的情况下动态删除陈旧的对等服务器。
从大多数服务器数量的失败中恢复(仲裁损失)
如果一个区域内的大多数服务器出现故障,则会丢失仲裁,从而导致在控制平面上完全停机,可能还会丢失一些数据。幸运的是,可以使用剩余服务器上的数据进行部分恢复。这需要操作员的干预。另外,需要注意的是,Nomad服务器宕机并不一定意味着工作负载已经停止。如果Nomad客户机及其主机处于运行状态,工作负载将继续运行,而只是Nomad服务器没有仲裁。
简单地说,恢复过程包括停止所有剩余的服务器,创建一个raft/peer.json中包含所有剩余服务器的条目,然后重启它们。一旦其余的服务器都以相同的raft/peer.json配置重新启动,集群应该能够选举一个leader。您稍后引入的任何新服务器,例如恢复多数仲裁,都可以使用完全干净的数据目录,并使用Nomad的server join
命令进行连接。
在极端的情况下,应该可以仅使用一个剩余的服务器进行恢复,方法是启动该服务器,并将其本身作为raft/peer.json恢复文件中的唯一对等点。
然而,使用raft/peers.json用于恢复会导致未提交的Raft log条目被隐式提交,因此只有在宕机之后才应该使用它,因为没有其他选项可用来恢复丢失的服务器。确保您没有任何自动的进程,将对等文件放在适当的定期基础上。
有关从任何类型的停机恢复的完整详细信息,请参阅停机恢复。
停机和地区
在某些情况下,对于可用性或可伸缩性,您可以选择运行多个区域。Nomad支持将多个区域联合成一个集群。
一个区域通常映射到一个大的地理区域,例如美国或欧洲,可能有多个区域,这些区域映射到数据中心,如us-west和us-east。属于相同数据中心的节点应该进行合并(它们应该共享本地LAN连接)。
区域是调度边界。它们完全独立于彼此,不共享工作、客户或国家。它们使用WAN上的gossip协议松散耦合,该协议允许用户向任何区域提交作业,或透明地查询任何区域的状态。请求被转发到要处理的适当区域中的服务器,并返回结果。数据不会在区域之间复制。这允许区域作为“批量头”,以应对其他区域的故障。
客户机被配置为与其区域服务器通信,并使用远程过程调用(RPC)进行通信,以注册自己、发送心跳以获取活性、等待新的分配以及更新分配状态。
由于Nomad的两层方法,如果您在一个数据中心中丢失了几个Nomad服务器,那么您可能不会经历仲裁的损失,因为在同一区域内的其他数据中心中的服务器都参与了Raft共识的计算。如果您在单个区域中丢失了少数的Nomad服务器,那么您的集群将不会出现停机,您也不必进行任何数据恢复。使用上面提到的过程并在我们的停用指南中详细介绍,将集群恢复到完全健康状态。
如果一个区域内的大多数服务器节点出现故障,那么在控制平面级别将会丢失仲裁和完全停机,并且可能会丢失关于该区域中运行的作业的数据。集群中的其他区域不会受到停机影响。在其他区域运行的作业将继续运行,即使它们是通过受影响区域的Nomad服务器提交的。在受影响的区域,只要Nomad客户机及其主机处于运行状态,工作负载就会继续运行。上面和我们的停用指南中简要介绍了此场景的恢复过程。一旦您恢复了失败的服务器并恢复了集群的健康状态,Nomad就会意识到所有仍在运行和协调状态的作业。
总结
在我们关于用Nomad构建弹性基础架构的系列文章(第1部分,第2部分,第3部分)的第四篇也是最后一篇文章中,我们介绍了Nomad的基础架构模型和Raft 一致性算法的使用如何提供数据丢失的弹性以及如何从停机中恢复。Nomad设计用于优雅地处理客户端和服务器的临时和永久故障,以便于运行高度可靠的基础架构。