游牧民族:问题与解决方案

我在Nomad I中的第一项服务于2016年9月启动。 目前,我使用它作为程序员和两个Nomad集群的管理员的支持-一个用于我的个人项目的“家”(在欧洲5个不同数据中心的Hetzner Cloud和ArubaCloud中有6个微虚拟机),另一个在工作中(大约40个私有虚拟和物理服务器)在两个数据中心)。


在过去的时间里,Nomad环境已经积累了很多经验,在本文中,我将描述Nomad遇到的问题以及如何处理它们。



Yamal Nomad使您的软件连续交付实例©National Geographic Russia


1.每个数据中心的服务器节点数


解决方案:一个服务器节点足以容纳一个数据中心。


文档未明确指出一个数据中心需要多少个服务器节点。 仅表明每个区域需要3-5个节点,这对于筏协议共识是合乎逻辑的。



最初,我在每个数据中心计划了2-3个服务器节点以提供冗余。


经使用证明:


  1. 根本不需要这样做,因为在数据中心发生节点故障的情况下,该数据中心中代理的服务器节点的角色将由该区域中的其他服务器节点扮演。
  2. 如果问题8没有得到解决,那就更糟了。 重新选择该向导时,可能会发生不一致,并且Nomad将重新启动部分服务。

2.服务器节点的服务器资源


解决方案:小型虚拟机足以容纳服务器节点。 在同一服务器上,允许运行其他服务的非资源密集型服务。


Nomad守护程序的内存消耗取决于正在运行的任务数。 CPU消耗-基于区域中的任务数和服务器/代理数(不是线性)。


在我们的例子中:对于300个正在运行的任务,当前主节点的内存消耗约为500 MB。


在工作群集中,是服务器节点的虚拟机:4个CPU,6 GB RAM。
还推出了:Consul,Etcd,Vault。


3.关于缺乏数据中心的共识


解决方案:我们为三个物理数据中心创建了三个虚拟数据中心和三个服务器节点。


Nomad在该区域内的工作基于筏协议。 为了正确操作,您至少需要3个位于不同数据中心的服务器节点。 这将使正确的操作成为可能,并且完全失去与数据中心之一的网络连接。


但是我们只有两个数据中心。 我们做出一个妥协:选择一个我们更信任的数据中心,并在其中创建一个附加服务器节点。 为此,我们引入了一个额外的虚拟数据中心,该虚拟数据中心实际上位于同一数据中心中(请参阅问题1的第2小节)。


替代解决方案:我们将数据中心分为不同的区域。


结果,数据中心独立运行,仅在一个数据中心内需要达成共识。 在数据中心内部,在这种情况下,最好通过在一个物理中心中实现三个虚拟数据中心来制作3个服务器节点。


此选项不太方便进行任务分配,但是在数据中心之间出现网络问题时,可以100%保证服务的独立性。


4.同一服务器上的“服务器”和“代理”


解决方案:如果您的服务器数量有限,则有效。


Nomad文档说这样做是不可取的。 但是,如果您没有机会为服务器节点分配单独的虚拟机,则可以将服务器和代理节点放在同一服务器上。


同时运行意味着在客户端模式和服务器模式下启动Nomad守护程序。


这有什么威胁? 在此服务器的CPU上负载很重时,Nomad服务器节点将无法稳定运行,可能会失去共识和心跳,并会重新加载服务。
为了避免这种情况,我们从问题8的描述中增加了限制。


5.命名空间的实现


解决方案:也许通过组织一个虚拟数据中心。


有时您需要在单独的服务器上运行部分服务。


解决方案是第一个简单,但要求更高的资源。 我们根据用途将所有服务分为几类:前端,后端,...向服务器添加元属性,规定要为所有服务运行的属性。


第二种解决方案很简单。 我们添加了新服务器,为其指定了元属性,为必要的服务指定了这些启动属性,所有其他服务都禁止在具有此属性的服务器上启动。


第三种解决方案很复杂。 我们创建了一个虚拟数据中心:为新数据中心启动Consul,为该数据中心启动Nomad服务器节点,不要忘记该区域的服务器节点数。 现在,您可以在此专用虚拟数据中心中运行各个服务。


6.与保险柜集成


解决方案:避免Nomad <-> Vault循环依赖项。


已启动的保险柜不应与Nomad有任何依赖关系。 在Nomad中注册的保管库地址最好应直接指向保管库,而没有平衡层(但有效)。 在这种情况下,可以通过DNS-Consul DNS或外部进行保管库预订。


如果将保管库数据写入Nomad配置文件中,则Nomad会在启动时尝试访问保管库。 如果访问不成功,则Nomad拒绝启动。


