Linux descheduler 的 RemoveDuplicates / LowNodeUtilization 策略优先级

1次阅读

removeduplicates 仅当存在完全相同的副本集且节点亲和性、污点容忍等调度约束完全一致时才触发,非自动去重同名pod;lownodeutilization需cpu和内存利用率同时低于阈值(基于allocatable计算);策略执行顺序依配置文件排列,建议removeduplicates置前;驱逐后pending多因调度条件不满足,需检查事件与资源约束。

Linux descheduler 的 RemoveDuplicates / LowNodeUtilization 策略优先级

RemoveDuplicates 策略为什么没触发?

它只在存在「完全相同副本集 + 相同节点亲和性/污点容忍」的 Pod 时才起作用,不是“自动去重”所有同名 Pod。常见误判是以为 label selector 一样就算重复,其实还要看 nodeSelectortolerationstopologySpreadConstraints 等调度约束是否完全一致。

实操建议:

  • kubectl get pods -o wide 对比疑似重复 Pod 的 NODE 列 —— 如果已分散在不同节点,RemoveDuplicates 不会动它们
  • 检查 Pod spec 中的 schedulerName:如果用了非默认调度器(如 volcano),descheduler 默认不处理
  • 确保策略配置里启用了 excludeOwnerKinds 白名单外的控制器类型,否则可能跳过 Deployment 管理的 Pod

LowNodeUtilization 的阈值怎么才算“低”?

它不是看单个指标,而是同时满足 CPU 和内存两个维度的「低于阈值」才算节点低利用率。默认阈值是 cpuThresholdPercent: 10memoryThresholdPercent: 20,但注意:这两个是「节点总容量」的百分比,不是 allocatable。

实操建议:

  • kubectl describe node 查看 CapacityAllocatable,计算时以 Allocatable 为分母更贴近实际可调度空间
  • 如果节点有大量 systemd 进程或 kubelet 自身开销,top 显示的 usage 可能远高于 descheduler 认为的 utilization(后者只算 Pod requests 总和 / Allocatable)
  • 避免把 thresholds 设得太低(比如都设成 5%),否则容易误判系统组件占满的控制平面节点为“可清空”

RemoveDuplicates 和 LowNodeUtilization 谁先执行?

descheduler 按配置文件中策略出现的顺序执行,没有内置优先级。但行为上存在隐含依赖:如果 RemoveDuplicates 把某个节点上的冗余 Pod 驱逐了,可能让该节点进入 LowNodeUtilization 的识别范围;反过来,如果先触发 LowNodeUtilization 清空节点,RemoveDuplicates 就可能找不到足够多的同构 Pod 来比较。

实操建议:

  • DeschedulerPolicy YAML 中,把 RemoveDuplicates 放在 LowNodeUtilization 前面,更符合“先收敛再腾挪”的逻辑
  • 不要指望两个策略协同完成一次“完美腾挪”——descheduler 不做跨策略状态传递,每次运行都是独立扫描
  • 若需强顺序控制,拆成两个独立 Job,用 ttlSecondsAfterFinishedbackoffLimit 控制串行执行

驱逐后 Pod 卡在 Pending 的常见原因

descheduler 只负责驱逐,不保证重调度成功。Pending 往往是因为目标节点不满足调度条件,而不是 descheduler 本身出错。

实操建议:

  • 检查被驱逐 Pod 的 eventskubectl describe pod <name></name>,重点看 FailedScheduling 后面的具体原因,比如 node(s) had taints that the pod didn't tolerate
  • 确认集群是否有足够 allocatable 资源:descheduler 计算利用率只看 requests,但 kube-scheduler 分配时会检查 limits 和实际可用 capacity
  • 如果用了 TopologySpreadConstraints,驱逐后剩余 Pod 可能违反 maxSkew,导致新 Pod 无法调度 —— 这类约束不会被 descheduler 检查

真正难处理的是那些「看起来该被移走,但又卡在 Pending」的 Pod:它们暴露的是调度策略和资源规划之间的断层,不是 descheduler 配置本身的问题。

text=ZqhQzanResources