最近无意间看到一篇两年前的文章《Scaling Kubernetes to 7,500 nodes》原文如下:openai.com/research/sc… 虽然有点倔坟,但好在里面的东西并不算太落后,至少从OpenAI团队之前的文章来看,也确实记载了整个在Kubernetes集群规划的成长与经历的同享,非常的值得学习。正好最近我们 KubeGems PAI(机器学习渠道)也遇到一些调度方面的问题,便一再阅读并简略做个笔记与我们同享读后感。
资源调度
**说明:**由于Kubernetes中的每个Node节点的GPU均选用NVLink和GPUDirect直通网卡,所以在一个Node上仅调度一个Pod独占全部资源来到达算力最大化运用。 要完成这个效果,选用NodeSelector和DaemoSet可以最简略满意需求,对K8S的调度压力也最小(后边提到OpenAI并不是运用DaemonSet办法,且也无法做到更高级的调度战略,这儿仅仅只是举例)。在独占Node场景下确实不需求调度支撑Bin-Pack(尽或许将pod填布满node)和Fragmentation(碎片化)算法,由于此刻整个集群的资源最小粒度是Node而不是Pod,也天然不用考虑CPU NUMA拓扑结构。也不存在Node资源争强的问题。
**新知识:**full bisection bandwidth(全双工切分带宽)指一个集群中任何一半的节点都可以与另一半的节点进行最大带宽的通讯,而不会遭到带宽约束的影响。例如,假定一个系统有16个节点,每个节点都有一个10 Gb/s的网络连接。假设系统规划得很好,那么任何8个节点都应该可以一起与其他8个节点进行10 Gb/s的通讯。全双工切分带宽的首要长处是它可以大大提高系统的并行处理才华,由于它可以让全部的节点都可以最大化地运用他们的网络带宽。
说明:我们依据团队姓名规划了一个污点openai.com/team=teamname:NoSchedule
并把他符号到服务器上,这样不同团队在运用资源时就必须要增加污点忍耐才华协调到资源。一起我们还自己开发了个控制器,用于在准入阶段将忽略污点,优先调度低优先级的pod。这样就可以让团队直接可以相互借用资源。这个Webhook挺有意思的,了解Volcano的知道,它在做资源调度时也容许不同Queue之间相互借用资源,并reclaim这个布尔值来决定是否其时Queue是否容许收回正在运用中的过量资源。这儿可以说是英雄所见略同了。
说明:Gang scheduling在处理MPI作业时非常重要,原因在于MPI作业的同步通讯特性。由于MPI是一种并行核算的编程模型,它容许进程间通过消息传递的办法进行通讯,以结束一项共同的核算任务。在MPI中,一项常见的操作是调集通讯,其中全部进程需求一起参加。假设任何一个进程滞后或许不可用,那么全部的进程都将被堵塞,等待该进程结束。这就导致了MPI作业非常依靠于全部参加进程的同步实行。OpenAI完成Gang Scheduling的办法则是通过嵌入k8s scheuler plugis的办法完成。这个插件名叫Coscheduling,其时已被合并到scheudler-plugin主线。github.com/kubernetes/…. 上文也提到,Gang Scheduling也可通过Volcano来扩展Kubernetes的调度功用来完成。
并行作业处理
说明: 参加到工作MPI作业任务的work节点都必须定时进行checkpoint,这是一种容错机制,可以在作业犯错或许系统崩溃时康复作业的情况,用来避免核算犯错后全部重头来过。
新概念: semi-stateful pod (半情况容器),由于并行任务的Runtime载体是Pod,它的情况数据首要便是任务实行是产生的checkpoint。显着这部分数据需求被耐久化到PVC中。之所以称之为半情况,首要在于即使该容器挂了,最坏的情况也是任务全体暂停并回到上一次checkpoint重新开始,并不会像有情况运用产生不可逆的灾祸
网络
说明: 操练过程中几乎没有外部的网络开支(个人了解不包含存储数据集的数据拜访),所以对Kubernetes的kube-proxy,ingress组建没有特别的依靠。之前调度部分说过,许多时分一个Node上就调度一个Pod独占,我甚至认为有或许Pod直接运用了Host网络来最小化网络的影响。 此外对Kubernets的服务发现运用场景也首要是为参加到MPI并行作业的进程供应网络拓扑结构,并用在各个Worker之间进行团体通讯。
说明: 当K8S集群扩大到7500台时,网络计划不管是依据overlay的flannel仍是依据路由完成的组网,都无法在IP地址扩展性和功用方面做到一起统筹。所以我们运用了Azure的VMSS处理了我们的问题。
**新知识:**VMSS是Azure上管理大规划虚拟机集群的网络服务和处理计划。
资料较少,看起来这儿看起想表达的意思是OpenAI将Azure上管理虚拟机地址的VMSS服务通过CNI给Kuberntes Pod用了起来。
说明: 我们的Pod对外拜访仍是依据NAT的,只不过用了Iptables来符号流量的来源以及运用量,这个首要用来评估Pod间或许说是并行作业间网络通讯是否存在瓶颈
存储
说明:由于没有更多资料参看OpenAI中Blob存储的规划,依照这儿意思,我们存储的用处首要来放操练时所需求的数据集以及记载操练过程中的checkout(上文有提到)。并且该存储还支撑数据的预热以加速数据拜访功率,一起这个存储对上还完成了操作系统标准的POSIX接口便利开发人员直接操作。
API servers
**说明:**我们用5台独立的ETCD服务器和5台独立的api server服务器支撑了7500个节点,并其时的装备还足以应对未来的扩容的需求。这儿面我们的首要优化点是将Kuebrnetes Events别离到其它Etcd集群上以削减记载许多工作的IO带来的推迟
说明:工作许多节点场景下,每个Node上的List-Watch
带来的泛洪效应比较显着,涓流成河,当全部请求都会聚到API Server后所带来的传输带宽高达1GB/s! 好在我们用了Kubernete 1.1之后的版别,通过EndpointSlices在服务器将压力缩小了1000倍
新知识:EndpointSlices是Kubernetes 1.16 版别引入的新Feature。它将Endpoint信息松散在多个较小的方针中,每个方针只包含一部分Endpoint信息。这样,对端点的增加、删去或修改只需求更新一个较小的 EndpointSlice 方针,而不需求更新整个 Endpoints 方针。这大大提高了 Kubernetes 在处理大规划集群时的功用和可扩展性。
监控
说明: 我们也遇到了海量无效的方针,这真的很”烦人”,大部分我们都不从来不重视。我们Prometheus也常常OOM,后来发现是许多的histogram方针查询堆积造成的。所以我们在后端查询时设置了实行超时时刻,这样promtheus的内存就再没爆过了。
另外Prometheus重启后对WAL文件的重放工作慢得我们也无法忍耐,后来在Robust Perception的帮忙下知道了调大GOMAXPROCS参数来设置goroutine数来加速重放速度
啊?原本OpenAI的工程师竟然不知道 – -!
总结
OpenAI 将 Kubernetes 集群扩展到 7,500 个节点,并为 GPT-3、CLIP 和 DALLE 等大型模型供应了可扩展的基础设施,足以证明Kubernetes 是一个非常灵敏的渠道,跟着AI职业的这波浪潮,Kubernetes也会跟着机器学习、更大规划和精细化的调度迎来一波新的高点。