Kubernetes Descheduler Helm 部署:策略怎么选,装完如何确认它在干活
【免费下载链接】deschedulerDescheduler for Kubernetes项目地址: https://gitcode.com/gh_mirrors/de/descheduler
Descheduler for Kubernetes 会周期性扫描集群,把节点放"错位置"的 Pod 驱逐掉,交给调度器重新安置。官方仓库里自带 Helm chart,一条helm install就能把 CronJob、RBAC 和策略 ConfigMap 全部铺好。本文按"先判断值不值得上 → 怎么装 → 策略取舍 → 验证生效"的顺序走一遍,全程只用最小可运行的命令集。
一、先判断你的集群有哪些 Pod 值得被挪走
一个跑了几个月的集群,常见病灶是节点冷热不均:一部分节点 CPU 长期贴着 90%,另一部分刚过 10%,而调度器只管"能不能放得下",不管"放得匀不匀"。Descheduler 解决的就是这类存量问题,它盯的信号可以归纳成 4 类:
- 资源占用失衡:节点负载明显低于目标水位,或个别节点长期过载,对应
LowNodeUtilization/HighNodeUtilization。 - 规则违反:Pod 所在节点已经不满足它的节点亲和、污点容忍、Pod 间反亲和或拓扑分布约束,对应
RemovePodsViolatingNodeAffinity、RemovePodsViolatingNodeTaints、RemovePodsViolatingInterPodAntiAffinity、RemovePodsViolatingTopologySpreadConstraint。 - 冗余副本:同一 Deployment 的多个副本挤在同一个节点上,对应
RemoveDuplicates。 - 健康异常:容器反复崩溃、重启次数越过阈值,对应
RemovePodsHavingTooManyRestarts。
如果你的集群里这四类问题一个都没有,Descheduler 开了也是空转;如果第一类是主要矛盾,那核心就是后面要讲的LowNodeUtilization阈值怎么调。
二、Descheduler 怎么装:前置检查与 chart 安装
先过三关:
- 版本对应:Descheduler 的版本号和 Kubernetes 小版本是对齐的,比如 v0.36 对应 K8s v1.36,且每个版本只在最近 3 个 K8s 小版本上测试过。装之前先
kubectl version确认集群不低于 1.21,并据此选镜像 tag。 - Helm 3.x:chart 用了
batch/v1的 CronJob,Helm 2 直接不可用。 - 集群管理员权限:chart 要创建 ClusterRole、ClusterRoleBinding 和 ServiceAccount,没有 cluster-admin 等价权限会在渲染后 apply 失败。
拿到 chart 的方式是克隆仓库,进入 chart 目录:
git clone https://gitcode.com/gh_mirrors/de/descheduler cd descheduler/charts/descheduler安装时只改最影响行为的两三个参数即可:
helm install descheduler . -n kube-system --set schedule="*/15 * * * *"values.yaml 里值得注意的 key 有这几个:
schedule:CronJob 触发周期,chart 默认是*/2 * * * *(每 2 分钟一轮),生产环境建议放宽到 10~15 分钟,避免驱逐风暴。image.tag:留空时取 chart 的 appVersion(当前 v0.36.0),想锁定版本就显式给值。kind:默认CronJob,改Deployment则常驻运行,按deschedulingInterval循环,需要同时配置leaderElection。deschedulerPolicy:策略本体,以profiles+plugins的形式渲染成 ConfigMap 挂到 Pod 的/policy-dir/policy.yaml,下一节展开。serviceMonitor.enabled:默认 false,装了 Prometheus Operator 再打开(见第四节)。
改deschedulerPolicy后 Job Pod 会带checksum/config注解,ConfigMap 一变就自动滚动重建,不需要额外操作。
三、内置策略的取舍:默认开了什么,HighNodeUtilization 为什么关着
Descheduler 的每个调度周期都会按 profile 依次执行 Sort → Filter → 驱逐插件,一轮跑完叫一个 Descheduling Cycle:
策略插件的实现都放在 pkg/framework/plugins/ 目录,可以直接对照源码看每个插件的入参。默认渲染出的 policy 已经把插件分成了两组:
- balance 组(
RemoveDuplicates、RemovePodsViolatingTopologySpreadConstraint、LowNodeUtilization):目标是把负载摊匀,是集群调优的主力。 - deschedule 组(
RemovePodsHavingTooManyRestarts、RemovePodsViolatingNodeTaints、RemovePodsViolatingNodeAffinity、RemovePodsViolatingInterPodAntiAffinity):目标是清理"不该在这"的 Pod。
各策略的适用形态可以对照这张图,左边是重复副本与高重启次数,中间是反亲和与拓扑分布,右边是污点与节点标签:
几个取舍建议:
- LowNodeUtilization 的阈值是重点。默认
thresholds为 cpu/memory/pods 各 20、targetThresholds各 50,含义是:只有当某节点利用率低于 20 且集群平均低于 50 时才启动,驱逐以把该节点抬到 50 附近为目标。业务波动大的集群可以把 target 压到 30,防止来回搬 Pod。 - HighNodeUtilization 默认不开,它需要接 metrics.k8s.io 的实时用量,要在 policy 里加
metricsProviders(source 为 KubernetesMetrics),chart 检测到后会为 ClusterRole 追加 metrics 资源权限。开了 balance 组的 LowNodeUtilization 后,通常不需要再叠加它。 - DefaultEvictor 的 Pod 保护默认禁用了
PodsWithLocalStorage(带本地盘的 Pod 不动),启用了PodsWithPVC。如果你的业务大量使用 emptyDir/emptyDir+本地存储,驱逐前务必确认这一项。 - RemovePodsHavingTooManyRestarts默认阈值是 100 次,对"频繁重启但没坏透"的 Pod 很激进,建议按业务容忍度上调。
权限方面 chart 遵循最小集:只有对pods/eviction的 create 权限会真正产生驱逐,其余 nodes/namespaces/pods/PDB 等只是只读 watch,events 用于记录驱逐事件;只有在配置了 KubernetesMetrics 时才会额外授予 metrics.k8s.io 的 get/list。想核对完整规则可以看 clusterrole.yaml。
四、装完之后如何确认它真的在工作
安装后等第一个 schedule 周期触发,看最近一次 Job 的日志最直接:
kubectl get pods -n kube-system -l app.kubernetes.io/name=descheduler日志里出现running profile "default"以及各策略的执行记录,说明周期在跑;看到evicting pod说明确实有 Pod 被挪动。确认没有误伤的方式,是紧接着跑一遍kubectl get pods -A,核对被驱逐的 Pod 都在其他节点重新拉起了。
指标层面,Descheduler 在 10258 端口暴露/metrics,核心有四个:
descheduler_pods_evicted_total:按策略、命名空间、节点分标签的驱逐计数,result="error"表示驱逐失败,这个标签最值得配告警。descheduler_loop_duration_seconds:一个完整周期耗时,接近 schedule 间隔就说明周期太密了。descheduler_strategy_duration_seconds:单个策略耗时,能定位哪个插件拖慢周期。descheduler_build_info:版本核对用。
Prometheus 集成只需--set serviceMonitor.enabled=true,chart 会渲染一个 monitoring.coreos.com/v1 的 ServiceMonitor,配合namespace指向 Prometheus 所在命名空间即可。
五、收尾前检查一遍的三件事
跑完验证后,把这三项过一遍再收工:schedule是否已放宽到业务可接受的间隔;LowNodeUtilization的targetThresholds是否贴合当前集群水位;以及descheduler_pods_evicted_total{result="error"}是否持续为零。之后每周一看一次descheduler_loop_duration_seconds和驱逐计数即可,等下一个 schedule 周期触发,翻一遍 Job 日志确认没有任何 Pod 被误驱逐,这次部署就算落地了。
【免费下载链接】deschedulerDescheduler for Kubernetes项目地址: https://gitcode.com/gh_mirrors/de/descheduler
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考