Descheduler for Kubernetes(K8s 重调度器)

Descheduler for Kubernetes(K8s 重调度器)是一款官方维护的工具,核心作用是优化已运行 Pod 的调度位置——它会识别并迁移那些因集群状态变化(如节点资源不足、节点亲和性失效等)而“调度不合理”的 Pod,解决原生调度器(kube-scheduler)仅在 Pod 创建时调度、无法动态调整的问题。

一、核心定位与解决的问题

原生 kube-scheduler 仅在 Pod 首次创建时进行调度,当集群后续出现以下情况时,已运行的 Pod 会处于“不合理”状态,此时需要 Descheduler 介入:

  1. 节点资源失衡:部分节点 CPU/内存使用率过高(负载不均),部分节点资源闲置。
  2. 节点亲和性/反亲和性失效:例如 Pod 要求“运行在带 gpu=true 标签的节点”,但节点标签被删除后,Pod 仍留在原节点。
  3. 节点污点/容忍变化:节点新增污点(如 node-role.kubernetes.io/unschedulable=true),而 Pod 无对应容忍,导致后续无法重启。
  4. 新节点加入集群:集群扩容后,原有 Pod 未迁移到新节点,新节点资源闲置。
  5. PVC 绑定优化:Pod 挂载的 PVC 对应的 PV 所在节点与 Pod 当前节点不同,导致跨节点存储访问,性能损耗。

二、工作原理:“识别不合理 Pod → 驱逐 → 原生调度器重新调度”

Descheduler 以 Deployment 形式运行在集群中(通常部署在 kube-system 命名空间),通过定时任务(默认 5 分钟一次,可配置)执行“重调度循环”,核心步骤分为 3 步:

1. 第一步:筛选“可重调度的 Pod”(排除不可迁移的 Pod)

Descheduler 首先会过滤掉无法迁移的 Pod,避免影响核心业务,主要排除规则包括:

  • 标记了 descheduler.alpha.kubernetes.io/evict=false 注解的 Pod(明确禁止重调度)。
  • 本地存储依赖的 Pod(如使用 emptyDirhostPath 且数据不可丢失的 Pod)。
  • 未就绪(Not Ready)的 Pod(可能处于启动中,迁移风险高)。
  • 静态 Pod(由 kubelet 直接管理,无法通过 API 驱逐)。
  • 有本地亲和性的 Pod(如 nodeSelector 绑定特定节点,且无其他节点满足条件)。
  • 核心组件 Pod(如 kube-apiserveretcd 等,通常配置了禁止驱逐注解)。
2. 第二步:通过“策略”识别“不合理 Pod”

Descheduler 内置多种“重调度策略”(可按需启用/禁用),通过策略筛选出需要驱逐的“不合理 Pod”,常用策略如下:

策略名称作用(识别的不合理场景)
RemoveDuplicates同一 Deployment/DaemonSet 的多个 Pod 运行在同一节点,导致节点负载集中,需驱逐部分 Pod 到其他节点。
LowNodeUtilization节点资源利用率过低(如 CPU 使用率 < 20%),或过高(如 CPU 使用率 > 80%),通过驱逐平衡负载。
HighNodeUtilization针对节点资源使用率过高的场景(单独优化过载节点),驱逐部分 Pod 到低负载节点。
RemovePodsViolatingNodeAffinityPod 违反“节点亲和性规则”(如 requiredDuringSchedulingIgnoredDuringExecution),需驱逐到符合条件的节点。
RemovePodsViolatingNodeTaintsPod 无法容忍节点当前的污点(如节点新增 node-role.kubernetes.io/unschedulable),需驱逐。
RemovePodsViolatingTopologySpreadConstraintsPod 违反“拓扑分布约束”(如 topologySpreadConstraints 要求跨节点/跨可用区均匀分布)。
3. 第三步:驱逐 Pod 并由原生调度器重新调度
  • 驱逐逻辑:Descheduler 对筛选出的“不合理 Pod”发送 Eviction API 请求(类似 kubectl drain),触发 Pod 驱逐。
  • 重新调度:Pod 被驱逐后,会进入“Pending”状态,此时原生 kube-scheduler 会按照正常调度流程,将 Pod 重新调度到“合理的节点”(满足资源、亲和性、污点容忍等条件)。
  • 驱逐保护:为避免频繁驱逐,Descheduler 支持配置“驱逐阈值”(如单次最多驱逐节点上 10% 的 Pod)、“冷却时间”(同一 Pod 被驱逐后,多久内不再重新驱逐)。

三、核心配置:通过 ConfigMap 定义重调度策略

Descheduler 的行为由 ConfigMap 配置(默认名称 descheduler-config,挂载到 Descheduler Deployment 中),核心配置包括“调度周期”“启用的策略”“策略参数”,示例如下:

# descheduler-config.yaml(ConfigMap 内容)
apiVersion: v1
kind: ConfigMap
metadata:
  name: descheduler-config
  namespace: kube-system
data:
  policy.yaml: |
    apiVersion: "descheduler/v1alpha2"
    kind: "DeschedulerPolicy"
    schedule: "0 */5 * * *"  # 重调度周期:每 5 分钟一次(Cron 表达式)
    strategies:
      LowNodeUtilization:  # 启用“节点负载均衡”策略
        enabled: true
        params:
          nodeResourceUtilizationThresholds:
            thresholds:  # 节点资源使用率阈值(超过/低于则触发重调度)
              cpu: 80
              memory: 80
              pods: 80
            targetThresholds:  # 目标使用率(重调度后希望达到的水平)
              cpu: 50
              memory: 50
              pods: 50
      RemoveDuplicates:  # 启用“移除重复 Pod”策略
        enabled: true
      RemovePodsViolatingNodeAffinity:  # 启用“移除违反节点亲和性的 Pod”策略
        enabled: true

四、部署与使用注意事项

  1. 部署方式:Descheduler 可通过 Helm Chart(官方维护的 descheduler Chart)或 YAML 清单直接部署,需为其配置 ClusterRole 权限(需访问 podsnodesevictions 等 API 资源)。
  2. 业务影响:驱逐 Pod 会导致业务短暂中断(除非 Pod 属于多副本 Deployment,且配置了 PodDisruptionBudget 控制中断数量),建议:
    • 对核心业务 Pod 配置 descheduler.alpha.kubernetes.io/evict=false 注解,禁止驱逐。
    • 配置 PodDisruptionBudget(PDB),限制同一时间被驱逐的 Pod 数量(如 minAvailable: 1)。
  3. 性能开销:Descheduler 运行时会扫描集群所有 Pod 和节点,对超大规模集群(如 1000+ 节点),建议调大重调度周期(如 15 分钟一次),避免占用过多 API Server 资源。

总结

Descheduler 是原生调度器的“补充工具”——它不替代原生调度器,而是通过“事后优化”解决集群动态变化带来的调度不合理问题,核心价值是提升集群资源利用率、保证 Pod 运行合规性。在中大规模集群(尤其是节点动态变化、业务负载波动大的场景)中,Descheduler 是保障集群稳定性和资源效率的关键组件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

网络飞鸥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值