Kubernetes拓扑分布约束与抢占事件诊断 - 第1节
1. 课程导论:K8s 调度器整体架构与调度框架概述
Kubernetes 调度器(kube-scheduler)是控制平面中负责将 Pod 绑定到合适 Node 的核心组件。其决策质量直接影响集群的资源利用率、应用性能与运维稳定性。本章首先建立调度器的整体架构认知,再聚焦于拓扑分布约束与抢占事件这两个关键调度策略。
1.1 调度器整体架构
kube-scheduler 采用“调度队列 + 调度框架 + 绑定回写”的三层架构。调度框架(Scheduling Framework)自 v1.19 起成为扩展点标准,允许用户通过插件机制定制调度行为。
架构要点:调度器不直接与 Node 通信,而是通过 API Server 监听 Pod 与 Node 的变更事件,将调度决策写入 Pod 的
spec.nodeName 字段。
1.2 调度框架核心扩展点
调度框架将调度周期划分为多个扩展点(Extension Points),每个扩展点可插入一个或多个插件。下表列出与拓扑分布约束和抢占事件最相关的扩展点:
| 扩展点 | 执行阶段 | 与拓扑/抢占的关系 |
|---|---|---|
| PreFilter | 过滤前预处理 | 校验 Pod 的拓扑分布约束声明,预计算所需拓扑域 |
| Filter | 节点过滤 | 检查每个 Node 是否满足 Pod 的拓扑分布约束(topologySpreadConstraints) |
| PostFilter | 过滤后处理 | 当无可用 Node 时,触发抢占逻辑(Preemption) |
| Score | 节点打分 | 对满足约束的 Node 按拓扑分布均匀度打分,优先选择分布更均衡的 Node |
| Reserve | 资源预留 | 抢占成功后,预留被抢占 Pod 的资源,防止其他调度器占用 |
实践提示:拓扑分布约束在 Filter 阶段做硬性检查,在 Score 阶段做软性优化。如果集群中大量 Pod 因拓扑约束无法调度,应优先检查 Filter 阶段的日志,而非 Score 阶段的打分结果。
1.3 拓扑分布约束在调度中的角色
拓扑分布约束(Topology Spread Constraints)是 v1.19 进入 Beta、v1.24 进入 GA 的调度特性。它允许用户定义 Pod 在集群拓扑域(如 zone、region、hostname)上的分布规则,避免 Pod 集中部署在少数节点或可用区。
1.3.1 核心参数
- topologyKey:拓扑域键,如
topology.kubernetes.io/zone、kubernetes.io/hostname。 - maxSkew:最大偏斜度,表示任意两个拓扑域之间 Pod 数量的最大差值。
- whenUnsatisfiable:不满足约束时的行为,可选
DoNotSchedule(硬约束)或ScheduleAnyway(软约束)。 - labelSelector:用于匹配 Pod 的标签选择器,决定哪些 Pod 参与分布计数。
调度角色:拓扑分布约束在 Filter 阶段作为硬性准入条件,在 Score 阶段作为软性优化目标。硬约束保证 Pod 不会过度集中,软约束在满足硬约束的前提下尽量均匀分布。
1.4 抢占事件在调度中的角色
抢占(Preemption)是调度器在 PostFilter 扩展点触发的应急机制。当高优先级 Pod 无法找到满足所有约束的 Node 时,调度器会尝试驱逐低优先级 Pod 来释放资源。
1.4.1 抢占触发条件
- Pod 经过 Filter 阶段后,所有 Node 均不满足调度条件。
- Pod 的
priorityClassName对应的优先级高于被抢占 Pod。 - 被抢占 Pod 的
preemptionPolicy为PreemptLowerPriority(默认值)。
1.4.2 抢占流程
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 候选节点筛选 | 找出所有 Node,计算驱逐低优先级 Pod 后能否满足高优先级 Pod 的资源需求 |
| 2 | 受害者选择 | 在每个候选 Node 上选择优先级最低、且与高优先级 Pod 不冲突的 Pod 作为受害者 |
| 3 | 抢占裁决 | 选择受害者数量最少、总优先级最低的 Node 作为最终抢占目标 |
| 4 | 资源预留 | 在 Reserve 扩展点预留资源,防止其他调度器占用 |
| 5 | 驱逐与绑定 | 通过 API Server 删除受害者 Pod,将高优先级 Pod 绑定到目标 Node |
运维警告:抢占事件会触发 Pod 驱逐,导致服务中断。生产环境中应严格控制优先级配置,避免频繁抢占。建议结合
priorityClass 的 globalDefault 和 preemptionPolicy: Never 来限制非关键 Pod 的抢占行为。
1.4.3 拓扑分布约束与抢占的交互
当拓扑分布约束与抢占同时生效时,调度器需要额外考虑:
- 抢占后,目标 Node 的拓扑域内 Pod 数量变化可能违反其他 Pod 的
maxSkew约束。 - 调度器在 PostFilter 阶段会重新计算拓扑分布,确保抢占后的分布仍满足硬约束。
- 如果抢占导致拓扑分布超限,调度器会放弃该 Node,继续评估其他候选节点。
调优关键:拓扑分布约束与抢占的交互是调度调优的高频难点。建议在测试环境中使用
kube-scheduler 的 --v=5 日志级别,观察 PostFilter 阶段的决策日志,确认抢占是否因拓扑约束被拒绝。