2. Kubernetes 调度框架:调度器架构、调度队列、调度周期与绑定周期

Kubernetes 调度器(kube-scheduler)是控制平面中负责将 Pod 分配到合适 Node 的核心组件。理解其内部架构、排队机制以及两阶段调度周期,是设计网络拓扑亲和性规则的前提。本章从调度器整体架构出发,依次剖析调度队列、调度周期与绑定周期的运行原理。

2.1 调度器整体架构

kube-scheduler 采用“事件驱动 + 插件化”的架构设计。其核心组件包括:

  • 调度器主循环(Scheduler Main Loop):监听 Pod 与 Node 的变化,触发调度流程。
  • 调度队列(Scheduling Queue):管理待调度的 Pod,支持优先级排序与重试。
  • 调度框架(Scheduling Framework):定义扩展点(Extension Points),允许通过插件注入调度逻辑。
  • 缓存(Cache):维护集群中 Node 与 Pod 的实时状态快照,避免频繁访问 API Server。
架构要点: 调度器本身不直接与容器运行时交互,而是通过 API Server 更新 Pod 的 nodeName 字段完成绑定。所有调度决策基于缓存中的快照数据,而非实时查询。
Kubernetes 调度器整体架构 kube-scheduler 整体架构 API Server 调度器主循环 调度队列 (优先级队列 + 重试) 调度框架 (扩展点 + 插件) 缓存 (Cache) (Node/Pod 快照) 说明: 1. 调度器通过 Watch 机制监听 API Server 中未调度的 Pod。 2. 调度队列按优先级排序,支持退避重试(Backoff)。 3. 调度框架的扩展点允许自定义过滤、评分、绑定等逻辑。

2.2 调度队列:Pod 的排队与重试机制

调度队列是 Pod 进入调度流程的第一道关卡。Kubernetes 使用 优先级队列(Priority Queue) 管理待调度 Pod,确保高优先级任务优先获得调度机会。

2.2.1 队列结构

调度队列内部由三个子队列组成:

子队列 作用 数据来源
activeQ 存放所有待调度的 Pod,按优先级排序 新创建的 Pod、重试队列到期后移入
backoffQ 存放调度失败的 Pod,等待退避时间后重试 调度周期失败的 Pod
unschedulableQ 存放因资源不足或节点不可用而无法调度的 Pod 调度周期失败且不可重试的 Pod
设计意图: 三队列机制避免了频繁重试导致的“惊群效应”,同时保证高优先级 Pod 不会被低优先级任务阻塞。网络拓扑亲和性规则在调度失败时,Pod 会进入 backoffQ 或 unschedulableQ,等待集群拓扑变化后重新尝试。

2.2.2 队列操作流程

  1. 入队(Add):新 Pod 或更新后的 Pod 进入 activeQ,按优先级排序。
  2. 出队(Pop):调度器主循环从 activeQ 取出最高优先级的 Pod。
  3. 调度失败处理:若调度周期失败,Pod 进入 backoffQ(可重试)或 unschedulableQ(不可重试)。
  4. 重试与回迁:backoffQ 中的 Pod 在退避时间到期后自动移回 activeQ;unschedulableQ 中的 Pod 在集群事件(如新增 Node)触发时重新评估。

2.3 调度周期与绑定周期

Kubernetes 调度器将一次 Pod 调度决策拆分为两个独立的阶段:调度周期(Scheduling Cycle) 和 绑定周期(Binding Cycle)。这种分离设计使得调度决策与绑定操作可以异步执行,提升吞吐量。

调度周期与绑定周期流程 调度周期与绑定周期 调度周期 (Scheduling Cycle) PreFilter Filter PostFilter PreScore / Score 绑定周期 (Binding Cycle) Reserve PreBind Bind PostBind 关键区别: • 调度周期:选择候选 Node,不修改集群状态。失败时 Pod 进入 backoffQ。 • 绑定周期:将 Pod 绑定到选定 Node,修改 API Server 中的 nodeName。 • 绑定周期失败不会回滚调度周期的选择,但会触发重试。 • 网络拓扑亲和性规则主要在 Filter 和 Score 阶段生效。

2.3.1 调度周期(Scheduling Cycle)

调度周期是“选择节点”的阶段,包含以下扩展点:

扩展点 作用 网络拓扑亲和性相关
PreFilter 预处理 Pod 信息,校验基本约束 检查 Pod 是否声明了拓扑亲和性规则
Filter 过滤不满足条件的 Node 过滤掉不满足网络拓扑约束的 Node
PostFilter 处理 Filter 后无可用 Node 的情况 触发抢占或返回不可调度原因
PreScore 为评分阶段准备数据 计算网络拓扑距离矩阵
Score 对通过 Filter 的 Node 进行打分 根据网络拓扑距离、带宽、延迟等指标评分
NormalizeScore 归一化评分结果 确保不同插件的评分在同一量级

2.3.2 绑定周期(Binding Cycle)

绑定周期是“执行绑定”的阶段,包含以下扩展点:

扩展点 作用 说明
Reserve 在缓存中预留资源,防止并发冲突 确保同一 Node 不会同时被多个 Pod 绑定
PreBind 绑定前的预处理,如创建存储卷 网络拓扑亲和性规则通常不在此阶段干预
Bind 执行绑定,更新 Pod 的 nodeName 默认通过 API Server 更新;可自定义绑定逻辑
PostBind 绑定后的清理或通知 可用于更新网络拓扑缓存
注意: 绑定周期是幂等的。如果 Bind 调用失败,调度器会重试,但不会回滚 Reserve 阶段预留的资源。因此,网络拓扑亲和性插件在 Reserve 阶段应避免修改外部状态,以免重试时产生副作用。

2.4 调度框架的插件化设计

Kubernetes 调度框架采用 插件(Plugin) 机制,允许用户在不修改调度器核心代码的情况下,注入自定义调度逻辑。每个插件可以注册到多个扩展点,实现过滤、评分、绑定等功能。

2.4.1 插件注册与执行顺序

调度器启动时,通过配置文件指定启用的插件及其执行顺序。以下是一个典型的调度配置片段:

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
  - schedulerName: default-scheduler
    plugins:
      filter:
        enabled:
          - name: "NodeResourcesFit"
          - name: "NodeName"
          - name: "NetworkTopology"   # 自定义网络拓扑过滤插件
      score:
        enabled:
          - name: "NodeResourcesBalancedAllocation"
          - name: "NetworkTopology"   # 自定义网络拓扑评分插件
        disabled:
          - name: "*"                 # 禁用默认评分插件
实践要点: 网络拓扑亲和性插件通常注册到 Filter 和 Score 扩展点。Filter 阶段排除不满足拓扑约束的 Node,Score 阶段根据网络距离、带宽利用率等指标为候选 Node 打分。

2.4.2 插件生命周期

  • 初始化(Init):插件在调度器启动时初始化,加载配置和外部依赖(如网络拓扑数据库)。
  • 执行(Run):每次调度周期或绑定周期,插件在注册的扩展点被调用。
  • 清理(Cleanup):调度器关闭时,插件释放资源。

2.5 本章小结

Kubernetes 调度器通过“调度队列 → 调度周期 → 绑定周期”的三段式架构,实现了高效、可扩展的 Pod 调度。调度队列管理 Pod 的排队与重试,调度周期负责节点选择,绑定周期负责执行绑定。网络拓扑亲和性规则主要作用于调度周期的 Filter 和 Score 扩展点,通过插件化机制灵活集成。理解这一框架,是后续设计基于网络拓扑的亲和性规则的基础。