2. Kubernetes 调度基础:调度器工作原理、调度队列、调度周期、Predicates 与 Priorities 算法
2.1 调度器核心工作原理
Kubernetes 调度器(kube-scheduler)是控制平面的核心组件之一,负责将待调度的 Pod 绑定到最合适的 Node 上。其本质是一个基于 事件驱动 和 周期循环 的决策引擎,通过监听 API Server 中未调度的 Pod(spec.nodeName 为空),执行一套可插拔的调度算法,最终将 Pod 与 Node 的绑定关系写回 etcd。
2.2 调度队列(Scheduling Queue)
调度队列是调度器的“待办事项列表”,负责管理所有等待调度的 Pod。Kubernetes 使用 优先级队列 实现,Pod 在队列中的顺序由其 优先级(Priority) 和 入队时间 共同决定。
| 队列类型 | 作用 | 数据来源 |
|---|---|---|
| activeQ(活跃队列) | 存放所有等待调度的 Pod,按优先级排序 | API Server 中 spec.nodeName="" 的 Pod |
| backoffQ(回退队列) | 存放调度失败、需要等待一段时间后重试的 Pod | 调度周期或绑定周期失败的 Pod |
| unschedulableQ(不可调度队列) | 存放因资源不足、节点不可用等原因暂时无法调度的 Pod | Predicates 阶段失败的 Pod |
unschedulableQ 中的 Pod 可能因频繁的 Node 更新事件被反复唤醒,导致调度器 CPU 飙升。可通过调整 --permit-every-one-second 和 --unschedulableQ-burst 参数控制回填速率。
2.3 调度周期(Scheduling Cycle)
调度周期是调度器为单个 Pod 选择 Node 的完整过程,分为两个阶段:过滤(Filtering) 和 打分(Scoring)。调度周期是串行的,同一时间只有一个 Pod 在执行调度周期。
2.4 Predicates 算法(过滤阶段)
Predicates 算法是一组 硬约束 检查,用于过滤掉不满足 Pod 运行条件的 Node。只有通过所有 Predicates 检查的 Node 才会进入打分阶段。常见的 Predicates 算法包括:
- PodFitsResources: 检查 Node 剩余 CPU、内存是否满足 Pod 的 requests 需求。
- PodFitsHostPorts: 检查 Node 上是否已有 Pod 占用了相同的 hostPort。
- PodSelectorMatches: 检查 Node 的标签是否匹配 Pod 的
nodeSelector。 - CheckNodeCondition: 检查 Node 是否处于 Ready、DiskPressure 等健康状态。
- CheckVolumeBinding: 检查 Pod 使用的 PVC 是否能在该 Node 上挂载。
- NoDiskConflict: 检查 Pod 使用的 Volume 是否与 Node 上已有 Pod 冲突。
- MatchInterPodAffinity: 检查 Pod 间的亲和性和反亲和性规则。
PodFitsResources 和 MatchInterPodAffinity 是最耗时的 Predicates 算法。如果集群中 Node 数量超过 5000,建议启用 NodeResourcesFit 的 LeastAllocated 或 MostAllocated 策略,并合理设置 --hard-pod-affinity-weight 参数。
2.5 Priorities 算法(打分阶段)
Priorities 算法对通过过滤的 Node 进行 软评分,每个算法返回一个 0-100 的分数,最终加权求和得到每个 Node 的总分。调度器选择总分最高的 Node 作为目标节点。常见的 Priorities 算法包括:
| 算法名称 | 评分逻辑 | 权重(默认) | 适用场景 |
|---|---|---|---|
| LeastRequestedPriority | 优先选择资源使用率低的 Node(CPU + 内存) | 1 | 负载均衡、资源碎片最小化 |
| MostRequestedPriority | 优先选择资源使用率高的 Node | 1 | 资源密集型应用、减少空闲 Node |
| BalancedResourceAllocation | 优先选择 CPU 和内存使用率最均衡的 Node | 1 | 混合负载、避免单资源瓶颈 |
| NodeAffinityPriority | 根据 preferredDuringSchedulingIgnoredDuringExecution 规则打分 |
2 | 节点亲和性调度 |
| InterPodAffinityPriority | 根据 Pod 间的亲和性/反亲和性规则打分 | 2 | Pod 亲和性调度 |
| ImageLocalityPriority | 优先选择已缓存 Pod 所需镜像的 Node | 1 | 镜像拉取加速 |
2.6 调度周期与绑定周期的协作
调度器将 Pod 的调度过程拆分为 调度周期 和 绑定周期,两者通过 异步通道 解耦。调度周期是串行的,绑定周期可以并发执行。这种设计使得调度器在等待绑定结果时,可以继续处理下一个 Pod 的调度周期,提升整体吞吐量。
- 调度延迟(Scheduling Latency): Pod 从创建到被调度器选中 Node 的时间,通常应 < 100ms。
- 绑定延迟(Binding Latency): 调度器将绑定关系写入 API Server 的时间,受 etcd 写入性能影响。
- 调度吞吐量(Scheduling Throughput): 每秒能调度的 Pod 数量,默认约 10-50 Pod/s,可通过
--kube-api-qps和--kube-api-burst调整。
2.7 调度器扩展机制
Kubernetes 调度器支持 调度框架(Scheduling Framework),允许用户通过 调度插件(Scheduler Plugin) 扩展调度逻辑。调度框架定义了多个扩展点:
- QueueSort: 自定义调度队列的排序逻辑。
- PreFilter / Filter: 对应 Predicates 阶段,可添加自定义过滤逻辑。
- PreScore / Score / NormalizeScore: 对应 Priorities 阶段,可添加自定义打分逻辑。
- Reserve / Permit / PreBind / Bind: 绑定周期的扩展点,用于预留资源、权限检查、自定义绑定逻辑。
values.yaml 配置调度器的 plugins 和 pluginConfig,实现调度策略的声明式管理。例如,使用 NodeResourcesFit 插件的 scoringStrategy 字段切换 LeastAllocated 和 MostAllocated 策略。