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。
nodeName 字段完成绑定。所有调度决策基于缓存中的快照数据,而非实时查询。
2.2 调度队列:Pod 的排队与重试机制
调度队列是 Pod 进入调度流程的第一道关卡。Kubernetes 使用 优先级队列(Priority Queue) 管理待调度 Pod,确保高优先级任务优先获得调度机会。
2.2.1 队列结构
调度队列内部由三个子队列组成:
| 子队列 | 作用 | 数据来源 |
|---|---|---|
| activeQ | 存放所有待调度的 Pod,按优先级排序 | 新创建的 Pod、重试队列到期后移入 |
| backoffQ | 存放调度失败的 Pod,等待退避时间后重试 | 调度周期失败的 Pod |
| unschedulableQ | 存放因资源不足或节点不可用而无法调度的 Pod | 调度周期失败且不可重试的 Pod |
2.2.2 队列操作流程
- 入队(Add):新 Pod 或更新后的 Pod 进入 activeQ,按优先级排序。
- 出队(Pop):调度器主循环从 activeQ 取出最高优先级的 Pod。
- 调度失败处理:若调度周期失败,Pod 进入 backoffQ(可重试)或 unschedulableQ(不可重试)。
- 重试与回迁:backoffQ 中的 Pod 在退避时间到期后自动移回 activeQ;unschedulableQ 中的 Pod 在集群事件(如新增 Node)触发时重新评估。
2.3 调度周期与绑定周期
Kubernetes 调度器将一次 Pod 调度决策拆分为两个独立的阶段:调度周期(Scheduling Cycle) 和 绑定周期(Binding Cycle)。这种分离设计使得调度决策与绑定操作可以异步执行,提升吞吐量。
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 | 绑定后的清理或通知 | 可用于更新网络拓扑缓存 |
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: "*" # 禁用默认评分插件
2.4.2 插件生命周期
- 初始化(Init):插件在调度器启动时初始化,加载配置和外部依赖(如网络拓扑数据库)。
- 执行(Run):每次调度周期或绑定周期,插件在注册的扩展点被调用。
- 清理(Cleanup):调度器关闭时,插件释放资源。
2.5 本章小结
Kubernetes 调度器通过“调度队列 → 调度周期 → 绑定周期”的三段式架构,实现了高效、可扩展的 Pod 调度。调度队列管理 Pod 的排队与重试,调度周期负责节点选择,绑定周期负责执行绑定。网络拓扑亲和性规则主要作用于调度周期的 Filter 和 Score 扩展点,通过插件化机制灵活集成。理解这一框架,是后续设计基于网络拓扑的亲和性规则的基础。