很久以前,我就因周期性依赖而犯了一个错误,这曾经短暂地几乎完全摧毁了Nomad集群。 不管Nomad是什么,Vault都可以正确启动,但是Nomad通过Nomad本身运行的平衡器查看了Vault地址。 Nomad服务器节点的重新配置和重新启动导致平衡器服务的重新启动,这导致无法启动服务器节点本身。


7.启动重要的全状态服务


解决方案:有效,但我无效。


是否可以通过Nomad运行PostgreSQL,ClickHouse,Redis Cluster,RabbitMQ,MongoDB?


想象一下,您有一组重要的服务,其工作与大多数其他服务相关。 例如,PostgreSQL / ClickHouse中的数据库。 或Redis Cluster / MongoDB中的常规短期存储。 或Redis Cluster / RabbitMQ中的数据总线。


所有这些服务都以某种方式实现了容错方案:用于PostgreSQL的Stolon / Patroni,在Redis Cluster中自己的Raft实现,在RabbitMQ,MongoDB,ClickHouse中自己的集群实现。


是的,所有这些服务都可以通过Nomad引用特定服务器来启动,但是为什么呢?


另外-与其他服务一样,易于启动,单一脚本格式。 无需担心ansible脚本/其他任何问题。


减号是其他故障点,它没有任何好处。 就我个人而言,出于各种原因,我两次完全删除了Nomad集群:一次是“回家”,一次是工作。 这是在引进Nomad的早期阶段,并且过于草率。
此外,由于问题编号8,Nomad开始表现不良并重新启动服务。 但是,即使解决了这个问题,危险仍然存在。


8.在不稳定的网络中重新启动工作和服务的稳定性


解决方案:使用心跳调整选项。


默认情况下,对Nomad进行了配置,以便任何短期网络问题或CPU负载都会导致失去共识,并重新选择向导或将代理节点标记为不可访问。 这会导致服务自发重启,并将其转移到其他节点。


解决此问题之前,“家庭”群集的统计信息:重新启动之前,容器的最大寿命约为10天。 在这里,仍然需要在一台服务器上运行代理和服务器,并将其放置在欧洲的5个不同数据中心中,这仍然很重,这意味着CPU负载较大,网络不稳定。


修复问题之前工作集群的统计信息:重新启动之前,容器的最大寿命超过2个月。 这里的一切都比较好,因为Nomad服务器节点使用独立的服务器以及数据中心之间的出色网络。


预设值


heartbeat_grace = "10s" min_heartbeat_ttl = "10s" max_heartbeats_per_second = 50.0 

根据代码判断:在这种配置下,心跳每10秒发出一次。 在丢失两个心跳的情况下,开始重新选择主节点或从代理节点转移服务。 我认为有争议的设置。 我们根据应用程序对其进行编辑。


如果您所有的服务都在多个实例中运行并由数据中心分发,那么很可能对您来说确定服务器不可访问性的时间很长(在下面的示例中大约为5分钟)对于您来说无关紧要-我们降低了心跳间隔的频率,并确定了不可访问性的时间更长。 这是设置家庭集群的示例:


  heartbeat_grace = "300s" min_heartbeat_ttl = "30s" max_heartbeats_per_second = 10.0 

如果您具有良好的网络连接性,请为服务器节点使用单独的服务器,并且确定服务器不可访问性的时间很重要(一个实例中正在运行某些服务,因此快速传输它很重要),然后增加确定不可访问性的时间(heartbeat_grace)。 (可选)您可以执行更多心跳(通过减少min_heartbeat_ttl)-这会稍微增加CPU的负载。 工作集群配置示例:


  heartbeat_grace = "60s" min_heartbeat_ttl = "10s" max_heartbeats_per_second = 50.0 

这些设置可以完全解决问题。


9.开始定期任务


解决方案:可以使用Nomad定期服务,但是cron支持更方便。


Nomad有能力定期启动该服务。


唯一的好处就是这种配置的简单性。


第一个缺点是,如果服务频繁启动,它将乱丢任务列表。 例如,每5分钟启动一次,每小时就会将12个额外的任务添加到列表中,直到GC Nomad触发,这将删除旧任务。


第二点-尚不清楚如何正确配置对此类服务的监视。 如何理解服务的开始,实现和完成工作?


结果,对我自己来说,我来到了定期任务的“ cron”实现:


  1. 它可以是不断运行的容器中的常规cron。 Cron定期运行某个脚本。 脚本运行状况检查很容易添加到这样的容器中,该容器检查创建运行脚本的任何标志。
  2. 它可以是一个持续运行的容器,并具有持续运行的服务。 服务内部已经实施了定期启动。 可以将类似的script-healthcheck或http-healthcheck轻松添加到此类服务,该服务可通过其“内部”立即检查状态。

