4. 默认调度算法:节点筛选(Predicates)、节点优选(Priorities)、调度器扩展点

Kubernetes 默认调度器(kube-scheduler)的核心工作流程可概括为两个连续阶段:节点筛选(Predicates)与节点优选(Priorities)。筛选阶段从集群中选出所有满足 Pod 调度约束的候选节点;优选阶段则对这些候选节点进行打分排序,最终选择最优节点完成绑定。此外,调度器还提供了丰富的扩展点(Extension Points),允许用户在不修改核心代码的前提下注入自定义调度逻辑。

默认调度器三阶段工作流 1. 节点筛选 Predicates 2. 节点优选 Priorities 3. 绑定 Bind 调度器扩展点(Extension Points) QueueSort | PreFilter | Filter | PostFilter | PreScore | Score | NormalizeScore | Reserve | Permit | PreBind | Bind | PostBind 用户可在这些扩展点注入自定义插件,覆盖或增强默认调度行为 输入:Pod + 所有 Node 信息 调度队列 + 集群快照 输出:Pod 与最优 Node 的绑定 写入 etcd,更新调度状态

4.1 节点筛选(Predicates)

筛选阶段是一组硬约束(Hard Constraints)的集合,只有通过所有激活筛选器的节点才会进入下一阶段。如果没有任何节点通过筛选,Pod 将处于 Pending 状态,调度器会持续重试直到满足条件。

筛选器名称 功能描述 关键参数
PodFitsResources 检查节点剩余 CPU、内存等资源是否满足 Pod 请求 requests.cpu, requests.memory
PodFitsHostPorts 检查节点上指定端口是否已被占用 containerPort, hostPort
PodMatchNodeSelector 检查节点标签是否匹配 Pod 的 nodeSelector 或 nodeAffinity nodeSelector, matchExpressions
PodToleratesNodeTaints 检查 Pod 的 tolerations 是否能容忍节点的 taints taints, tolerations
CheckNodeDiskPressure 检查节点是否处于磁盘压力状态 NodeCondition
CheckNodeMemoryPressure 检查节点是否处于内存压力状态 NodeCondition
CheckNodePIDPressure 检查节点是否处于 PID 压力状态 NodeCondition
CheckNodeUnschedulable 检查节点是否被标记为不可调度(spec.unschedulable: true) node.Spec.Unschedulable
InterPodAffinity 检查节点上已有 Pod 是否满足 Pod 的亲和性/反亲和性规则 podAffinity, podAntiAffinity
性能优化提示: 筛选器按计算开销从低到高排序执行。例如,CheckNodeUnschedulable 和 PodFitsResources 优先执行,而 InterPodAffinity 等需要遍历所有 Pod 的筛选器放在最后。这种排序可以尽早淘汰不合格节点,减少计算量。

4.2 节点优选(Priorities)

优选阶段对通过筛选的节点进行软评分(Soft Scoring),每个优选器输出 0-100 的分数,最终按权重加权求和,得分最高的节点被选中。如果多个节点得分相同,调度器会随机选择一个。

优选器名称 评分逻辑 默认权重
LeastRequestedPriority 优先选择资源利用率低的节点,实现负载均衡 1
MostRequestedPriority 优先选择资源利用率高的节点,提高资源装箱率 1
BalancedResourceAllocation 优先选择 CPU 和内存使用率最均衡的节点 1
NodePreferAvoidPodsPriority 根据节点注解 scheduler.alpha.kubernetes.io/preferAvoidPods 打分 10000
NodeAffinityPriority 根据 preferredDuringSchedulingIgnoredDuringExecution 亲和性规则打分 2
TaintTolerationPriority 根据 Pod 对节点 taints 的容忍程度打分,容忍越多分数越高 1
InterPodAffinityPriority 根据 Pod 亲和性/反亲和性偏好打分 2
ImageLocalityPriority 优先选择已缓存 Pod 所需镜像的节点 1
关键理解: 筛选是“能不能调度”,优选是“调度到哪里最好”。筛选失败意味着 Pod 无法运行在该节点;优选分数低只是调度优先级低,并不阻止调度。

4.3 调度器扩展点(Extension Points)

Kubernetes 1.19+ 的调度器框架(Scheduling Framework)将调度流程拆分为多个扩展点,每个扩展点对应一个调度阶段。用户可以通过实现 Plugin 接口并注册到指定扩展点,来定制调度行为。

调度器扩展点与插件注入位置 QueueSort PreFilter Filter PostFilter PreScore Score Normalize Reserve Permit PreBind Bind PostBind 扩展点分类说明 • Filter 类(PreFilter/Filter/PostFilter):控制节点是否进入候选列表 • Score 类(PreScore/Score/NormalizeScore):控制节点打分与分数归一化 • Bind 类(Reserve/Permit/PreBind/Bind/PostBind):控制绑定前的资源预留、权限检查、绑定执行与后处理 • QueueSort:控制调度队列中 Pod 的排序顺序 • 用户通过实现 schedulerframework.Plugin 接口并注册到 KubeSchedulerConfiguration 来注入自定义逻辑

4.4 自定义调度器配置示例

以下是一个使用 KubeSchedulerConfiguration 启用自定义插件的配置片段:

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: custom-scheduler
    plugins:
      filter:
        enabled:
          - name: "MyCustomFilter"
      score:
        enabled:
          - name: "MyCustomScorer"
        disabled:
          - name: "*"  # 禁用所有默认评分插件
    pluginConfig:
      - name: "MyCustomFilter"
        args:
          threshold: 80
注意: 禁用默认插件(如 NodeResourcesFit、NodeName)可能导致调度行为异常。建议在自定义插件中保留关键筛选逻辑,或通过 disabled 精确控制而非通配符禁用。

4.5 调度算法选择策略

  • 默认策略:适用于大多数通用工作负载,兼顾资源利用率和负载均衡。
  • 装箱策略(Bin Packing):启用 MostRequestedPriority 并提高权重,适用于资源紧张、需要最大化节点利用率的场景。
  • 拓扑感知策略:结合 NodeAffinityPriority 和 InterPodAffinityPriority,将 Pod 调度到靠近数据源或同组 Pod 的节点,降低网络延迟。
  • 自定义策略:通过扩展点注入 GPU 拓扑、NUMA 亲和性、存储本地性等专业调度逻辑。
生产建议: 在大型集群中,筛选器和优选器的数量直接影响调度延迟。建议定期使用 scheduler_scheduling_duration_seconds 指标监控各阶段耗时,对计算开销大的插件(如 InterPodAffinity)进行针对性优化或降级。