调度概述

在Kubernetes集群中,调度(Scheduling)指调度器组件(kube-scheduler)根据集群整体资源规划,将待运行的Pod分配到最合适的节点上,以实现应用高可用、提高集群资源利用率等目的。ACK针对不同工作负载提供了更灵活、更丰富的调度策略,包括任务调度、拓扑感知调度、QoS感知调度、重调度等。

阅读前提示

  • 本文面向集群运维人员(包括集群资源管理员)、应用开发人员提供集群调度方案。您可以根据您的业务场景、业务角色选择合适的调度策略。

    • 集群运维人员:关心集群成本,确保集群资源能够被最大化地利用,避免资源浪费。同时关心集群的高可用,希望平衡好节点间的负载均衡,通过合理的调度避免单点故障。

    • 应用开发人员:希望通过简便的办法部署和管理应用,且应用能够根据其性能要求获取所需的CPU、GPU、内存等资源。

  • 为了帮助您更好地使用ACK提供的调度策略,建议您在使用功能前参见Kubernetes官方文档了解调度器(Scheduler)节点标签(Label)驱逐(Evict)拓扑分布约束(Topology Spread Constraints)等调度相关的基本概念。

    此外,ACK Scheduler的默认调度策略与社区Kubernetes调度器保持一致,包括Filter(过滤)和Score(评分)两个环节。

Kubernetes原生调度策略

Kubernetes原生的调度策略可以分为节点调度策略和Pod间(Inter-Pod)调度策略。

  • 节点调度策略:聚焦于节点的特性和资源情况,让Pod能够被调度到符合其需求的节点上。

  • Pod间调度策略:聚焦于如何控制Pod之间的分布和定位,以优化Pod的总体布局,保障应用的高可用性。

策略

策略说明

适用场景

nodeSelector

一种较为简单的定向调度机制,使用标签(Label)的键值对对节点进行打标,然后在Pod配置中使用节点选择器(NodeSelector)的方式,将Pod调度至带有相应Label的节点上。

例如,您可以使用NodeSelector调度应用至指定节点调度应用至指定节点池

基础的节点选择功能,但无法支持更复杂的调度功能,例如软性调度规则等。

nodeAffinity

相较于NodeSelector更灵活、更精细的Pod的调度策略。例如,节点亲和性(Node Affinity)支持配置硬性调度规则(requiredDuringSchedulingIgnoredDuringExecution),确保Pod必须调度到指定节点上,以及软性的调度规则(preferredDuringSchedulingIgnoredDuringExecution),使Pod尽可能调度到满足偏好条件的节点上。

基础的节点选择功能。亲和性可以根据节点的某些特性(例如地区、机型、硬件配置等)指定Pod应该运行在哪些节点上;反亲和性可以指定Pod不应该运行在某些特定节点上,以实现跨节点分散部署,提升应用的可用性。

污点和容忍

污点(Taint)主要由键(key)、值(value)和效果(effect)组成,常见的效果包括NoSchedulePreferNoScheduleNoExecute。当节点打上污点后,只有在YAML配置中声明了与节点污点匹配的容忍(Tolerations)的Pod才允许调度到此节点上。

  • 为某些应用保留专用的节点资源,例如为AI/ML工作负载的Pod预留GPU节点资源。

    ACK还支持为节点池添加污点或标签,使得某些应用可以调度到指定节点池。具体操作,请参见创建节点池编辑节点池

  • 基于污点和容忍的Pod驱逐,例如为不健康的节点添加NoExecute的污点,将其上没有匹配容忍的Pod驱逐,并防止新的Pod调度。

podAffinity和podAntiAffinity

通过Pod标签来指定Pod应该调度或不被调度到某些节点上。例如,与节点亲和性类似,podAffinity字段支持配置硬性调度规则(requiredDuringSchedulingIgnoredDuringExecution)和软性调度规则(preferredDuringSchedulingIgnoredDuringExecution)。

  • 让需要协同的Pod调度到相同或临近的节点,从而减少网络延迟、提高通信效率,例如将前端服务和的后端服务部署在同一节点上。

  • 将关键应用分散在不同节点或故障域上,例如将数据库的不同副本部署在不同节点上。

ACK提供的调度策略

如果Kubernetes原生调度策略无法满足您更为复杂的业务诉求,例如指定不同实例资源的顺序扩容及逆序缩容、 基于节点实际资源使用情况的负载感知调度,在离线混部架构下的QoS保障、Pod的重调度及重调度后的负载均衡等,您可以参照下文选择ACK提供的调度策略。

配置调度资源优先级

  • 适用角色:集群运维人员

  • 说明:如果您的ACK集群中存在不同种类的实例资源,例如ECS和ECI,且不同资源有不同的付费类型,例如包年包月、按量付费和抢占实例等,推荐您配置调度资源优先级,指定应用实例Pod被调度到不同类型节点资源的顺序,并实现逆序缩容。

策略

策略说明

典型场景

参考文档

自定义弹性资源优先级调度

支持在应用发布或扩容过程中自定义ResourcePolicy,设置应用Pod被调度到不同类型节点资源的顺序,例如先调度到包年包月ECS,再调度到按量计费ECS,最后调度到ECI。

