重调度(Descheduling)通常是指将部署在某个节点上调度不合理的Pod重新调度到另一个节点,适用于集群资源利用不均衡、节点负载过高或有新的调度策略需求等场景。启用重调度功能可以优化集群资源使用和应用服务质量。本文以节点污点校验插件RemovePodsViolatingNodeTaints为例,介绍如何基于ack-koordinator组件开启重调度功能。
阅读前提示
- 使用前,建议已参见重调度了解功能介绍、使用场景、工作流程和基本概念。 
- 本文以节点污点校验插件 - RemovePodsViolatingNodeTaints为例,请参见Kubernetes官方文档了解污点和容忍度的工作原理、驱逐效果(例如NoSchedule)等概念。
- 对于社区Kubernetes Descheduler用户,建议参见Koordinator Descheduler与Kubernetes Descheduler了解Koordinator Descheduler与Kubernetes Descheduler的差异,并完成组件的迁移。 
- 如需了解系统、模板概要、策略插件、驱逐器插件的高级配置参数以实现更精细化的重调度策略,可直接跳转至高级配置参数。 
前提条件
- 已创建ACK托管集群Pro版,请参见创建ACK托管集群。 - 重调度功能不支持在虚拟节点中使用。 
- 已通过kubectl工具连接集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。 
注意事项
- Koordinator Descheduler只负责驱逐正在运行的Pod,并不负责Pod驱逐后的重建以及调度。Pod被驱逐后的重建由其工作负载对应的Controller实现(例如Deployment、StatefulSet),重建后Pod的调度流程仍然调度器负责。 
- 重调度在执行过程中会先驱逐旧Pod,再创建新Pod。请确保您的应用有充足的冗余副本( - replicas),避免驱逐时影响应用可用性。
示例说明
本文以开启节点污点校验插件RemovePodsViolatingNodeTaints为例,介绍如何基于ack-koordinator组件开启重调度功能,并实现重调度策略。
RemovePodsViolatingNodeTaints策略默认检查并驱逐违反了节点上effect为NoSchedule的污点的Pod。例如,对于一个已经有Pod在运行的节点,当管理员在节点上新增一个污点deschedule=not-allow:NoSchedule后,若节点上的Pod没有配置相应的容忍策略,则Pod就会被该重调度策略驱逐。更多信息,请参见RemovePodsViolatingNodeTaints。
RemovePodsViolatingNodeTaints策略支持通过excludedTaints字段定义哪些节点污点不在策略的考虑范围内。如果节点上的任何污点的键(key)或键值对(key=value)与 excludedTaints 列表中的条目匹配,那么策略会自动忽略这些污点。
本示例将该插件对污点的检查配置为:
- 节点上存在 - effect为- NoSchedule的污点属性。
- 在 - NoSchedule的污点属性中,- key不等于- deschedule,且- value不等于- not-allow。
在符合以上要求的节点上,如果已经完成调度并运行中的Pod未配置相应的容忍策略,则会被重调度器驱逐。
步骤一:安装或修改ack-koordinator组件并开启重调度
您可以参见本小节步骤安装ack-koordinator组件,使用其提供的Koordinator Descheduler重调度器功能。Koordinator Descheduler会以Deployment的形式部署在节点上。
如果您已安装ack-koordinator组件,请确保组件版本为v1.2.0-ack.2及以上。
- 登录容器服务管理控制台,在左侧导航栏选择集群列表。 
- 在集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理。 
- 定位ack-koordinator组件,单击右下角的安装,在安装对话框上面勾选开启重调度模块,按页面提示完成组件的配置和安装。 
步骤二:开启重调度插件RemovePodsViolatingNodeTaints
- 使用如下YAML文件,创建koord-descheduler-config.yaml。 - 创建ConfigMap对象koord-descheduler-config.yaml,以启用和配置插件 - RemovePodsViolatingNodeTaints。- # koord-descheduler-config.yaml apiVersion: v1 kind: ConfigMap metadata: name: koord-descheduler-config namespace: kube-system data: koord-descheduler-config: | # 以下为Koordinator Descheduler系统配置,请保持不变。 apiVersion: descheduler/v1alpha2 kind: DeschedulerConfiguration leaderElection: resourceLock: leases resourceName: koord-descheduler resourceNamespace: kube-system deschedulingInterval: 120s # 执行周期间隔,120s执行一次重调度插件。 dryRun: false # 全局只读模式开关,开启后Koordinator Descheduler整体不做任何操作。 # 以上为系统配置。 profiles: - name: koord-descheduler plugins: deschedule: enabled: - name: RemovePodsViolatingNodeTaints # 配置开启节点污点校验插件。 pluginConfig: - name: RemovePodsViolatingNodeTaints # 节点污点校验插件配置。 args: excludedTaints: - deschedule=not-allow # 忽略包含key为"deschedule"且value为"not-allow"的污点的节点。 # 以下为驱逐器插件MigrationController生效所需的系统配置,请勿删除。 - name: MigrationController # 重调度迁移控制参数。 args: apiVersion: descheduler/v1alpha2 kind: MigrationControllerArgs defaultJobMode: EvictDirectly
- 执行如下命令,部署koord-descheduler-config.yaml,将配置更新到集群中。 - kubectl apply -f koord-descheduler-config.yaml
- 执行如下命令,重启重调度器模块Koordinator 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- 通过将 - ack-koord-descheduler的Deployment副本数量设置为- 0,然后再设置为- 1,重调度器模块Koordinator Descheduler将重启启动,并在启动后使用最新配置。
步骤三:验证重调度能力
下文以拥有3台节点的集群为例进行说明。
- 使用如下YAML文件,创建stress-demo.yaml。 - stress-demo.yaml中定义了一个示例应用程序。 
- 执行以下命令,部署stress-demo.yaml,创建测试Pod。 - kubectl create -f stress-demo.yaml
- 执行如下命令,观察Pod的状态,直至开始运行。 - kubectl get pod -o wide- 预期输出: - NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES stress-demo-5f6cddf9-9**** 1/1 Running 0 10s 192.XX.XX.27 cn-beijing.192.XX.XX.247 <none> <none> stress-demo-5f6cddf9-h**** 1/1 Running 0 10s 192.XX.XX.20 cn-beijing.192.XX.XX.249 <none> <none> stress-demo-5f6cddf9-v**** 1/1 Running 0 10s 192.XX.XX.32 cn-beijing.192.XX.XX.248 <none> <none>
- 执行如下命令,分别为节点增加污点 - key=value:NoSchedule。- 为节点 - cn-beijing.192.XX.XX.247增加- deschedule=not-allow:NoSchedule污点。- kubectl taint nodes cn-beijing.192.XX.XX.247 deschedule=not-allow:NoSchedule- 预期输出: - node/cn-beijing.192.XX.XX.247 tainted
- 为节点 - cn-beijing.192.XX.XX.248增加- deschedule=allow:NoSchedule污点。- kubectl taint nodes cn-beijing.192.XX.XX.248 deschedule=allow:NoSchedule- 预期输出: - node/cn-beijing.192.XX.XX.248 tainted
 
