使用负载热点打散重调度

ack-koordinator组件提供负载热点打散重调度能力,可以感知集群内节点负载的变化,自动优化超过负载水位安全阈值的节点,防止出现负载极端不均衡的情况。本文介绍如何使用负载热点打散重调度及其高级配置参数。

使用限制

  • 仅支持ACK集群Pro版。具体操作,请参见创建ACK托管集群

  • 使用负载热点打散重调度,需满足以下版本要求。

    组件

    版本要求

    ACK调度器版本

    v1.22.15-ack-4.0及以上,v1.24.6-ack-4.0及以上

    ack-koordinator(ack-slo-manager)

    v1.1.1-ack.1及以上

    Helm版本

    v3.0及以上

重要
  • 重调度器只负责驱逐,调度过程仍由ACK Scheduler负责。在使用重调度功能时,建议和负载感知调度搭配使用,ACK Scheduler将尽量避免Pod被重新分配到热点节点。

  • 重调度在执行过程中会先驱逐旧Pod,再创建新Pod。请确保您的应用有充足的冗余副本,避免驱逐时影响应用可用性。

  • 重调度在驱逐时使用的是K8s标准的驱逐接口,请确保应用Pod自身逻辑具备可重入性,不会因驱逐后重新启动而导致服务受损。

费用说明

ack-koordinator组件本身的安装和使用是免费的,不过需要注意的是,在以下场景中可能产生额外的费用:

  • ack-koordinator是非托管组件,安装后将占用Worker节点资源。您可以在安装组件时配置各模块的资源申请量。

  • ack-koordinator默认会将资源画像、精细化调度等功能的监控指标以Prometheus的格式对外透出。若您配置组件时开启了ACK-Koordinator开启Prometheus监控指标选项并使用了阿里云Prometheus服务,这些指标将被视为自定义指标并产生相应费用。具体费用取决于您的集群规模和应用数量等因素。建议您在启用此功能前,仔细阅读阿里云Prometheus计费说明,了解自定义指标的免费额度和收费策略。您可以通过账单和用量查询,监控和管理您的资源使用情况。

负载热点打散重调度介绍

以下介绍负载热点打散重调度相关的概念。

负载感知调度

调度器支持负载感知调度,能够在调度时选择负载较低的节点运行新的Pod。节点的利用率会随着时间、集群环境变化、工作负载的流量或请求等动态变化,继而导致集群内节点间原本负载均衡的情况被打破,甚至有可能出现极端负载不均衡的情况,影响到工作负载运行时质量。ack-koordinator组件提供重调度能力,防止负载出现极端不均衡的情况。通过将负载感知调度和热点打散重调度结合使用,可以获得集群良好的负载均衡效果。关于负载感知调度,请参见使用负载感知调度

koord-descheduler模块工作原理

ack-koordinator组件提供koord-descheduler模块,其中LowNodeLoad插件负责感知负载水位并完成热点打散重调度工作。与Kubernetes原生的Descheduler的插件LowNodeUtilization不同,LowNodeLoad是根据节点真实利用率决策重调度,而LowNodeUtilization是根据资源分配率决策重调度。

模块执行过程

koord-descheduler模块周期性运行,每个周期内的执行过程分为以下三个阶段。

koorle-descheduler执行过程

  1. 数据收集:获取集群内的节点和工作负载信息,以及相关的资源利用率数据。

  2. 策略插件执行。

    下文以LowNodeLoad为例。

    1. 筛选负载热点节点。关于节点分类,请参见下文LowNodeLoad负载水位参数说明

    2. 遍历热点节点,从中筛选可以迁移的Pod,并进行排序。关于Pod打分排序,请参见下文Pod打分策略

    3. 遍历每个待迁移的Pod,检查其是否满足迁移条件,综合考虑集群容量、资源利用率水位、副本数比例等约束。详细信息,请参见下文负载热点打散重调度策略说明

    4. 若满足条件则将Pod归类为待迁移副本,若不满足则继续遍历其他Pod和热点节点。

  3. 容器驱逐迁移:针对待迁移的Pod发起Evict驱逐操作。关于Evict驱逐,请参见Evict驱逐

LowNodeLoad负载水位参数说明

