1. 调度器架构总览:核心组件、调度框架与扩展点

Kubernetes 调度器(kube-scheduler)是控制平面中负责将 Pod 绑定到合适 Node 的核心组件。其设计经历了从“硬编码调度策略”到“可插拔调度框架”的重大演进。本章将拆解调度器的内部架构、调度框架(Scheduling Framework)的插件化设计,以及关键的扩展点(Extension Points)。

1.1 调度器核心组件

调度器内部由多个协作模块构成,每个模块承担明确的职责。下表列出了核心组件及其功能:

组件 职责 说明
调度队列 管理待调度 Pod 包含 activeQ、backoffQ、unschedulableQ 三个子队列,支持优先级排序与重试
调度框架 插件化调度流程 定义扩展点,允许用户注入自定义调度逻辑
调度缓存 缓存集群状态 维护 Node 和 Pod 的实时快照,避免频繁访问 API Server
调度器主循环 驱动调度周期 从队列取出 Pod,依次执行过滤、打分、绑定等阶段
绑定器 写入绑定关系 将 Pod 与选定 Node 的绑定记录写入 API Server
关键指标:调度延迟(Scheduling Latency)通常指 Pod 进入调度队列到完成绑定的时间。核心组件中,调度队列的排序效率和调度框架的插件执行时间是主要影响因素。

1.2 调度框架(Scheduling Framework)

调度框架是 Kubernetes 1.15+ 引入的插件化架构,它将调度周期拆解为多个独立的扩展点。每个扩展点可以注册一个或多个插件,插件按顺序执行,共同决定 Pod 的调度结果。

调度框架的核心设计原则:

  • 可插拔:插件通过配置文件动态加载,无需重新编译调度器。
  • 分层:调度周期分为 调度周期(Scheduling Cycle) 和 绑定周期(Binding Cycle),两者异步执行。
  • 扩展点明确:每个扩展点有固定的输入输出和错误处理语义。
调度框架(Scheduling Framework)整体架构 调度队列 调度周期(Scheduling Cycle) 绑定周期(Binding Cycle) PreFilter Filter PostFilter PreScore Score NormalizeScore Reserve PreBind Bind PostBind 说明: • 调度周期和绑定周期异步执行:调度周期选出候选 Node 后,绑定周期独立完成绑定。 • 每个扩展点可注册多个插件,插件按配置顺序执行,任一插件返回错误则终止当前周期。 • 扩展点之间的数据通过 CycleState 对象传递,插件可读写共享状态。

1.3 扩展点(Extension Points)详解

调度框架定义了 11 个标准扩展点,分布在调度周期和绑定周期中。每个扩展点有特定的语义和调用时机:

扩展点 所属周期 调用时机 典型用途
PreFilter 调度 过滤前预处理 Pod 合法性检查、资源预计算
Filter 调度 过滤不满足条件的 Node 节点选择器、资源不足、端口冲突
PostFilter 调度 过滤后无可用 Node 时触发 抢占、调度失败处理
PreScore 调度 打分前预处理 计算评分所需的数据
Score 调度 对通过过滤的 Node 打分 资源均衡、亲和性评分
NormalizeScore 调度 分数归一化 将多个插件的分数合并为最终分数
Reserve 调度 预留资源 在缓存中预留 Pod 资源,防止冲突
Permit 调度 批准或延迟绑定 实现准入控制、等待条件
PreBind 绑定 绑定前预处理 网络配置、存储挂载准备
Bind 绑定 执行绑定 写入绑定记录到 API Server
PostBind 绑定 绑定后清理 日志记录、指标上报
优化提示:在多队列排序场景中,PreFilter 和 Filter 扩展点对调度延迟影响最大。如果插件执行时间过长,会阻塞整个调度周期。建议将耗时操作(如外部 API 调用)异步化或使用缓存。

1.4 调度队列与排序机制

调度队列是调度器的入口,负责管理所有待调度的 Pod。它包含三个子队列:

  • activeQ:存放准备调度的 Pod,按优先级排序。
  • backoffQ:存放调度失败但可重试的 Pod,按退避时间排序。
  • unschedulableQ:存放因资源不足等原因无法调度的 Pod,等待集群状态变化后重新入队。

队列排序的核心逻辑由 LessFunc 决定,默认基于 Pod 优先级、创建时间等字段。自定义排序可以通过实现 QueueSortPlugin 扩展点注入。

调度队列与排序流程 activeQ 按优先级排序,立即调度 backoffQ 按退避时间排序,延迟重试 unschedulableQ 等待集群状态变化 调度框架执行 绑定成功 调度失败 退避 集群变化 • 调度器主循环每次从 activeQ 取出一个 Pod,执行调度框架;失败后根据退避策略放入 backoffQ 或 unschedulableQ。 • QueueSortPlugin 扩展点允许自定义 activeQ 的排序逻辑,是实现多队列排序的核心入口。

1.5 调度器工作流程总结

一个完整的调度周期包含以下步骤:

  1. 入队:Pod 被创建或更新后,通过 Informer 机制加入调度队列。
  2. 出队:调度器主循环从 activeQ 取出优先级最高的 Pod。
  3. 过滤:执行 Filter 扩展点,筛选出满足条件的 Node 列表。
  4. 打分:执行 Score 扩展点,对候选 Node 进行评分。
  5. 选择:选择得分最高的 Node 作为绑定目标。
  6. 绑定:执行 Bind 扩展点,将 Pod 绑定到选定 Node。
  7. 后处理:执行 PostBind 扩展点,完成清理和指标上报。
延迟优化关注点:在多队列排序场景中,步骤 2(出队排序)和步骤 3-4(过滤/打分)是延迟瓶颈。队列排序的复杂度直接影响 Pod 等待时间,而过滤/打分插件的执行效率决定了调度周期的耗时。