- 执行如下命令,观察Pod变化。 - kubectl get pod -o wide -w- 等待重调度器检查节点污点,并执行驱逐迁移操作。 - 预期输出: - NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES stress-demo-5f6cddf9-9**** 1/1 Running 0 5m34s 192.XX.XX.27 cn-beijing.192.XX.XX.247 <none> <none> stress-demo-5f6cddf9-h**** 1/1 Running 0 5m34s 192.XX.XX.20 cn-beijing.192.XX.XX.249 <none> <none> stress-demo-5f6cddf9-v**** 1/1 Running 0 5m34s 192.XX.XX.32 cn-beijing.192.XX.XX.248 <none> <none> stress-demo-5f6cddf9-v**** 1/1 Terminating 0 7m58s 192.XX.XX.32 cn-beijing.192.XX.XX.248 <none> <none> stress-demo-5f6cddf9-j**** 0/1 ContainerCreating 0 0s <none> cn-beijing.192.XX.XX.249 <none> <none> stress-demo-5f6cddf9-j**** 1/1 Running 0 2s 192.XX.XX.32 cn-beijing.192.XX.XX.249 <none> <none>- 预期输出表明: - 增加了 - deschedule=allow:NoSchedule污点的节点- cn-beijing.192.XX.XX.248上的Pod- stress-demo-5f6cddf9-v****被驱逐。
- 增加了 - deschedule=not-allow:NoSchedule污点的节点- cn-beijing.192.XX.XX.247上的Pod- stress-demo-5f6cddf9-9****没有被驱逐。
- 被驱逐的Pod - stress-demo-5f6cddf9-v****重新调度到没有- NoSchedule污点的节点- cn-beijing.192.XX.XX.249。
 
