1. K8s 调度基础:Kubernetes 调度器架构、调度流程、调度器组件详解
Kubernetes 调度器(kube-scheduler)是控制平面的核心组件之一,负责将待调度的 Pod 绑定到最合适的 Node 上。调度决策不仅影响集群的资源利用率,还直接决定工作负载的性能、稳定性和成本。本章从架构、流程和组件三个维度深入解析调度器的工作原理。
1.1 调度器整体架构
kube-scheduler 采用“插件化 + 管道”架构,内部维护一个调度队列(Scheduling Queue)和一个调度框架(Scheduling Framework)。调度器通过 API Server 监听未调度的 Pod(spec.nodeName 为空),依次经过过滤、打分、绑定三个阶段完成调度决策。
架构要点:调度器本身是无状态的,所有待调度 Pod 和 Node 信息均从 API Server 缓存(Informer)中获取。调度框架的插件化设计允许用户通过
SchedulerConfiguration 自定义过滤、打分、预留等阶段的扩展点。
1.2 调度流程详解
调度器对每个 Pod 执行一个完整的调度周期(Scheduling Cycle)和绑定周期(Binding Cycle)。调度周期是串行的,绑定周期可以异步并发执行。完整流程分为以下 6 个步骤:
| 步骤 | 阶段 | 说明 | 关键组件 |
|---|---|---|---|
| 1 | 队列排序 | 从调度队列中按优先级取出下一个待调度 Pod | PriorityQueue、QoS 排序 |
| 2 | 过滤(Filter) | 遍历所有 Node,剔除不满足 Pod 约束的节点 | NodeResourcesFit、NodeSelector、NodeAffinity |
| 3 | 打分(Score) | 对过滤后的 Node 进行 0-100 评分,选出最优节点 | NodeResourcesBalancedAllocation、ImageLocality |
| 4 | 预留(Reserve) | 在选定 Node 上预留资源,防止并发冲突 | Reserve 插件、Cache 更新 |
| 5 | 绑定(Bind) | 通过 API Server 将 Pod 的 spec.nodeName 写入 etcd |
DefaultBinder、VolumeBinding |
| 6 | 后处理(PostBind) | 清理临时状态,记录调度指标 | MetricsRecorder、EventRecorder |
关键优化点:调度周期默认是串行的,但绑定周期可以并发执行。在集群规模较大时,可以通过调整
kube-scheduler --bind-timeout 和启用 Permit 插件来优化吞吐量。
1.3 调度器核心组件详解
调度器由多个内部组件协同工作,每个组件承担明确的职责。下表列出核心组件及其功能:
| 组件 | 类型 | 职责 | 配置方式 |
|---|---|---|---|
| SchedulingQueue | 队列 | 管理待调度 Pod,支持优先级、抢占、回退 | 通过 podPriorityThreshold 配置 |
| Framework | 框架 | 调度周期和绑定周期的执行引擎,管理插件生命周期 | 通过 KubeSchedulerConfiguration 配置插件 |
| Cache | 缓存 | 维护 Node 和 Pod 的实时状态快照,减少 API Server 压力 | 自动维护,无需手动配置 |
| Extenders | 扩展器 | 外部调度扩展,支持自定义过滤和打分逻辑(已逐步被插件替代) | 通过 extenders 字段配置 |
| EventRecorder | 事件 | 记录调度事件到 API Server,用于排障和审计 | 默认启用,可通过 --event-burst 调整 |
| Metrics | 指标 | 暴露调度延迟、队列深度、调度次数等 Prometheus 指标 | 通过 --metrics-bind-address 配置 |
1.4 调度框架插件扩展点
调度框架定义了 11 个扩展点(Extension Points),插件可以注册到这些扩展点来干预调度决策。最常用的扩展点包括:
- QueueSort:定义 Pod 在调度队列中的排序逻辑,默认按优先级排序。
- PreFilter:在过滤前执行预处理,例如检查 Pod 的 Volume 是否就绪。
- Filter:过滤不满足条件的 Node,是调度性能的关键瓶颈。
- PostFilter:过滤后无可用 Node 时触发,用于抢占(Preemption)逻辑。
- PreScore:打分前执行预处理,例如计算 Pod 的拓扑分布偏好。
- Score:对 Node 打分,支持多维度加权。
- Reserve:在选定 Node 上预留资源,防止并发冲突。
- Permit:在绑定前等待外部条件(如 GitOps 窗口信号),是本章后续课程的核心扩展点。
- PreBind:绑定前执行准备工作,例如动态创建 Volume。
- Bind:执行绑定操作,默认使用 API Server 的 Binding 接口。
- PostBind:绑定后清理临时状态。
注意:Permit 扩展点允许插件“批准”或“拒绝”绑定,是实现 GitOps 窗口数据传输机制的关键入口。在后续章节中,我们将基于 Permit 插件实现窗口期内的调度暂停与恢复。
1.5 调度器性能关键指标
在生产环境中,调度器的性能直接影响集群的响应速度。以下指标需要重点监控:
| 指标名称 | 类型 | 说明 | 建议阈值 |
|---|---|---|---|
scheduler_queue_incoming_pods_total |
Counter | 进入调度队列的 Pod 总数 | 无固定阈值,用于计算吞吐量 |
scheduler_e2e_scheduling_duration_seconds |
Histogram | Pod 从入队到绑定完成的端到端延迟 | P99 < 5s |
scheduler_scheduling_attempts_total |
Counter | 调度尝试次数(包括重试) | 重试率 < 5% |
scheduler_pod_scheduling_duration_seconds |
Histogram | 调度周期耗时(不含绑定周期) | P99 < 1s |
scheduler_unschedulable_pods |
Gauge | 当前无法调度的 Pod 数量 | 持续 > 0 需告警 |
实战建议:在 GitOps 窗口场景下,建议额外监控
scheduler_permit_waiting_pods(如果自定义 Permit 插件)和窗口期内的调度队列积压情况,以便及时调整窗口时长或并发度。