LowNodeLoad插件有两个重要的参数:

  • highThresholds:负载的热点水位,超过该阈值的节点上的Pod将参与重调度。建议您同时开启调度器的负载感知调度能力,请参见策略说明。关于两者如何搭配使用,请参见负载感知调度和热点打散重调度如何搭配使用?

  • lowThresholds:负载的空闲水位,低于该阈值的节点上的Pod不会被重调度。

以下图为例,将lowThresholds设置为45%,将highThresholds设置为70%,那么节点的分类标准如下。同理,如果lowThresholdshighThresholds的值发生变更,节点的分类标准也会相应发生变化。

image

资源利用率数据默认每分钟更新一次,粒度为最近5分钟的平均值。

  • 空闲节点(Idle Node):资源利用率低于45%的节点。

  • 正常节点(Normal Node):资源利用率高于等于45%且低于等于70%的节点。此节点的负载水位区间是期望达到的合理区间范围。

  • 热点节点(Hotspot Node):资源利用率高于70%的节点。热点节点将驱逐一部分Pod,降低负载水位,使其不超过70%。

负载热点打散重调度策略说明

策略名称

说明

热点检查重试次数策略

为了确保热点识别的准确性,避免部分毛刺监控数据触发应用频繁迁移,koord-descheduler支持为热点检查配置重试次数。只有节点连续多次触发阈值时才会识别为热点节点。

节点排序策略

在识别到的热点节点中,koord-descheduler会按资源用量从高到低的顺序,依次对节点发起重调度。其中,节点排序过程中会依次比较内存资源用量和CPU资源用量,优先选取资源用量更高的节点。

Pod打分策略

对于每个热点节点,koord-descheduler会对其中的Pod逐个打分排序,依次发起驱逐操作,将其迁移到空闲节点上。比较顺序如下:

  1. 优先级(Priority)更低的Pod,未设置时值为0,表示优先级最低。

  2. QoS等级更低的Pod。

  3. 对于优先级、QoS等级相同的Pod,koord-descheduler会综合考虑资源使用率、启动时间等因素进行排序。

说明

若您对Pod的驱逐顺序有要求,建议您考虑对Pod配置不同的优先级或QoS。

筛选策略

koord-descheduler模块支持为Pod和Node配置多种筛选参数,方便您在使用过程中进行灰度控制。

  • 按Namespace过滤:指定开启或关闭某些Namespace下Pod的重调度能力。详细信息,请参见高级配置中关于evictableNamespaces字段的描述。

  • 按Pod Selector过滤:指定Pod的Label Selector,选定开启重调度能力的Pod范围。详细信息,请参见高级配置中关于podSelectors字段的描述。

  • 按Node Selector过滤:指定Node的Label Selector,选定开启重调度能力的Node范围。详细信息,请参见高级配置中关于nodeSelector字段的描述。

前置检查策略

koord-descheduler模块支持在Pod迁移前提供前置检查能力,确保每个Pod的迁移过程尽量安全。

  • 检查节点亲和性和资源调度容量,确保Pod在重调度后,集群内有可以匹配的Node节点后再发起迁移。检查的属性包括Node Affinity、Node Selector、Toleration以及节点未分配的资源容量。

  • 检查空闲节点实际的资源用量情况,确保节点在收到新Pod后不会触及热点水位,避免出现频繁的抖动问题。

    计算公式:空闲节点实际空闲容量 = (highThresholds - 空闲节点当前负载) * 空闲节点总容量

    计算示例:假设空闲节点的负载水位是20%,highThresholds是70%,节点CPU总容量为96核。则节点实际空闲容量为48核( (70% - 20%) * 96)。此时,koord-descheduler会确保所有迁移Pod申请的CPU总量(Request)不超过48核。

迁移流量控制策略

为了满足Pod在迁移过程中应用的高可用要求,koord-descheduler模块还提供多种类型的限制能力,支持配置节点维度、命名空间维度以及工作负载维度下处于迁移状态Pod的最大数量。此外,它还提供基于时间窗口的流控机制,保证同一Workload下Pod的迁移不会过于频繁。koord-descheduler同样兼容K8s社区的干扰预算机制PDB(Pod Disruption Budgets),支持配置更精细的管理策略来保障工作负载的高可用。关于干扰预算机制,请参见干扰预算机制

可观测性策略

您可以通过Event观测重调度的迁移过程,并在详细信息中查看迁移的具体原因和当前状态。样例如下。