- 执行如下命令,观察被驱逐Pod的Event。 - kubectl get event | grep stress-demo-5f6cddf9-v****- 预期输出: - 3m24s Normal Evicting podmigrationjob/b0fba65f-7fab-4a99-96a9-c71a3798**** Pod "default/stress-demo-5f6cddf9-v****" evicted from node "cn-beijing.192.XX.XX.248" by the reason "RemovePodsViolatingNodeTaints" 2m51s Normal EvictComplete podmigrationjob/b0fba65f-7fab-4a99-96a9-c71a3798**** Pod "default/stress-demo-5f6cddf9-v****" has been evicted 3m24s Normal Descheduled pod/stress-demo-5f6cddf9-v**** Pod evicted from node "cn-beijing.192.XX.XX.248" by the reason "RemovePodsViolatingNodeTaints" 3m24s Normal Killing pod/stress-demo-5f6cddf9-v**** Stopping container stress- 预期输出中显示了Pod的迁移记录,此Pod所在节点 - cn-beijing.192.XX.XX.248没有容忍污点- deschedule=not-allow,导致该Pod被重调度到其他节点。结果符合预期。
高级配置参数
除了上述标准操作之外,您还可以使用ConfigMap对Koordinator Descheduler进行高级配置。
高级配置参数示例
下方YAML展示了Koordinator Descheduler的高级配置参数示例。该配置通过DeschedulerConfigurationAPI修改Koordinator Descheduler的行为,开启了RemovePodsViolatingNodeTaint节点污点校验重调度策略,并使用MigrationController作为Pod的驱逐器。
您可结合后续章节的说明,了解示例配置中各字段的详细含义。
系统配置
DeschedulerConfiguration中支持对Koordinator Descheduler全局的系统级行为进行配置。
| 参数 | 类型 | 取值 | 说明 | 示例值 | 
| 
 | boolean | 
 | 只读模式开关,开启后将不会发起Pod迁移。 | false | 
| 
 | time.Duration | >0s | 重调度的执行周期。 | 120s | 
| 
 | 结构体 | 不涉及 | 限制重调度器生效的节点。重调度策略只会在Node Selector指定的节点中生效。关于Node Selector的更多信息,请参见Kubernetes labelSelector。 | 分为两种方式,一种是指定单个节点池时的配置方式,一种是指定多个节点池时的配置方式。 
 | 
| 
 | int | ≥0(默认不限制) | 限制节点上能够同时驱逐的Pod的最大数量。在驱逐过程中生效。 | 10 | 
| 
 | int | ≥0(默认不限制) | 限制命名空间内能够同时驱逐的Pod的最大数量。在驱逐过程中生效。 | 10 | 
模板概要配置
Koordinator Descheduler使用重调度模板管理重调度策略和Pod驱逐器。在DeschedulerConfiguration的profiles字段中支持定义一个或多个重调度模板。在每个重调度模板中,重调度策略和Pod驱逐器都以插件的形式进行配置。重调度模板中包含以下三部分。
- name- string类型。自定义重调度模板的名称。 
- plugins- 配置需要启用或禁用的重调度策略( - deschedule、- balance)、Pod驱逐插件(- evict)以及Pod驱逐前的筛选策略(- filter)。支持配置的参数与说明如下所示。- 参数 - 类型 - 取值 - 说明 - 示例值 - deschedule- 结构体,数据结构为: - type PluginList struct { Enabled []Plugin Disabled []Plugin } type Plugin struct { Name string }- 其中, - Enabled和- Disabled均为- Plugin结构体类型的列表,分别表示开启和禁用插件。- 默认全部禁用。选择开启的Deschedule类型的重调度策略。 - plugins: deschedule: enabled: - name: PodLifeTime - name: RemovePodsViolatingNodeTaints- RemovePodsViolatingInterPodAntiAffinity- 驱逐违反Pod间反亲和性的Pod。 - RemovePodsViolatingNodeAffinity- 驱逐违反节点亲和性的Pod。 - RemovePodsViolatingNodeTaints- 驱逐违反节点污点的Pod。 - RemovePodsHavingTooManyRestarts- 驱逐重启次数过多的Pod。 - PodLifeTime- 驱逐超出存活时间限制的Pod。 - RemoveFailedPod- 驱逐状态为Failed的Pod。 - balance- 结构体,数据结构为: - type PluginList struct { Enabled []Plugin Disabled []Plugin } type Plugin struct { Name string }- 其中, - Enabled和- Disabled均为- Plugin结构体类型的列表,分别表示开启和禁用插件。- 默认全部禁用。选择开启的Balance类型的重调度策略。 - plugins: balance: enabled: - name: RemoveDuplicates - name: LowNodeLoad- RemoveDuplicates- 应用副本打散 - LowNodeUtilization- 按节点资源分配率进行热点打散。 - HighNodeUtilization- 按节点资源分配率进行负载聚合,即在策略允许的情况下将Pods从资源利用率较低的节点调度或迁移到资源利用率较高的节点。 - RemovePodsViolatingTopologySpreadConstraint- 驱逐违反拓扑分布约束的Pod。 - LowNodeLoad- 按节点资源利用率进行热点打散。 - evict- 结构体,数据结构为: - type PluginList struct { Enabled []Plugin Disabled []Plugin } type Plugin struct { Name string }- 其中,Enabled和Disabled均为Plugin结构体类型的列表。在Enabled列表中开启插件,在Disabled中禁用插件。 - MigrationController
- DefaultEvictor
 - 选择开启的Pod驱逐器。默认启用 - MigrationController。- 请勿同时开启多个 - evict插件。- plugins: evict: enabled: - name: MigrationController- filter- 结构体,数据结构为: - type PluginList struct { Enabled []Plugin Disabled []Plugin } type Plugin struct { Name string }- 其中,Enabled和Disabled均为Plugin结构体类型的列表。在Enabled列表中开启插件,在Disabled中禁用插件。 - MigrationController
