3. Scheduler 调度器架构:调度器组件、调度队列、调度算法、调度周期、与 API Server 交互
Kubernetes Scheduler(kube-scheduler)是控制平面中负责将待调度 Pod 绑定到合适 Node 的核心组件。在集群升级与证书轮换场景中,理解调度器内部架构是制定节点排空策略的前提——只有掌握调度器如何选择 Pod、如何与 API Server 交互,才能准确预判排空过程中哪些 Pod 会被重新调度、哪些 Node 会进入“不可调度”状态。
3.1 调度器组件架构
kube-scheduler 采用插件化架构,内部由三大核心模块构成:调度队列、调度框架(Scheduling Framework)和 绑定循环。调度框架通过注册一系列插件(Plugin)来实现调度算法,每个插件在调度周期的特定扩展点(Extension Point)执行。
| 组件 | 职责 | 与排空的关系 |
|---|---|---|
| 调度队列 | 管理待调度 Pod 的优先级排序与重试 | 排空时 Pod 被驱逐后进入队列等待重新调度 |
| 调度框架 | 定义扩展点,执行 Filter/Score/Normalize/Bind 等插件 | 决定排空后的 Pod 能否找到合适 Node |
| 绑定循环 | 将调度结果写入 API Server(Pod 与 Node 的绑定关系) | 绑定失败会导致 Pod 卡在 Pending 状态 |
| 缓存(Scheduler Cache) | 缓存 Node 和 Pod 状态,减少对 API Server 的读请求 | 缓存过期可能导致调度决策基于过时数据 |
3.2 调度队列(Scheduling Queue)
调度队列是调度器的入口,负责管理所有等待调度的 Pod。kube-scheduler 默认使用 PriorityQueue 实现,内部维护三个子队列:
- ActiveQ(活跃队列):存放所有可以立即调度的 Pod,按优先级排序。
- BackoffQ(退避队列):存放调度失败后需要等待一段时间才能重试的 Pod,退避时间指数增长。
- UnschedulableQ(不可调度队列):存放因资源不足、节点不可用等原因无法调度的 Pod,等待集群状态变化后重新评估。
3.3 调度算法与调度周期
调度器将每个 Pod 的调度过程分为两个阶段:调度周期(Scheduling Cycle)和 绑定周期(Binding Cycle)。调度周期是串行的,绑定周期可以并行执行。
3.3.1 调度周期(Scheduling Cycle)
调度周期包含以下扩展点,每个扩展点可以注册多个插件:
| 扩展点 | 插件类型 | 作用 |
|---|---|---|
| QueueSort | 排序 | 定义 Pod 在队列中的排序规则(默认按优先级) |
| PreFilter | 预过滤 | 检查 Pod 的调度约束(如 NodeSelector、Affinity) |
| Filter | 过滤 | 筛选出满足 Pod 资源需求的 Node(如 CPU、内存、端口) |
| PostFilter | 后过滤 | 当所有 Node 都被过滤掉时,执行抢占或标记不可调度 |
| PreScore | 预打分 | 运行评分前的准备工作 |
| Score | 打分 | 对通过过滤的 Node 进行评分(0-100) |
| NormalizeScore | 归一化 | 将多个插件的评分结果合并为最终分数 |
| Reserve | 预留 | 在缓存中预留 Pod 的资源,防止并发调度冲突 |
| Permit | 许可 | 允许或拒绝调度结果(可用于实现调度门控) |
3.3.2 绑定周期(Binding Cycle)
绑定周期在调度周期之后执行,包含以下扩展点:
- PreBind:绑定前的准备工作(如 CNI 网络分配、存储卷挂载准备)。
- Bind:将 Pod 与 Node 的绑定关系写入 API Server(通过 POST /api/v1/namespaces/{ns}/pods/{name}/binding)。
- PostBind:绑定成功后的清理或通知操作。
3.4 与 API Server 的交互
kube-scheduler 与 API Server 的交互主要通过 Informer 机制 和 REST API 完成。理解这些交互对于排空操作至关重要,因为排空过程中调度器需要实时感知 Node 状态变化和 Pod 驱逐事件。
3.4.1 监听机制(Informer)
调度器启动时会为 Pod、Node、PersistentVolumeClaim(PVC)、StorageClass 等资源创建 Informer,通过 List-Watch 模式从 API Server 获取资源变更事件:
- List:启动时全量拉取资源列表,初始化缓存。
- Watch:持续监听资源变更事件(ADDED/MODIFIED/DELETED),增量更新缓存。
3.4.2 写入操作
调度器对 API Server 的写入操作主要包括:
| 操作 | API 路径 | 触发时机 |
|---|---|---|
| Pod 绑定 | POST /api/v1/namespaces/{ns}/pods/{name}/binding | 调度周期完成后,将 Pod 绑定到选定 Node |
| Pod 状态更新 | PATCH /api/v1/namespaces/{ns}/pods/{name}/status | 更新 Pod 的调度相关状态(如 NominatedNodeName) |
| 事件记录 | POST /api/v1/namespaces/{ns}/events | 记录调度失败原因、抢占事件等 |
3.4.3 证书轮换对交互的影响
3.5 调度器高可用与 Leader Election
在生产环境中,kube-scheduler 通常以多副本方式部署,通过 Leader Election 机制保证同一时刻只有一个调度器实例执行调度决策:
- 所有副本通过 API Server 的
kube-system/kube-schedulerEndpoint 或 Lease 对象竞争 Leader 角色。 - Leader 实例负责执行调度周期和绑定周期,其他副本处于 Standby 状态。
- 当 Leader 实例故障或证书轮换导致连接中断时,其他副本会在 Lease 过期后接管调度任务。