更新时间:2024-12-04 GMT+08:00

节点伸缩原理

HPA是针对Pod级别的,可以根据负载指标动态调整副本数量,但是如果集群的资源不足,新的副本无法运行的情况下,就只能对集群进行扩容。

CCE集群弹性引擎是Kubernetes提供的集群节点弹性伸缩组件,根据Pod调度状态及资源使用情况对集群的节点进行自动扩容缩容,同时支持多可用区、多实例规格、指标触发和周期触发等多种伸缩模式,满足不同的节点伸缩场景。

前提条件

使用节点伸缩功能前,需要安装CCE集群弹性引擎插件,插件版本要求1.13.8及以上。

Cluster Autoscaler工作原理

Cluster Autoscaler主要流程包括两部分:

  • ScaleUp流程: Autoscaler会每隔10s检查一次所有未调度的Pod,根据用户设置的策略,选择出一个符合要求的节点池进行扩容。

    Autoscaler检测未调度Pod进行扩容时,使用的是与Kubernetes社区版本一致的调度算法进行模拟调度计算,若应用调度采用非内置kube-scheduler调度器或其他非Kubernetes社区调度策略,此类应用使用Autoscaler扩容时可能因调度算法不一致出现无法扩容或多扩风险。

  • ScaleDown流程:Autoscaler每隔10s会扫描一次所有的Node,如果该Node上所有的Pod Requests少于用户定义的缩容百分比时,Autoscaler会模拟将该节点上的Pod是否能迁移到其他节点,如果可以的话,当满足不被需要的时间窗以后,该节点就会被移除。
    当集群节点处于一段时间空闲状态时(默认10min),会触发集群缩容操作(即节点会被自动删除)。当节点存在以下几种状态的Pod时,不可缩容:
    • Pod有设置Pod Disruption Budget(即干扰预算),当移除Pod不满足对应条件时,节点不会缩容。
    • Pod由于一些限制,如亲和、反亲和等,无法调度到其他节点,节点不会缩容。
    • Pod拥有cluster-autoscaler.kubernetes.io/safe-to-evict: 'false'这个annotations时,节点不缩容。
    • 节点上存在kube-system命名空间下的Pod(除kube-system命名空间下由DaemonSet创建的Pod),节点不缩容。
    • 节点上如果有非controller(Deployment/ReplicaSet/Job/StatefulSet)创建的Pod,节点不缩容。

    当节点符合缩容条件时,Autoscaler将预先给节点打上DeletionCandidateOfClusterAutoscaler污点,限制Pod调度到该节点上。当autoscaler插件被卸载后,如果节点上依然存在该污点请您手动进行删除。

Cluster AutoScaler架构

Cluster AutoScaler架构如图1所示,主要由以下几个核心模块组成:

图1 Cluster AutoScaler架构图

