乐趣区

关于腾讯云:TKE-用户故事-作业帮-Kubernetes-原生调度器优化实践

作者

吕亚霖,2019 年退出作业帮,作业帮架构研发负责人,在作业帮期间主导了云原生架构演进、推动施行容器化革新、服务治理、GO 微服务框架、DevOps 的落地实际。

简介

调度零碎的实质是为计算服务 / 工作匹配适合的资源,使其可能稳固高效地运行,以及在此的根底上进一步提高资源应用密度,而影响利用运行的因素十分多,比方 CPU、内存、IO、差异化的资源设施等等一系列因素都会影响利用运行的体现。同时,独自和整体的资源申请、硬件 / 软件 / 策略限度、亲和性要求、数据区域、负载间的烦扰等因素以及周期性流量场景、计算密集场景、在离线混合等不同的利用场景的交错也带来了决策上的多变。

调度器的指标则是疾速精确地实现这一能力,但疾速和精确这两个指标在资源无限的场景下会往往产生产生矛盾,须要在二者间衡量。

调度器原理和设计

K8s 默认调度器的整体工作框架,能够简略用下图概括:

两个管制循环

  1. 第一个管制循环,称为 Informer Path。它的次要工作,是启动一系列的 Informer,用来监听(Watch)集群中 Pod、Node、Service 等与调度相干的 API 对象的变动。比方,当一个待调度 Pod 被创立进去之后,调度器就会通过 Pod Informer 的 Handler,将这个待调度 Pod 增加进调度队列;同时,调度器还要负责对调度器缓存 Scheduler Cache 进行更新,并以这个 cache 为参考信息,来进步整个调度流程的性能。
  2. 第二个管制循环,即为对 pod 进行调度的主循环,称为 Scheduling Path。这一循环的工作流程是一直地从调度队列中取出待调度的 pod,运行 2 个步骤的算法,来选出最优 node。
  • 在集群的所有节点中,选出所有“能够”运行该 pod 的节点,这一步被称为 Predicates;
  • 在上一步选出的节点中,依据一些列优选算法对节点就行打分,选出“最优”即得分最高的节点,这一步被称为 Priorities。

调度实现之后,调度器就会为 pod 的 spec.NodeName 赋值这个节点,这一步称为 Bind。而为了不在主流程门路中拜访 Api Server 影响性能,调度器只会更新 Scheduler Cache 中的相干 pod 和 node 信息:这种基于乐观的假如的 Api 对象更新形式,在 K8s 中称为 Assume。之后才会创立一个 goroutine 来异步地向 Api Server 发动更新 Bind 操作,这一步就算失败了也没有关系,Scheduler Cache 更新后就会一切正常。

大规模集群调度带来的问题和挑战

K8s 默认调度器策略在小规模集群下有着优异的体现,然而随着业务量级的减少以及业务品种的多样性变动,默认调度策略则逐步透出了局限性:调度维度较少,无并发,存在性能瓶颈,以及调度器越来越简单。

迄今为止,咱们以后单个集群规模节点量千级,pod 量级则在 10w 以上,整体资源分配率超过 60%,其中更是蕴含了 gpu,在离线混合部署等简单场景;在这个过程中,咱们遇到了不少调度方面的问题。

问题 1:高峰期的节点负载不平均

默认调度器,参考的是 workload 的 request 值,如果咱们针对 request 设置的过高,会带来资源的节约;过低则有可能带来高峰期 CPU 不平衡差别重大的状况;应用亲和策略尽管能够肯定水平防止这种,然而须要频繁填充大量的策略,保护老本就会十分大。而且服务的 request 往往不能体现服务实在的负载,带来差别误差。而这种差别误差,会在顶峰时体现到节点负载不均上。

实时调度器,在调度的时候获取各节点实时数据来参加节点打分,然而实际上实时调度在很多场景并不实用,尤其是对于具备显著规律性的业务来说;比方咱们大部分服务晚顶峰流量是平时流量的几十倍,高下峰资源应用差距剧大,而业务发版个别抉择低峰发版,采纳实时调度器,往往发版的时候比拟平衡,到晚顶峰就呈现节点间微小差别,很多实时调度器,往往在呈现微小差别的时候会应用再均衡策略来从新调度,顶峰时段对服务 POD 进行迁徙,服务高可用角度来思考是不事实的。显然实时调度是远远无奈满足业务场景的。

咱们的计划:顶峰预测时调度