应用缩容时,集群也会优先删除ECI上的Pod,释放ECI的节点资源,然后删除按量计费ECS上的Pod,最后再删除包年包月ECS上的Pod。

  • 指定优先使用或避免使用的节点,平衡集群中节点的资源利用率。

  • 应用对节点性能要求高时,优先让应用Pod调度到较高性能的节点上。

  • 应用对节点性能要求不高时,优先让应用Pod调度到抢占式实例或有剩余计算资源的节点,降低资源使用成本。

自定义弹性资源优先级调度

任务调度

  • 适用角色:集群运维人员

  • 说明:Kubernetes调度器能够根据预设的规则决定将Pod放置在哪个节点上运行,但并不适用于批处理任务下Pod的协同调度。在此基础上,ACK为批量计算的任务支持了Gang Scheduling、Capacity Scheduling能力。

策略

策略说明

典型场景

参考文档

Gang Scheduling

可在并发系统中将All-or-Nothing作业中多个相关联的进程调度到不同处理器上同时运行,即相关Pod要么全部被调度,要么都不被调度,防止因部分进程的异常而导致整个关联进程组阻塞的问题。

  • 批处理作业:作业中有多个相互依赖的任务组,需要同时处理。

  • 分布式计算:例如机器学习训练任务或其他需要严格协调运行的分布式应用。

  • 高性能计算:作业可能需要整套的资源同时可用才能开始执行。

使用Gang scheduling

Capacity Scheduling

允许集群为特定的命名空间或用户组预留一定的资源容量,并在集群资源紧张时,通过资源共享的方式来提升整体资源的利用率。

多租户场景下,不同租户使用资源的周期和方式不同,造成集群的整体资源利用率较低,期望在固定资源分配的基础上允许资源的借用和回收。

使用Capacity Scheduling

亲和性调度

  • 适用角色:集群运维人员

  • 说明:您可以基于Kubernetes原生调度策略将工作负载调度至指定的实例资源上,例如FPGA节点、Arm节点等。在此基础上,ACK集群还进一步丰富了调度能力,让Pod可以在多个不同的拓扑域上重试,直至找到一个能够满足整个作业的拓扑域。

策略

策略说明

典型场景

参考文档

拓扑感知调度

调度器为作业添加Gang调度标识,限制Pod必须同时获得所需的资源,并结合拓扑感知调度能力实现Pod,直到找到一个能够满足整个作业拓扑域的功能。

您还可以使用节点池的部署集能力,将Pod调度到属于同一低延时部署集的ECS实例中,进一步提高作业性能。

机器学习或大数据分析类作业中,Pod与Pod间通常有较大的网络通信需求。期望能让作业在多个拓扑域上重试,直至找到能够提供足够资源的拓扑域,减少作业的执行时间。

调度工作负载至FPGA节点

通过nodeSelector将工作负载调度到具有FPGA设备的节点上。

异构计算场景下,为了有效利用FPGA设备,期望将工作负载调度到具有FPGA设备的节点上。

调度工作负载至Arm节点

ACK集群默认会将所有工作负载调度到x86架构的Worker节点。您可以通过nodeSelectornodeAffinity将工作负载调度到Arm节点上。

集群中既有Arm节点,又有非Arm节点(例如x86节点),期望只兼容Arm架构的工作负载能够调度到Arm节点,多架构镜像优先调度到Arm节点。

负载感知调度

  • 适用角色:集群运维人员、应用开发人员

  • 说明:Kubernetes原生调度策略下,调度器主要基于资源的分配情况进行调度,即通过检查Pod的资源Requests与节点上尚未被分配的资源来确定是否应该在此节点上运行该Pod。但节点的利用率会随着时间、集群环境、工作负载的流量或请求等动态变化,Kubernetes调度器并不能感知节点实际的资源负载情况。

策略

策略说明

典型场景

参考文档

负载感知调度

通过参考节点负载的历史统计并对新调度Pod进行预估,ACK调度器可以感知节点真实使用的资源量,将Pod优先调度到负载较低的节点,实现节点负载均衡的目标,避免出现因单个节点负载过高而导致的应用程序或节点故障。

对请求压力或访问延迟等指标有明确的要求、对资源质量较为敏感的延时敏感型应用。

使用负载感知调度

说明

推荐您搭配使用负载热点打散重调度功能使用,防止Pod调度完成后集群再次出现负载极不均衡的情况。

QoS感知调度

  • 适用角色:集群运维人员、应用开发人员

  • 说明:您可以为Pod配置特定的QoS(Quality of Service)类,包括GuaranteedBurstableBestEffort。在节点资源不足时,kubelet可以根据Pod的QoS类决定驱逐的顺序。针对不同QoS类的应用,ACK提供差异化的SLO(Service Level Objectives)功能,以提升延迟敏感型应用的性能表现和服务质量,同时尽可能保证低优任务的资源使用。

策略

策略说明

典型场景

参考文档

CPU Burst