说明如下:

  • Estimator: 负责扩容场景下,评估满足当前不可调度Pod时,每个节点池需要扩容的节点数量。
  • Simulator: 负责缩容场景下,找到满足缩容条件的节点。
  • Expander: 负责在扩容场景下,根据用户设置的不同的策略来,从Estimator选出的节点池中,选出一个最佳的选择。当前Expander有多种策略:
    表1 CCE支持的Expander策略

    策略

    策略说明

    使用场景

    模拟样例

    Random

    随机选择一个可调度节点池中执行本次扩容。

    此策略通常作为其他更复杂策略的基础退避策略。仅当其他优选策略无法决策时,作为备选策略使用,通常不建议直接配置使用。

    假设集群中节点池1和节点池2启用了弹性伸缩,且均未达到扩容上限。当工作负载扩容副本数时,扩容策略如下:

    1. Pending Pods触发autoscaler决策扩容流程。
    2. autoscaler模拟调度阶段,评估节点池1和节点池2中扩容的节点均可调度。
    3. autoscaler决策优选节点池,将在节点池1和节点池2范围中随机选择一个节点池执行扩容。

    most-pods

    组合型策略,优先级排序为:most-pods > random。

    优先选择扩容后能调度最多Pods的节点池。如果存在多个节点池满足条件,则基于random策略进一步决策。

    此策略基于最多可调度Pods数量作为优选依据。

    假设集群中节点池1和节点池2启用了弹性伸缩,且均未达到扩容上限。当工作负载扩容副本数时,扩容策略如下:

    1. Pending Pods触发autoscaler决策扩容流程。
    2. autoscaler模拟调度阶段,评估节点池1和节点池2中扩容的节点均可调度部分Pending Pods。
    3. autoscaler决策优选节点池,评估节点池1扩容后可调度工作负载新增的20个Pods,而节点池2扩容仅可调度工作负载新增的10个Pods,因此优选节点池1执行本次扩容。

    least-waste

    组合型策略,优先级排序为:least-waste > random。

    评估本次扩容的节点池整体CPU或MEM资源分配率,优先选择具有最小浪费的CPU或者Mem资源的节点池。如果存在多个节点池满足条件,则基于random策略进一步决策。

    此策略将CPU或者内存资源最小浪费分数作为优选依据。

    其中最小浪费分数wastedScore定义公式如下:

    • wastedCPU = (待扩容节点的CPU总量 - 待调度Pods的CPU总量) / 待扩容节点的CPU总量
    • wastedMemory = (待扩容节点的MEM总量 - 待调度Pods的MEM总量) / 待扩容节点的MEM总量
    • wastedScore = wastedCPU + wastedMemory

    假设集群中节点池1和节点池2启用了弹性伸缩,且均未达到扩容上限。当工作负载扩容副本数时,扩容策略如下:

    1. Pending Pods触发autoscaler决策扩容流程。
    2. autoscaler模拟调度阶段,评估节点池1和节点池2中扩容的节点均可调度部分Pending Pods。
    3. autoscaler决策优选节点池,评估节点池1扩容后最小浪费分数小于节点池2,因此优选节点池1执行本次扩容。

    priority

    组合策略,优先级排序为:priority > least-waste > random。

    基于节点池/伸缩组优先级配置增强的least-waste策略。如果存在多个节点池满足条件,则基于least-waste策略进一步决策。

    priority可通过Console/API主动配置管理节点池/伸缩组优先级,least-waste则在通用场景下降低资源浪费比例。此策略通用性较好,当前作为默认优选策略。

    假设集群中节点池1和节点池2启用了弹性伸缩,且均未达到扩容上限。当工作负载扩容副本数时,扩容策略如下:

    1. Pending Pods触发autoscaler决策扩容流程。
    2. autoscaler模拟调度阶段,评估节点池1和节点池2中扩容的节点均可调度部分Pending Pods。
    3. autoscaler决策优选节点池,评估节点池1优先级高于节点池2,因此优选节点池1执行本次扩容。

    priority-ratio

    组合策略,优先级排序为:priority > priority-ratio > least-waste > random。

    基于priority策略的资源碎片重调度场景化配套策略,即在同优先级场景下,优先选择扩容后可使节点可分配资源的CPU/内存比,更接近于所有已调度Pods的申请的CPU/内存比。

    此策略基于集群中全局Pods/Nodes全局资源而非仅扩容节点部分,主要配套重调度等相关能力降低集群整体资源碎片率,无相关配套独立使用场景不建议使用。

    假设集群中节点池1和节点池2启用了弹性伸缩,且均未达到扩容上限。当工作负载扩容副本数时,扩容策略如下:

    1. Pending Pods触发autoscaler决策扩容流程。
    2. autoscaler模拟调度阶段,评估节点池1和节点池2中扩容的节点均可调度部分Pending Pods。
    3. autoscaler决策优选节点池,评估Pod的CPU/内存比为1:4,节点池1中的节点规格为2U8G(CPU/内存比为1:4),节点池2中的节点规格为2U4G(CPU/内存比为1:2)。因此优选节点池1执行本次扩容。