kubectl get event | grep stress-demo-588f9646cf-7****
55s         Normal    Evicting           podmigrationjob/3bf8f623-4d10-4fc5-ab4e-2bead3c4****   Pod "default/stress-demo-588f9646cf-7****" evicted from node "cn-beijing.10.XX.XX.53" by the reason "node is overutilized, cpu usage(76.72%)>threshold(50.00%)"
22s         Normal    EvictComplete      podmigrationjob/3bf8f623-4d10-4fc5-ab4e-2bead3c4****   Pod "default/stress-demo-588f9646cf-7****" has been evicted
55s         Normal    Descheduled        pod/stress-demo-588f9646cf-7****                       Pod evicted from node "cn-beijing.10.XX.XX.53" by the reason "node is overutilized, cpu usage(76.72%)>threshold(50.00%)"
55s         Normal    Killing            pod/stress-demo-588f9646cf-7****                       Stopping container stress

步骤一:安装或修改组件ack-koordinator并开启重调度

未安装ack-koordinator组件

安装ack-koordinator组件,并在安装组件 ack-koordinator(ack-slo-manager)页面选中ack-koordinator开启重调度模块。安装ack-koordinator组件,请参见安装ack-koordinator组件

已安装ack-koordinator组件

修改ack-koordinator组件,并在ack-koordinator参数配置页面选中ack-koordinator开启重调度模块。修改ack-koordinator组件,请参见修改ack-koordinator组件

步骤二:开启负载热点打散重调度插件

  1. 使用如下YAML文件,创建koord-descheduler-config.yaml。

    koord-descheduler-config.yaml是ConfigMap格式的对象,用于启用重调度插件LowNodeLoad。

    展开查看YAML文件内容

    # koord-descheduler-config.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: koord-descheduler-config
      namespace: kube-system
    data:
      koord-descheduler-config: |
        # 以下为koord-desheduler系统配置,请保持不变。
        apiVersion: descheduler/v1alpha2
        kind: DeschedulerConfiguration
        leaderElection:
          resourceLock: leases
          resourceName: koord-descheduler
          resourceNamespace: kube-system
        deschedulingInterval: 120s # 执行周期间隔,120s执行一次重调度插件。
        dryRun: false # 全局只读模式开关,开启后koord-descheduler整体不做任何操作。
        # 以上为系统配置。
    
        profiles:
        - name: koord-descheduler
          plugins:
            deschedule:
              disabled:
                - name: "*"
            balance:
              enabled:
                - name: LowNodeLoad # 配置开启负载热点打散插件LowNodeLoad。
            evict:
              disabled:
                - name: "*"
              enabled:
                - name: MigrationController # 配置开启驱逐迁移控制器。
    
          pluginConfig:
          - name: MigrationController # 重调度迁移控制参数。
            args:
              apiVersion: descheduler/v1alpha2
              kind: MigrationControllerArgs
              defaultJobMode: EvictDirectly
    
          - name: LowNodeLoad # 负载热点打散插件配置。
            args:
              apiVersion: descheduler/v1alpha2
              kind: LowNodeLoadArgs
    
              lowThresholds:  # lowThresholds表示空闲节点的准入水位阈值,判断条件为“所有资源维度均低于阈值”。
                cpu: 20 # CPU利用率为20%。
                memory: 30  # Memory利用率为30%。
              highThresholds: # highThresholds表示热点节点的准入水位阈值,判断条件为“只要有一个资源维度均高于阈值”。
                cpu: 50  # CPU利用率为50%。
                memory: 60 # Memory利用率为60%。
    
              evictableNamespaces: # 参与重调度的Namespace,include和exclude是互斥的,只能配置其中一种。
                include: # include表示只处理下面配置的Namespace。
                  - default
                # exclude: # exclude表示需要排除的Namespace。
                  # - "kube-system"
                  # - "koordinator-system"
  2. 执行如下命令,将配置更新到集群。

    kubectl apply -f koord-descheduler-config.yaml
  3. 执行如下命令,重启重调度器模块koord-descheduler。

    重启重调度器模块koord-descheduler后,koord-descheduler会使用修改后的最新配置。

    kubectl -n kube-system scale deploy ack-koord-descheduler --replicas 0
    deployment.apps/ack-koord-descheduler scaled
    kubectl -n kube-system scale deploy ack-koord-descheduler --replicas 1
    deployment.apps/ack-koord-descheduler scaled