目前,我大部分时间都是用Go编写的,我更喜欢使用http healthcheck的第二个选项-在Go和定期启动时,并在http healthcheck'i中添加了几行代码。


10.提供冗余服务


解决方案:没有简单的解决方案。 还有两个更困难的选择。


Nomad开发人员提供的配置方案用于支持运行中的服务数量。 您说游牧民族“向我启动了5个服务实例”,然后他从那里启动了它们。 无法控制分发。 实例可以在同一服务器上运行。


如果服务器崩溃,则实例将转移到其他服务器。 在传输实例时,该服务不起作用。 这是坏准备金的选择。


我们做对了:


  1. 我们通过distinct_hosts在服务器上分发实例。
  2. 我们在数据中心之间分布实例。 不幸的是,仅通过创建具有相同内容,不同名称和不同数据中心启动指示的形式为service1,service2形式的脚本的副本即可。

在Nomad 0.9中,将出现解决此问题的功能:可以在服务器和数据中心之间按百分比分配服务。


11. Web UI游牧


解决方案:内置的UI太糟糕了,hashi-ui很漂亮。


控制台客户端执行大多数必需的功能,但是有时您想查看图形,按按钮...


Nomad具有内置的UI。 这不是很方便(甚至比控制台差)。



我知道的唯一替代方法是hashi-ui



实际上,现在我个人仅需要控制台客户端进行“ nomad run”。 甚至计划将其转移到CI。


12.支持内存中的超额预订


解决方案:否。


在当前版本的Nomad中,必须为服务指定严格的内存限制。 如果超过该限制,该服务将被OOM Killer终止。


超额预订是指可以将服务限制指定为“从和到”。 与正常运行期间相比,某些服务在启动时需要更多的内存。 某些服务可能会在短时间内消耗比平常更多的内存。


选择严格的限制还是软性是讨论的话题,但是例如,Kubernetes允许程序员做出选择。 不幸的是,在当前版本的Nomad中没有这种可能性。 我承认它将出现在将来的版本中。


13.从Nomad服务中清洁服务器


解决方案:


 sudo systemctl stop nomad mount | fgrep alloc | awk '{print $3}' | xargs -I QQ sudo umount QQ sudo rm -rf /var/lib/nomad sudo docker ps | grep -v '(-1|-2|...)' | fgrep -v IMAGE | awk '{print $1}' | xargs -I QQ sudo docker stop QQ sudo systemctl start nomad 

有时“出问题了”。 在服务器上,它杀死代理节点,并拒绝启动。 或代理节点停止响应。 或代理节点在此服务器上“丢失”服务。
有时这是在较旧版本的Nomad中发生的,现在这种情况要么没有发生,要么很少发生。


考虑到排水服务器将无法产生理想的结果,在这种情况下最容易做到的是什么? 我们手动清洁服务器:


  1. 停止游牧特工。
  2. 将其挂载到它创建的挂载上。
  3. 删除所有座席数据。
  4. 我们通过过滤服务容器(如果有)来删除所有容器。
  5. 我们开始代理。

14.部署Nomad的最佳方法是什么?


解决方案:当然,通过领事。


在这种情况下,领事绝不是一个额外的层,而是一种有机地适合基础架构的服务,它的优点多于弊:DNS,KV存储,搜索服务,监视服务的可用性以及安全交换信息的能力。


此外,它和Nomad一样容易展开。


15.哪个更好-Nomad还是Kubernetes?


解决方案:取决于...


以前,我有时会想到开始迁移到Kubernetes的想法-定期自发地重启服务令我非常恼火(请参阅问题编号8)。 但是,在彻底解决问题之后,我可以说:游牧民族目前适合我。


另一方面:Kubernetes还具有半自发的服务重载-当Kubernetes调度程序根据负载重新分配实例时。 这不是很酷,但是很可能已经配置好了。


Nomad的优点:基础结构非常易于部署,简单的脚本,良好的文档,对Consul / Vault的内置支持,这反过来又提供了:密码存储问题的简单解决方案,内置DNS,易于配置的helcheck。


Kubernetes的优点:现在它是“事实上的标准”。 良好的文档资料,许多现成的解决方案,以及对发布的良好描述和标准化。


不幸的是,我在Kubernetes上没有同样出色的专业知识来明确地回答问题-在新集群中使用什么。 取决于计划的需求。
如果您计划了很多命名空间(问题编号5),或者您的特定服务在开始时占用了大量内存,则释放它(问题编号12)-肯定是Kubernetes,因为 游牧民族的这两个问题没有得到充分解决或带来不便。

Source: https://habr.com/ru/post/zh-CN435132/


All Articles