HashiCorp是一家神奇的公司,推出的产品Vagrant,Packer,Serf,Consul,Terraform,等等,几乎每个都是涉及到数据中心开发,架构,运维的核心工具。Nomad是在十一长假之前放出的多数据中心统一集群资源管理系统,光听这名字就够神奇的了,这么长时间也没有国内文章介绍,那么本公众号就来简要介绍下吧。
简单来说,Nomad跟Mesos+Aurora/Marathon...,以及K8S都是类似的东东,但设计完全不同。Nomad最值得关注地方在于,它的设计声称来自于Borg/Omega,也就是说Mesos这么多年没解决好的问题,K8S发明了那么久都还距离遥远的设计,就被这么一个小型公司"解决"了。事实也是如此,在核心架构领域,从来都是几个人的精锐团队制胜,任何依靠人数的做法都是然并卵。在声称Borg/Omega的版图里,还有一个资源调度器Firmament,目前正在紧张开发中,等到相关论文出来,本号会第一时间介绍。
Nomad采用Go语言开发,再加上架构上的简化,因此只有一个单一的运行程序,这在运维上是极其方便的。不同节点之间的成员管理依赖Hashicorp的另一个神器Consul/Serf,这是Gossip协议通信的最佳组件库,在跨机房协作上表现优异,这也是Nomad宣称"Multi-Datacenter and Multi-Region Aware"的重要原因之一。
下面谈一下Nomad能被称为集群资源管理系统的核心——调度器的设计,架构如下图所示:
Nomad为长期服务型任务和批处理任务分别提供了不同的调度器,同时也支持定制化的调度器。在调度时,Nomad首先过滤掉不健康的节点,以及不符合任务资源描述的节点,然后进行排序。排序本身需要对不同节点进行打分,这是一个"bin packing"问题,也是背包问题变种,其本质就是在考虑亲和(Affinity)以及反亲和(Anti-affinity)因素的情况下最大化节点利用率,本号在之前曾经介绍过Netflix的Fenzo库,就是为Mesos提供了一个"bin packing"库,而Nomad这些都已经包含了。"Bin packing"在图中对应于Plan阶段,在完成分配计划后,计划送入到队列中等待执行,该队列按照任务优先权排序,并且允许多个调度器无锁并发访问,这是Nomad宣称实现了类似Omega的乐观并发资源访问的源头之一,因此这种乐观并发会导致针对某节点的资源冲突,此时,Nomad可通过Leader节点拒绝掉任务队列请求,如果没有冲突,则创建执行计划并返回调度结果,任务的调度周期结束。
Nomad集群内分为Client和Server两种角色,Server用于处理任务调度请求,而Client则好比Agent来告知Server集群内可用资源。集群由不同Region组成,每个Region都通过Raft协议选举出Leader节点,Leader节点主要用于接收Client的请求日志,以及处理事务请求,不同Region之间通过Gossip来通信。Region是独立的调度集群,相互之间不共享任务,状态。每个Region也可以处理不同数据中心的Client,因此跨数据中心的资源管理十分方便。
还记得本号之前的文章,来自EBay首席架构的观点,叫做Cloud Native的定义么?其中很重要的,就是Cloud Native需要声明性的抽象,用户只需要声明任务需求,而无需考虑任何后续工作,从这个角度来说,Nomad无疑是Cloud Native的。
然而,从上面的描述来看,针对批处理的调度策略,以及两种任务混排的策略,Nomad文档并没有提及,另一方面,对于任务如何抢占也语焉不详,尽管我们知道这就是由那个任务队列来实现的。因此,尽管Nomad设计优雅,但是否能够商用,特别是如何处理批处理以及复杂的有状态服务,还需要进一步地测试和观察。
本文算不上Nomad的深度报道,主要内容也都来自Nomad的官方文档,介绍Nomad的目的也在于开阔架构视野,相信任何喜欢优雅架构的人,都会喜欢上Nomad的设计。