受CPU Limit机制的约束,操作系统会按照一定的时间周期约束资源使用,导致容器可能遭遇资源分配的限流,即CPU Throttled。CPU Burst功能可以让容器在空闲时积累一些CPU时间片,用于满足突发时的资源需求,以提升容器性能、降低延迟指标,进而提升应用的服务质量。

  • 容器应用在启动加载阶段CPU资源消耗较高,但在加载完成后的日常状态下其CPU用量相对正常的场景。

  • CPU资源需求可能会突然增长,需要快速应对突增的业务流量,例如电商、在线游戏等Web服务和应用。

CPU Burst性能优化策略

CPU拓扑感知调度

针对性能敏感型应用,将Pod固定在节点上的CPU核心运行,缓解因CPU上下文切换、跨NUMA访存导致的应用性能下降问题。

  • 应用尚未完成对云原生场景的适配,例如在设置线程数量时未考虑容器规格(而是整机物理核数量),导致应用出现性能下降问题。

  • 应用运行在神龙裸金属(Intel、AMD)等多核机器上,且出现大量因跨NUMA访存带来的应用性能下降问题。

  • 应用对CPU上下文切换十分敏感,无法承受因此带来的性能抖动。

CPU拓扑感知调度

GPU拓扑感知调度

集群中同时部署了多张GPU卡时,多个GPU密集型工作负载的Pod同时运行时,Pod之间可能会争抢节点的GPU资源,导致Pod在不同的GPU之间(甚至是NUMA Node之间)频繁地切换,影响程序性能。GPU拓扑感知调度能够将工作负载适当地分配到不同GPU卡上,减少跨越NUMA节点的内存访问,提升应用性能和响应速度。

  • 需要在大规模分布式计算中实现高效的数据传输和处理,例如高性能计算。

  • 机器学习和深度学习,需要大量GPU资源进行学习和训练,并合理将训练任务分配到各个 GPU。

  • 图形渲染和游戏开发,需要合理地分配渲染任务至不同的GPU。

动态资源超卖

将集群中已分配但未使用的资源量化并提供给低优先级任务使用,以实现对集群资源的超卖。需要结合以下单机QoS策略使用,以避免应用间的性能干扰。

  • 弹性资源限制:在整机资源用量安全水位下,控制低优先级Pod可使用的CPU资源量,保障节点内容器稳定运行。

  • 容器CPU QoS:基于容器的QoS等级,优先保障高优先级应用的CPU性能。

  • 容器内存QoS:基于容器的QoS等级,优先保障高优先级应用Pod的内存性能,延迟其触发整机内存回收的时间。

  • 容器L3 Cache及内存带宽隔离:基于容器的QoS等级,优先保障高优先级应用L3 cache和MBA内存带宽等资源的使用。

需要通过混部的方式提升集群资源利用率。典型的在离线混部的场景包括机器学习训练和推理、大数据批处理作业和数据分析、在线服务和离线备份服务等。

动态修改Pod资源参数

Kubernetes 1.27及更早版本中,如需在Pod运行中临时修改容器参数,只能更新PodSpec后重新提交,这种方式会触发Pod删除重建。ACK支持在不重启Pod的情况下,修改CPU、内存、磁盘IO等单机隔离参数。

仅适用于Pod资源(CPU、内存资源)的临时性调整。

动态修改Pod资源参数

重调度

  • 适用角色:集群运维人员、应用开发人员

  • 说明:Kubernetes调度器会根据当前的集群状态决定如何将一个Pod调度到合适的节点上。但集群的状态会不断变化,出于某些原因,您可能需要将运行中的Pod移动到其他节点,即将Pod重调度到其他节点。

策略

策略说明

典型场景

参考文档

重调度

在集群利用率不均而产生热点节点、节点属性变化导致存量Pod调度规则不匹配等场景下,您可能需要将部署在某个节点上调度不合理的Pod重新调度到另一个节点,确保Pod在最佳节点上运行,从而保障集群的高可用性和工作负载的高效运行。

  • 集群的工作负载分布不均,造成某些节点过载,例如在离线混部场景下不同应用被调度到同一节点上。

  • 集群的总体资源利用率较低,期望下线部分节点以节约成本。

  • 集群存在大量资源碎片,导致集群资源总量充足,但单节点上资源不足。

  • 节点新增或移除了污点或标签。

负载热点打散重调度

将负载感知调度和热点打散重调度结合使用,不仅能够实时感知集群内节点负载的变化,还能自动优化超过负载水位安全阈值的节点,防止出现负载极端不均衡的情况。

使用负载热点打散重调度

相关计费

使用ACK提供的调度功能时,除涉及的集群管理费用、相关云产品资源产生的计费外,调度组件还会产生如下费用。

  • ACK默认调度器由kube-scheduler组件提供,为控制面组件,安装和使用均为免费。

  • ACK的资源调度优化能力和重调度能力基于ack-koordinator组件实现。ack-koordinator组件本身的安装和使用是免费的,但在部分场景中可能产生额外的费用。更多信息,请参见ack-koordinator(ack-slo-manager)

常见问题

如果您在使用调度功能时遇到问题,可参见调度FAQ进行排查。

相关文档