Kubernetes Descheduler 全维度指南(Helm 部署+配置+优缺点)
一、Descheduler 核心定义
Kubernetes Descheduler 是一款官方开源工具,用于主动驱逐不符合调度策略的 Pod,重新调度至更优节点,解决集群运行中因节点资源变化、标签/污点更新、亲和性调整等导致的 Pod 分布不均问题(区别于 K8s 原生调度器仅在 Pod 创建时生效)。
二、完整 Helm Chart 安装步骤
1. 环境前置要求
- Kubernetes 集群版本 ≥ 1.21(Descheduler v0.28+ 适配,低版本需对应降级 Descheduler);
- Helm 版本 ≥ 3.0;
- 集群内有
cluster-admin权限(Descheduler 需读取/操作全集群 Pod/Node 资源)。
2. 安装流程
步骤1:添加官方 Helm 仓库
bash
# 添加 Descheduler 官方仓库(CNCF 托管)
helm repo add descheduler https://kubernetes-sigs.github.io/descheduler/
# 更新仓库索引
helm repo update
步骤2:自定义 values.yaml(核心配置,见下文"必要配置")
yaml
# 基础配置
replicaCount: 1
image:
repository: k8s.gcr.io/descheduler/descheduler
tag: v0.29.0 # 适配 K8s 1.24+,按需选择版本
pullPolicy: IfNotPresent
# 调度策略配置(核心)
policy:
profiles:
- name: default
pluginConfig:
- name: "RemoveDuplicates" # 驱逐重复 Pod(同一节点多副本)
args:
excludeOwnerKinds: ["DaemonSet"]
- name: "LowNodeUtilization" # 驱逐低资源利用率节点的 Pod
args:
thresholds:
cpu: 20 # 节点CPU利用率低于20%触发
memory: 20
targetThresholds:
cpu: 50 # 目标利用率50%
memory: 50
- name: "HighNodeUtilization" # 驱逐高负载节点的 Pod
args:
thresholds:
cpu: 80 # 节点CPU利用率高于80%触发
memory: 80
- name: "NodeAffinity" # 驱逐不满足节点亲和性的 Pod
args:
nodeAffinityType: ["requiredDuringSchedulingIgnoredDuringExecution"]
- name: "PodAffinity" # 驱逐不满足Pod亲和性的 Pod
args:
hardPodAffinityWeight: 1
- name: "TaintToleration" # 驱逐不满足污点容忍的 Pod
args:
tolerateTaints: []
- name: "NodeResourcesFit" # 驱逐节点资源不足的 Pod
args:
ignoredResources: ["ephemeral-storage"]
plugins:
deschedule:
enabled:
- "RemoveDuplicates"
- "LowNodeUtilization"
- "HighNodeUtilization"
- "NodeAffinity"
- "PodAffinity"
- "TaintToleration"
- "NodeResourcesFit"
disabled: []
# 调度周期(默认每10分钟执行一次)
args:
- --policy-config-file=/policy/policy.yaml
- --descheduling-interval=10m
- --v=2 # 日志级别
# 权限配置(默认已包含 ClusterRole/ClusterRoleBinding,无需额外修改)
rbac:
create: true
rules: []
clusterRoleAnnotations: {}
clusterRoleBindingAnnotations: {}
# 资源限制
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
# 命名空间(建议独立部署)
namespace: kube-system # 或自定义命名空间如 descheduler-system
步骤3:安装 Descheduler
bash
# 创建命名空间(若自定义)
kubectl create namespace descheduler-system
# 安装 Helm Chart
helm install descheduler descheduler/descheduler \
--namespace descheduler-system \
--values values.yaml \
--version 0.29.0 # 与镜像版本一致
步骤4:验证安装
bash
# 检查 Pod 运行状态
kubectl get pods -n descheduler-system
# 查看日志验证策略执行
kubectl logs -f <descheduler-pod-name> -n descheduler-system
三、核心必要配置(按优先级排序)
1. 调度策略(policy.profiles)
Descheduler 核心能力依赖策略配置,需根据集群场景启用/禁用插件:
| 插件名称 | 作用 | 必配场景 | 核心参数示例 |
|---|---|---|---|
| RemoveDuplicates | 驱逐同一节点上的重复 Pod(如 Deployment 多副本被调度到同一节点) | 所有集群 | excludeOwnerKinds: ["DaemonSet"] |
| LowNodeUtilization | 驱逐低负载节点 Pod,均衡集群资源利用率 | 资源碎片化严重的集群 | thresholds.cpu: 20、targetThresholds.cpu: 50 |
| HighNodeUtilization | 驱逐高负载节点 Pod,避免节点资源耗尽 | 节点负载不均的集群 | thresholds.cpu: 80 |
| NodeAffinity | 驱逐不满足节点亲和性的 Pod(如节点标签更新后) | 依赖节点亲和性的应用 | nodeAffinityType: ["requiredDuringSchedulingIgnoredDuringExecution"] |
| TaintToleration | 驱逐不满足节点污点容忍的 Pod(如节点新增污点后) | 节点有动态污点的集群 | tolerateTaints: [] |
| PodLifeTime | 驱逐运行超期的 Pod(需手动启用) | 需定期重启 Pod 的场景 | maxPodLifeTimeSeconds: 86400 |
2. 调度周期(args.descheduling-interval)
- 格式:
--descheduling-interval=Xm(X 为分钟,默认 10m); - 建议值:测试环境 5m,生产环境 10-30m(避免频繁驱逐影响业务);
- 核心原则:周期过短易导致 Pod 频繁重建,过长无法及时均衡资源。
3. 资源限制(resources)
-
Descheduler 本身资源消耗极低,建议配置:
yamlresources: limits: cpu: 100m memory: 128Mi requests: cpu: 50m memory: 64Mi -
避免无限制占用资源,防止影响集群核心组件。
4. 权限配置(rbac)
- 必须开启
rbac.create: true,Descheduler 需以下核心权限:- 读取所有节点/Pod 信息;
- 驱逐 Pod(
pods/eviction权限); - 读取 Namespace/Node 标签/污点。
5. 排除规则(可选但建议配置)
避免驱逐核心组件 Pod,需在策略中添加排除规则:
yaml
policy:
profiles:
- name: default
plugins:
deschedule:
enabled: [...]
filters: # 排除规则
- name: "Namespaces"
args:
include: []
exclude: ["kube-system", "descheduler-system"] # 排除核心命名空间
- name: "OwnerReferences"
args:
excludeOwnerKinds: ["DaemonSet", "StatefulSet"] # 排除有状态应用(按需)
四、Descheduler 核心优缺点
1. 优点
| 优势点 | 具体说明 |
|---|---|
| 动态均衡集群资源 | 解决 K8s 原生调度器"一次性调度"缺陷,主动优化运行中 Pod 分布 |
| 适配多种不均衡场景 | 支持重复 Pod、资源高低负载、亲和性/污点不匹配等多类场景的 Pod 重调度 |
| 非侵入式部署 | 仅驱逐 Pod 不修改应用配置,Helm 一键部署,对业务无感知 |
| 高度可配置 | 支持启用/禁用特定插件、设置排除规则,适配不同集群规模和业务场景 |
| 官方维护,兼容性好 | 与 K8s 版本同步迭代,支持 1.21+ 所有主流版本 |
2. 缺点
| 风险点 | 具体说明 | 规避方案 |
|---|---|---|
| 可能导致业务中断 | Pod 被驱逐后重建过程中业务短暂不可用,无状态应用影响小,有状态应用风险高 | 1. 排除 StatefulSet 等有状态应用;2. 配置 PodDisruptionBudget 限制驱逐数量 |
| 资源消耗叠加 | 大规模驱逐时,Pod 重建会占用集群资源,可能引发资源竞争 | 1. 降低调度频率;2. 限制单次驱逐 Pod 数量(通过 maxPodsToEvictPerNode) |
| 策略配置复杂 | 插件参数多,配置不当易导致无效驱逐或过度驱逐 | 1. 先在测试环境验证策略;2. 从基础插件(RemoveDuplicates)逐步启用 |
| 无原生监控告警 | 默认无内置监控指标,需手动集成 Prometheus | 1. 配置 Prometheus 抓取 Descheduler 日志;2. 基于驱逐事件配置告警规则 |
| 不支持预调度验证 | 无法提前验证驱逐后的调度结果,可能出现驱逐后 Pod 无法重新调度的情况 | 1. 先启用模拟模式(--dry-run)验证;2. 确保集群有足够空闲节点 |
五、最佳实践补充
- 测试先行 :先通过
--dry-run模式运行 Descheduler,验证策略是否触发预期驱逐,避免直接影响生产; - 配合 PDB:为核心应用配置 PodDisruptionBudget,限制单次驱逐的 Pod 数量,保障业务可用性;
- 监控驱逐事件:通过 K8s Event 或 Descheduler 日志,监控 Pod 驱逐行为,配置告警(如单次驱逐超 N 个 Pod 告警);
- 版本匹配:Descheduler 版本需与 K8s 集群版本匹配(如 K8s 1.26 对应 Descheduler v0.28+)。
下一步迭代建议
需要我为你编写 Descheduler 核心监控告警配置(Prometheus + Grafana 模板 + 驱逐事件告警规则),帮助你实时监控其运行状态和驱逐行为吗?