步骤三(可选):开启调度器负载均衡插件

开启调度器负载均衡插件,以获得集群良好的负载均衡效果。具体操作步骤,请参见步骤一:开启负载感知调度

步骤四:验证重调度能力

下文以拥有3台104核 396 GB节点的集群为例进行说明。

  1. 使用如下YAML文件,创建stress-demo.yaml

    展开查看YAML文件内容。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: stress-demo
      namespace: default
      labels:
        app: stress-demo
    spec:
      replicas: 6
      selector:
        matchLabels:
          app: stress-demo
      template:
        metadata:
          name: stress-demo
          labels:
            app: stress-demo
        spec:
          containers:
            - args:
                - '--vm'
                - '2'
                - '--vm-bytes'
                - '1600M'
                - '-c'
                - '2'
                - '--vm-hang'
                - '2'
              command:
                - stress
              image: polinux/stress
              imagePullPolicy: Always
              name: stress
              resources:
                limits:
                  cpu: '2'
                  memory: 4Gi
                requests:
                  cpu: '2'
                  memory: 4Gi
          restartPolicy: Always
  2. 执行如下命令,创建压测Pod。

    kubectl create -f stress-demo.yaml
    deployment.apps/stress-demo created
  3. 执行如下命令,观察Pod的状态,直到它开始运行。

    kubectl get pod -o wide

    预期输出:

    NAME                           READY   STATUS    RESTARTS   AGE   IP            NODE                    NOMINATED NODE   READINESS GATES
    stress-demo-588f9646cf-s****   1/1     Running   0          82s   10.XX.XX.53   cn-beijing.10.XX.XX.53   <none>           <none>

    可以看到,Pod stress-demo-588f9646cf-s****调度在节点cn-beijing.10.XX.XX.53上。

  4. 提升节点cn-beijing.10.XX.XX.53的负载水位,然后执行如下命令,检查每个Node节点的负载。

    kubectl top node

    预期输出:

    NAME                      CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
    cn-beijing.10.XX.XX.215   17611m       17%    24358Mi         6%
    cn-beijing.10.XX.XX.53    63472m       63%    11969Mi         3%

    可以看到,节点cn-beijing.10.XX.XX.53的负载较高,为63%,已经超过配置的热点水位50%。节点cn-beijing.10.XX.XX.215负载较低,为17%,低于配置的空闲水位20%。

  5. 开启重调度。具体操作,请参见步骤二:开启负载热点打散重调度插件

  6. 执行如下命令,观察Pod变化。

    等待重调度器检查热点节点,并执行驱逐迁移操作。

    说明

    判定为热点节点的默认条件为连续5次检查节点均超过热点水位,即10分钟。

    kubectl get pod -w

    预期输出:

    NAME                           READY   STATUS               RESTARTS   AGE     IP           NODE                     NOMINATED NODE   READINESS GATES
    stress-demo-588f9646cf-s****   1/1     Terminating          0          59s   10.XX.XX.53    cn-beijing.10.XX.XX.53     <none>           <none>
    stress-demo-588f9646cf-7****   1/1     ContainerCreating    0          10s   10.XX.XX.215   cn-beijing.10.XX.XX.215    <none>           <none>
  7. 执行如下命令,观察Event。

    kubectl get event | grep stress-demo-588f9646cf-s****

    预期输出:

    2m14s       Normal    Evicting            podmigrationjob/00fe88bd-8d4c-428d-b2a8-d15bcdeb****   Pod "default/stress-demo-588f9646cf-s****" evicted from node "cn-beijing.10.XX.XX.53" by the reason "node is overutilized, cpu usage(68.53%)>threshold(50.00%)"
    101s        Normal    EvictComplete       podmigrationjob/00fe88bd-8d4c-428d-b2a8-d15bcdeb****   Pod "default/stress-demo-588f9646cf-s****" has been evicted
    2m14s       Normal    Descheduled         pod/stress-demo-588f9646cf-s****                       Pod evicted from node "cn-beijing.10.XX.XX.53" by the reason "node is overutilized, cpu usage(68.53%)>threshold(50.00%)"
    2m14s       Normal    Killing             pod/stress-demo-588f9646cf-s****                       Stopping container stress

    预期输出为迁移记录,可以看出结果符合预期。热点节点上的Pod被重调度到其他节点。