所以针对这种状况,须要预测性调度,依据以往顶峰时候 CPU、IO、网络、日志等资源的使用量,通过对服务在节点上进行最优排列组合回归测算,失去各个服务和资源的权重系数,基于资源的权重打分扩大,也就是应用过来顶峰数据来预测将来顶峰节点服务使用量,从而干涉调度节点打分后果。

问题 2:调度维度多样化

随着业务越来越多样性,须要退出更多的调度维度,比方日志。因为采集器不可能有限速率采集日志且日志采集是基于节点维度。须要将均衡日志采集速率,不能各个节点差别过大。局部服务 CPU 使用量个别然而日志输出量很大;而日志并不属于默认调度器决策的一环,所以当这些日志量很大的服务多个服务的 pod 在同一个节点上的时候,该机器上的日志上报就有可能呈现局部提早。

咱们的计划:补全调度决策因子

该问题显然须要咱们对调度决策补全,咱们扩大了预测调度打分策略,增加了日志的决策因子,将日志也作为节点的一种资源,并依据历史监控获取到服务对应的日志使用量来计算分数。

问题 3:大批量服务扩缩导带来的调度时延

随着业务的复杂度进一步回升,在顶峰时段呈现,会有大量定时工作和集中大量弹性扩缩,大批量(上千 POD)同时调度导致调度时延的上涨,这两者对调度工夫比拟敏感,尤其对于定时工作来说,调度延时的上涨会被显著感知到。起因是 K8s 调度 pod 自身是对集群资源的调配,反馈在调度流程上则是预选和打分阶段是程序进行的;如此一来,当集群规模大到肯定水平的时候,大批量更新就会呈现可感知到的 pod 调度提早。

咱们的计划:拆分任务调度器,加大并发调度域、批量调度

解决吞吐能力低下的最间接的办法就是串行改并行,对于资源抢占场景,尽量细化资源域,资源域之间并行。给予以上策略,咱们拆分出了独立的 job 调度器,同时应用了 serverless 作为 job 运行的底层资源。K8s serverless 为每一个 JOB POD,独自申请了独立的 POD 运行 sanbox,也就是任务调度器,是残缺并行。 以下比照图

原生调度器在晚顶峰下节点 CPU 使用率

优化后调度器在晚顶峰下节点 CPU 使用率

总结

work 节点资源、GPU 资源、serverless 资源这就是咱们集群异构资源分属于这三类资源域,这三种资源上运行的服务存在人造的差异性,咱们应用 forecast-scheduler、gpu-scheduler、job-schedule 三个调度器来治理这三种资源域上的 pod 的调度状况。

预测调度器治理大部分在线业务,其中扩大了资源维度,增加了预测打分策略。

GPU 调度器治理 GPU 资源机器的调配,运行在线推理和离线训练,两者的比例处于长期稳定中,顶峰期间离线训练缩容、在线推理扩容;非顶峰期间离线训练扩容、在线推理缩容;同时解决一些离线图片解决工作来复用 GPU 机器上比拟闲暇的 CPU 等资源

Job 调度器负责管理咱们定时工作的调度,定时任务量大且创立销毁频繁,资源应用十分碎片化,而且对实效性要求更高;所以咱们将工作尽量调度到 Serverless 服务上,压缩集群中为了能包容大量的工作而冗余的机器资源,晋升资源利用率。

将来的演进探讨

更细粒度的资源域划分

将资源域划分至节点级别,节点级别加锁来进行。

资源抢占和重调度

失常场景下,当一个 pod 调度失败的时候,这个 pod 会放弃在 pending 的状态,期待 pod 更新或者集群资源发生变化进行从新调度,然而 K8s 调度器仍然存在一个抢占性能,能够使得高优先级 pod 在调度失败的时候,挤走某个节点上的局部低优先级 pod 以保障高优 pod 的失常,迄今为止咱们并没有应用调度器的抢占能力,即便咱们通过以上多种策略来增强调度的准确性,但仍然无奈防止局部场景下因为业务带来的不平衡状况,这种非正常场景中,重调度的能力就有了用武之地,兴许重调度将会成为日后针对异样场景的一种主动修复的形式。

对于咱们

更多对于云原生的案例和常识,可关注同名【腾讯云原生】公众号~

福利:

①公众号后盾回复【手册】,可取得《腾讯云原生路线图手册》&《腾讯云原生最佳实际》~

②公众号后盾回复【系列】,可取得《15 个系列 100+ 篇超实用云原生原创干货合集》,蕴含 Kubernetes 降本增效、K8s 性能优化实际、最佳实际等系列。

③公众号后盾回复【白皮书】,可取得《腾讯云容器平安白皮书》&《降本之源 - 云原生老本治理白皮书 v1.0》

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

退出移动版