- DefaultEvictor
 - 选择Pod驱逐前的筛选策略。默认启用 - MigrationController。- 请勿同时开启多个 - filter插件。- plugins: filter: enabled: - name: MigrationController
- pluginConfig- 配置每个插件的高级参数。以 - name字段指定所配置的插件名。关于如何在- args字段配置插件。请参见策略插件配置和驱逐器插件配置。
- nodeSelector- 限制重调度模板的生效范围。模板中配置的重调度策略仅在Node Selector指定的节点上生效。更多信息,请参见Kubernetes labelSelector。若不指定该字段,默认在全部节点上生效。 说明- 模板概要配置中的 - nodeSelector字段仅在ack-koordinator组件版本v1.6.1-ack.1.16及以上支持。
策略插件配置
Koordinator Descheduler支持6种Deschedule策略插件和5种Balance策略插件。其中,热点打散重调度策略插件LowNodeLoad由社区Koordinator提供,请参见使用负载热点打散重调度了解详细配置;其他重调度策略插件由社区Kubernetes Descheduler提供,如下所示。
| 策略类型 | 策略功能 | 策略配置 | 
| Deschedule | 驱逐违反Pod间反亲和性的Pod | |
| 驱逐违反节点亲和性的Pod | ||
| 驱逐违反节点污点的Pod | ||
| 驱逐重启次数过多的Pod | ||
| 驱逐超出存活时间限制的Pod | ||
| 驱逐状态为Failed的Pod | ||
| Balance | 应用副本打散 | |
| 按节点资源分配率进行热点打散 | ||
| 按节点资源分配率进行负载聚合 | ||
| 驱逐违反拓扑分布约束的Pod | 
驱逐器插件配置
Koordinator Descheduler支持DefaultEvictor和MigrationController两种驱逐器插件。
MigrationController
MigrationController驱逐器插件的高级配置参数如下所示。
| 参数 | 类型 | 取值 | 说明 | 示例值 | 
| 
 | boolean | 
 | 是否允许配置了HostPath或EmptyDir的Pod参与重调度。出于安全性考量,默认不开启。 | false | 
| 
 | int64 | ≥0(默认值为2) | 每个节点处于迁移状态的Pod的最大数量。0表示不限制。 | 2 | 
| 
 | int64 | ≥0(默认不限制) | 每个命名空间处于迁移状态的Pod的最大数量。0表示不限制。 | 1 | 
| 
 | intOrString | ≥0(默认值为10%) | 每个工作负载(例如Deployment)中处于迁移状态的Pod的最大数量或百分比。0表示不限制。 若工作负载只有单副本,则不参与重调度。 | 1或10% | 
| 
 | intOrString | ≥0(默认值为10%),且小于工作负载对应的副本总数 | 每个工作负载(例如Deployment)最大不可用副本数或百分比。0表示不限制。 | 1或10% | 
| 
 | 结构体,数据格式为:  | 
 | 工作负载级别Pod迁移的流量控制。 
 | 表示5分钟内单个工作负载内最多迁移1个副本。 | 
| 
 | string | 目前支持三种模式: 
 | 
 | Eviction | 
DefaultEvictor
DefaultEvictor插件由社区Kubernetes Descheduler提供,请参见DefaultEvictor了解详细配置。
差异对比
DefaultEvictor与MigrationController在Pod驱逐能力方面的详细对比如下所示。
| 对比项 | DefaultEvictor | MigrationController | 
| 驱逐方法 | 调用Eviction API驱逐Pod。 | |
| 驱逐限额 | 
 | 
 | 
| 驱逐限流 | 不支持 | 支持基于时间窗口的流控机制,保证同一工作负载中Pod的迁移不会过于频繁。 | 
| 驱逐观测 | 支持通过组件日志观测Pod驱逐信息。 | 
 | 
相关文档
- 部分重调度功能需与ACK调度器配合使用,请参见使用负载热点打散重调度。 
- 您可以启用成本洞察功能,了解集群资源使用量及成本分布,获取成本节约建议,请参见成本洞察。 
- 如在使用调度功能中遇到问题,可参见调度FAQ进行排查。 
- 关于ack-koordinator组件的详细介绍及变更记录,请参见ack-koordinator(ack-slo-manager)。 
- ack-descheduler已停止维护,建议您迁移至当前维护的组件模块Koordinator Descheduler。更多信息,请参见如何将ack-descheduler迁移至Koordinator Descheduler。