高级配置参数

koord-descheduler模块高级配置参数介绍

koord-descheduler的所有参数配置以ConfigMap形式提供,以下展示了负载热点打散重调度的高级配置参数格式。

展开查看YAML文件内容。

# koord-descheduler-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: koord-descheduler-config
  namespace: kube-system
data:
  koord-descheduler-config: |
    # 以下为koord-desheduler系统配置,请保持不变。
    apiVersion: descheduler/v1alpha2
    kind: DeschedulerConfiguration
    leaderElection:
      resourceLock: leases
      resourceName: koord-descheduler
      resourceNamespace: kube-system
    deschedulingInterval: 120s # 执行周期间隔,120s执行一次重调度插件。
    dryRun: false # 全局只读模式开关,开启后koord-descheduler整体不做任何操作。
    # 以上为系统配置。

    profiles:
    - name: koord-descheduler
      plugins:
        deschedule:
          disabled:
            - name: "*"
        balance:
          enabled:
            - name: LowNodeLoad # 配置开启负载热点打散插件LowNodeLoad。
        evict:
          disabled:
            - name: "*"
          enabled:
            - name: MigrationController # 配置开启驱逐迁移控制器。

      pluginConfig:
      - name: MigrationController # 重调度迁移控制参数。
        args:
          apiVersion: descheduler/v1alpha2
          kind: MigrationControllerArgs
          defaultJobMode: EvictDirectly
          maxMigratingPerNode: 1 # 每个节点处于迁移状态的Pod的最大数量。
          maxMigratingPerNamespace: 1  # 每个Namespace处于迁移状态的Pod的最大数量。
          maxMigratingPerWorkload: 1 # 每个Workload(例如Deployment)中处于迁移状态的Pod的最大数量。
          maxUnavailablePerWorkload: 2 # 每个Workload(例如Deployment)最大不可用副本数。
          evictLocalStoragePods: false # 是否允许配置了HostPath或EmptyDir的Pod参与重调度
          objectLimiters:
            workload: # Workload级别Pod迁移的流量控制.默认为首次驱逐后,5分钟内最多迁移1个副本。
              duration: 5m
              maxMigrating: 1

      - name: LowNodeLoad # 负载热点打散插件配置。
        args:
          apiVersion: descheduler/v1alpha2
          kind: LowNodeLoadArgs

          lowThresholds:  # lowThresholds表示空闲节点的准入水位阈值,判断条件为“所有资源维度均低于阈值”。
            cpu: 20 # CPU利用率为20%。
            memory: 30  # Memory利用率为30%。
          highThresholds: # highThresholds表示热点节点的准入水位阈值,判断条件为“只要有一个资源维度均高于阈值”。
            cpu: 50  # CPU利用率为50%。
            memory: 60 # Memory利用率为60%。

          anomalyCondition: # 热点节点检查配置。
            consecutiveAbnormalities: 5 # 连续多个执行周期检查中,均超过highThresholds的节点,才会被判定为热点节点。热点节点被驱逐后会重新计数。

          evictableNamespaces: # 参与重调度的Namespace。include和exclude是互斥的,只能配置其中一种。
            include: # include表示只处理下面配置的Namespace。
              - default
            # exclude: # exclude表示需要排除的Namespace。
              # - "kube-system"
              # - "koordinator-system"

          nodeSelector: # 只处理指定的部分节点。
            matchLabels:
              alibabacloud.com/nodepool-id: np77f520e1108f47559e63809713ce****

          podSelectors: # 只处理部分类型的Pod。
          - name: lsPods
            selector:
              matchLabels:
                koordinator.sh/qosClass: "LS"

koord-descheduler系统配置

参数

类型

取值

说明

示例值

dryRun

boolean

  • true

  • false(默认值)

只读模式开关,开启后将不会发起Pod迁移。

false

deschedulingInterval

time.Duration

>0s

重调度执行周期。

120s

驱逐迁移控制配置

参数

类型

取值

说明

示例值

maxMigratingPerNode

int64

≥0(默认值为2)

每个节点处于迁移状态的Pod的最大数量。0表示不限制。

2

maxMigratingPerNamespace

int64

