2. Kubernetes 调度器基础:kube-scheduler 工作原理、调度框架与调度周期
Kubernetes 调度器(kube-scheduler)是控制平面的核心组件之一,负责将待调度的 Pod 绑定到最合适的 Node 上。理解其工作原理、调度框架(Scheduling Framework)以及调度队列与调度周期,是掌握多集群调度策略的前提。
2.1 kube-scheduler 工作原理
kube-scheduler 通过监听 API Server 获取未调度的 Pod(spec.nodeName 为空),经过一系列过滤、评分、绑定步骤,最终将 Pod 与 Node 绑定。其核心工作流程如下:
- 监听与入队:通过 Informer 机制监听 Pod 和 Node 的变化,将待调度 Pod 加入调度队列。
- 调度周期:从队列中取出一个 Pod,依次执行过滤(Predicates)和评分(Priorities)算法。
- 绑定周期:将选中的 Node 信息写入 Pod 的
spec.nodeName,完成绑定。 - 异步绑定:绑定操作是异步的,调度器不会等待绑定结果即开始处理下一个 Pod。
2.2 调度框架(Scheduling Framework)
Kubernetes 从 v1.19 开始引入调度框架,将调度周期和绑定周期拆分为多个可扩展的扩展点(Extension Points)。调度框架允许用户通过实现插件(Plugin)来定制调度行为,而无需修改核心代码。
调度框架的核心扩展点如下表所示:
| 扩展点 | 阶段 | 说明 | 常见插件示例 |
|---|---|---|---|
| QueueSort | 调度队列 | 对队列中的 Pod 进行排序 | PrioritySort |
| PreFilter | 调度周期 | 预处理 Pod 信息,检查是否满足调度前提 | NodeResourcesFit |
| Filter | 调度周期 | 过滤不满足条件的 Node | NodeName, PodTopologySpread |
| PostFilter | 调度周期 | 当所有 Node 都被过滤时,执行抢占或失败处理 | DefaultPreemption |
| PreScore | 调度周期 | 评分前的预处理 | NodeResourcesBalancedAllocation |
| Score | 调度周期 | 对通过过滤的 Node 进行评分 | NodeResourcesLeastAllocated, ImageLocality |
| NormalizeScore | 调度周期 | 对评分结果进行归一化 | NodeResourcesMostAllocated |
| Reserve | 绑定周期 | 预留资源,防止并发冲突 | VolumeBinding |
| Permit | 绑定周期 | 允许或拒绝绑定,支持等待/超时 | NodeAffinity |
| PreBind | 绑定周期 | 绑定前的准备工作 | NodeVolumeLimits |
| Bind | 绑定周期 | 执行绑定操作 | DefaultBinder |
| PostBind | 绑定周期 | 绑定后的清理或通知 | NodeResourcesFit |
下图展示了调度框架中扩展点与调度周期的关系:
2.3 调度队列
调度队列负责管理待调度的 Pod,是调度器的入口。Kubernetes 使用优先级队列(Priority Queue)实现,支持三种子队列:
- activeQ:存放等待调度的 Pod,按优先级排序。
- backoffQ:存放调度失败的 Pod,经过退避时间后重新入队。
- unschedulableQ:存放因资源不足等原因无法调度的 Pod,当集群资源变化时重新评估。
2.4 调度周期详解
调度周期是调度器的核心执行单元,分为过滤阶段和评分阶段。过滤阶段确保 Node 满足 Pod 的硬性约束,评分阶段则从满足条件的 Node 中选出最优解。
2.4.1 过滤阶段(Filtering)
过滤阶段依次执行多个 Filter 插件,任何一个插件返回失败,该 Node 即被排除。常见的过滤条件包括:
- 节点资源是否满足 Pod 的 Request
- 节点是否满足 NodeSelector 和 NodeAffinity
- Pod 是否与节点上的 Pod 存在端口冲突
- Pod 是否满足 PodTopologySpread 约束
2.4.2 评分阶段(Scoring)
评分阶段对通过过滤的 Node 进行打分,分数范围 0-100。调度器最终选择总分最高的 Node。如果多个 Node 分数相同,则随机选择。常见的评分策略包括:
- LeastRequestedPriority:优先选择资源利用率低的节点,实现负载均衡。
- MostRequestedPriority:优先选择资源利用率高的节点,实现资源集中。
- BalancedResourceAllocation:优先选择 CPU 和内存使用率均衡的节点。
下图展示了调度周期中过滤与评分的详细流程:
2.5 绑定周期
绑定周期在调度周期之后执行,负责将 Pod 与选中的 Node 进行绑定。绑定周期包含 Reserve、Permit、PreBind、Bind、PostBind 五个扩展点。其中:
- Reserve:在缓存中预留资源,防止并发调度冲突。
- Permit:允许或拒绝绑定,支持等待(例如等待 CSI 卷挂载完成)。
- Bind:实际执行绑定操作,默认通过 API Server 更新 Pod 的
spec.nodeName。
2.6 调度器配置与扩展
Kube-scheduler 支持通过 KubeSchedulerConfiguration 配置文件进行灵活配置,包括:
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
filter:
enabled:
- name: NodeResourcesFit
- name: NodeName
disabled:
- name: "*"
score:
enabled:
- name: NodeResourcesLeastAllocated
weight: 2
- name: ImageLocality
weight: 1
pluginConfig:
- name: NodeResourcesLeastAllocated
args:
resources:
- name: cpu
weight: 1
- name: memory
weight: 1
通过配置多个 Profile,可以实现多调度器共存,每个 Profile 使用不同的插件组合,适用于不同的工作负载类型。