重调度(Descheduling)通常是指将部署在某个节点上调度不合理的Pod重新调度到另一个节点,适用于集群资源利用不均衡、节点负载过高或有新的调度策略需求等场景。重调度功能有助于维护集群健康、优化资源使用以及提高工作负载的服务质量。本文以节点污点校验插件RemovePodsViolatingNodeTaints
为例,介绍如何基于ack-koordinator组件开启重调度功能。
阅读前提示
使用本文前,建议您已参见重调度概述了解重调度的功能介绍、使用场景、工作流程和基本概念。
本文以节点污点校验插件
RemovePodsViolatingNodeTaints
为例,请参见Kubernetes官方文档了解污点和容忍度的工作原理、驱逐效果(例如NoSchedule)等概念。如果您是社区Kubernetes Descheduler用户,建议您参见Koordinator Descheduler与Kubernetes Descheduler了解Koordinator Descheduler与Kubernetes Descheduler的差异,并完成组件的迁移。
如果您已经了解基础使用方法,需要了解系统、模板概要、策略插件、驱逐器插件的高级配置参数以实现更精细化的重调度策略,可直接阅读高级配置参数。
前提条件
已创建ACK集群Pro版。具体操作,请参见通过Terraform创建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。
koord-descheduler-config.yaml是ConfigMap格式的对象,用于启用和配置重调度插件
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"的污点的节点。
执行如下命令,部署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
上的Podstress-demo-5f6cddf9-v****
被驱逐。增加了
deschedule=not-allow:NoSchedule
污点的节点cn-beijing.192.XX.XX.247
上的Podstress-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的高级配置参数示例。该配置通过DeschedulerConfiguration
API修改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
字段配置插件。请参见策略插件配置和驱逐器插件配置。
策略插件配置
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。