≥0(默认不限制)

每个命名空间处于迁移状态的Pod的最大数量。0表示不限制。

1

maxMigratingPerWorkload

intOrString

≥0(默认值为10%)

每个工作负载(例如Deployment)中处于迁移状态的Pod的最大数量或百分比。0表示不限制。

若工作负载只有单副本,则不参与重调度。

1或10%

maxUnavailablePerWorkload

intOrString

≥0(默认值为10%),且小于工作负载对应的副本总数

每个工作负载(例如Deployment)最大不可用副本数或百分比。0表示不限制。

1或10%

evictLocalStoragePods

boolean

  • true

  • false(默认值)

是否允许配置了HostPath或EmptyDir的Pod参与重调度。出于安全考虑,默认不开启。

false

objectLimiters.workload

结构体,数据格式为:

type MigrationObjectLimiter struct {
    Duration time.Duration `json:"duration,omitempty"`
    MaxMigrating *intstr.IntOrString `json:"maxMigrating,omitempty"`
}
  • Duration的值大于0秒(默认值5m

  • MaxMigrating的值≥0(默认值为10%)

工作级别Pod迁移的流量控制。

  • Duration:时间窗口长度,例如5m表示5分钟。

  • MaxMigrating:副本数量或百分比,可设置为整数或百分比(默认值取自maxMigratingPerWorkload的值)。

objectLimiters:
  workload:
    duration: 5m
    maxMigrating: 1

表示5分钟内单个工作负载最多迁移1个副本。

LowNodeLoad插件配置

参数

类型

取值

说明

示例值

highThresholds

map[string]float64

说明

支持CPU和内存两个维度,值的单位为百分比。

[0,100]

表示负载的热点水位,超过该阈值的节点上的Pod将参与重调度。

说明

可以和调度器的负载感知调度能力搭配使用,将节点筛选参数loadAwareThreshold配置为相同的值,调度器会拒绝将Pod调度到该热点节点上,详情请参见策略说明

highThresholds:
  cpu: 55 # CPU利用率热点水位55%。
  memory: 75 # Memory利用率热点水位75%。

lowThresholds

map[string]float64

说明

支持CPU和内存两个维度,值的单位为百分比。

[0,100]

表示负载的空闲水位。低于该阈值的节点上的Pod不会被重调度。

lowThresholds:
  cpu: 25 # CPU利用率空闲水位25%。
  memory: 25 # Memory利用率空闲水位25%。

anomalyCondition.consecutiveAbnormalities

int64

>0(默认值为5)

热点检查重试次数。连续多个执行周期检查后,均超过highThresholds的节点,才会被判定为热点节点。热点节点发生驱逐后会重新计数。

5

evictableNamespaces

  • include: string

  • exclude: string

集群内的命名空间

可以参与重调度的Namespace,不填表示所有Pod全部可参与。

支持配置includeexclude策略。两种策略需二选一。

  • include:只处理指定的Namespace。

  • exclude:只处理指定之外的Namespace。

evictableNamespaces:
  exclude:
    - "kube-system"
    - "koordinator-system"

nodeSelector

metav1.LabelSelector

关于LabelSelector的格式,请参见Labels and Selectors

通过LabelSelector选择目标节点。

分为两种方式,一种是指定单个节点池时的配置方式,一个是指定多个节点池时的配置方式。

  • 方式一

    # 只处理指定的单个节点池的机器
    nodeSelector:
      matchLabels:
        alibabacloud.com/nodepool-id: np77f520e1108f47559e63809713ce****
  • 方式二

    # 只处理指定的多个节点池的机器
    nodeSelector:
      matchExpressions:
      - key: alibabacloud.com/nodepool-id
        operator: In
        values:
        - node-pool1
        - node-pool2

podSelectors

由PodSelector组成的List,支持配置多组Pod。PodSelector的数据格式为:

type PodSelector struct {
    name     string
    selector metav1.LabelSelector
}

关于LabelSelector的格式,请参见Labels and Selectors

通过LabelSelector选择开启重调度的Pod。

# 只处理LS类型的Pod。
podSelectors:
- name: lsPods
  selector:
    matchLabels:
      koordinator.sh/qosClass: "LS"

常见问题

节点利用率阈值已经达到阈值,但是节点上Pod没有被驱逐怎么办?

出现这种情况时,一般可能是有以下几种原因,请参考对应的解决方法进行调整。

原因分类

原因描述

解决方法

组件配置未生效

开启范围未指定

重调度器配置中包含Pod和节点的开启范围配置,请检查对应的命名空间和节点是否开启。

重调度器配置修改后未重启

重调度器配置修改后,需要对其进行重启才能生效。关于重启重调度器,请参见步骤二:开启负载热点打散重调度插件

节点状态不满足条件

节点的平均利用率长时间低于阈值

重调度器会持续对利用率监控一段时间,并对监控数据做平滑均值处理,因此只有节点持续超过阈值才会触发重调度,默认为10分钟左右。而kubectl top node返回的利用率只是最近1分钟的情况。请结合重试次数和执行周期配置综合观察节点一段时间的利用率情况,并按需调整配置。

集群内剩余的容量不足

在对Pod驱逐前,重调度器会对集群内其他节点进行检查,确保容量充足才会进行迁移。例如选择了一个规格为8 Core 16 G的Pod准备驱逐,而集群所有节点的空闲容量均低于该值,出于安全考虑重调度器则不会对其迁移。请考虑增加节点,确保集群容量充足。

工作负载属性约束限制

工作负载为单副本

为了保证单副本应用的高可用,这类Pod默认不参与重调度。如果您评估此类单副本应用后,希望该Pod参与重调度,请给Pod或者工作负载(如Deployment或StatefulSet)的TemplateSpec中追加Annotation descheduler.alpha.kubernetes.io/evict: "true"

说明

该Annotation配置仅支持v1.2.0-ack1.3及更早版本。

Pod指定了HostPath或EmptyDir

出于安全考虑,这类指定了HostPath或EmptyDir的Pod默认不参与重调度。如果需要对其进行迁移,可以参考evictLocalStoragePods配置允许其参与重调度。详细信息,请参见驱逐迁移控制配置

不可用或迁移中的副本数量过多

当工作负载(如Deployment或StatefulSet)的不可用或迁移中的副本数超过了限制配置(maxUnavailablePerWorkloadmaxMigrationPerWorkload)。例如 maxUnavailablePerWorkloadmaxMigrationPerWorkload设置为20%,Deployment的期望副本数设置为10,当前正好有2个Pod正在被驱逐或者正在发布,重调度器就不会对其发起驱逐。请等待Pod驱逐或发布完成,或将以上两个配置调大。

副本数量约束配置错误

当工作负载的副本总数小于等于最大迁移数量配置maxMigrationPerWorkload或最大不可用数量配置maxUnavailablePerWorkload时,出于安全考虑重调度器将不会对其进行重调度。请将以上两个配置调小或修改为百分比模式。

重调度器频繁重启是什么原因?

重调度器的配置ConfigMap格式错误或不存在,请参考高级配置参数检查ConfigMap文件内容和格式并进行修改,修改后重启重调度器。重启重调度器,请参见步骤二:开启负载热点打散重调度插件

负载感知调度和热点打散重调度如何搭配使用?

开启热点打散重调度后,负载热点上的Pod将会被驱逐。对于上层控制器(例如Deployment)新建的Pod,调度器会根据其配置选择合适的节点进行调度。为了获得更好的负载均衡效果,建议您同时为调度器开启负载感知调度能力,请参见使用负载感知调度

配置时,建议您将负载感知调度中的节点筛选功能参数loadAwareThreshold配置为与热点打散重调度器的highThresholds参数相同的值,具体请参见策略说明。当节点的负载超过highThresholds时,重调度器将驱逐该节点上的Pod,而调度器则通过loadAwareThreshold拒绝新的Pod被调度到该热点节点上。否则,经驱逐的Pod可能重新被调度到原来的节点,尤其是在Pod指定了节点调度范围,但对应的节点数量较少且利用率较为接近时。

重调度参考的利用率算法是什么?

重调度器会持续对利用率监控一段时间,并对监控数据做平滑均值处理,因此只有节点持续超过阈值才会触发重调度,默认为10分钟左右。此外对于内存资源维度,重调度器参考的内存用量排除了page cache,因为这部分资源是可以被操作系统回收的,而通过kubectl top node返回的利用率是包含page cache的,您可以通过使用阿里云Prometheus监控查看真实的内存用量信息。