2. K8s 调度基础:调度器架构、调度流程、节点选择与绑定机制

Kubernetes 调度器(kube-scheduler)是控制平面中负责将 Pod 分配到合适 Node 的核心组件。理解其架构、流程与绑定机制,是后续进行调度策略调优与配置漂移审计的基础。本章从调度器内部架构出发,逐步拆解调度全生命周期。

2.1 调度器架构:组件与职责

kube-scheduler 采用插件化架构,通过一系列可配置的调度队列、调度框架(Scheduling Framework)与绑定回路完成 Pod 的调度决策。其核心组件如下:

组件 职责 关键特性
调度队列 管理待调度的 Pod,支持优先级排序与重试 ActiveQ / BackoffQ / UnschedulableQ
调度框架 定义扩展点(Extension Points),允许插件注入过滤、评分、绑定等逻辑 PreFilter / Filter / PostFilter / Score / Reserve / Permit / PreBind / Bind / PostBind
调度器缓存 维护集群 Node 与 Pod 的实时快照,减少 API Server 请求 增量更新、过期清理
绑定回路 将选定 Node 与 Pod 的绑定关系写入 API Server 异步绑定、幂等性保证
架构要点: 调度框架的插件化设计使得调度策略可动态组合,Prometheus 可通过监控每个扩展点的执行耗时与错误率,精准定位调度性能瓶颈。
K8s 调度器内部架构图 kube-scheduler 内部架构 调度队列 ActiveQ BackoffQ UnschedulableQ 调度框架 PreFilter / Filter PostFilter / Score Reserve / Permit PreBind / Bind PostBind 调度器缓存 Node 快照 Pod 快照 增量更新 绑定回路 异步写入 API Server 调度框架扩展点 支持自定义插件注入

2.2 调度流程:从入队到绑定

一个 Pod 从创建到完成调度,经历以下核心阶段:

  1. 入队(Queue):Pod 进入 ActiveQ,按优先级排序;若调度失败则进入 BackoffQ 或 UnschedulableQ。
  2. PreFilter:执行 Pod 级别的预处理检查(如 Pod 拓扑分布约束、卷冲突检测)。
  3. Filter:遍历所有 Node,执行过滤插件(如节点资源不足、端口冲突、污点容忍)。
  4. PostFilter:若无可调度 Node,执行抢占逻辑或标记为不可调度。
  5. Score:对通过过滤的 Node 进行评分,选择最高分 Node。
  6. Reserve:在缓存中预留资源,防止并发调度冲突。
  7. Permit:等待外部准入许可(如动态资源调度)。
  8. PreBind / Bind:执行绑定前预处理(如 CSI 卷挂载),然后写入绑定关系。
  9. PostBind:绑定完成后的清理与通知。
审计关注点: 每个扩展点均可通过 Prometheus Histogram 指标(如 scheduler_framework_extension_point_duration_seconds)监控耗时分布。若 Filter 阶段耗时异常,通常意味着节点资源检查插件存在性能瓶颈。
Pod 调度流程时序图 Pod 调度流程(从入队到绑定) 1. 入队 2. PreFilter 3. Filter 4. PostFilter 5. Score 6. Reserve 7. Permit 8. Bind 各阶段关键动作 • 入队:按优先级排序,支持重试与回退 • PreFilter:Pod 级预处理(拓扑约束、卷冲突) • Filter:节点级过滤(资源、端口、污点) • PostFilter:抢占或标记不可调度 • Score:多维度评分,选择最优节点 • Reserve:缓存预留,防止并发冲突 • Permit:等待外部准入许可 • Bind:写入绑定关系至 API Server • PostBind:清理与通知(图中未展开)

2.3 节点选择与绑定机制

节点选择是调度流程的核心输出,绑定机制则确保选择结果持久化。两者协同工作,形成调度决策的闭环。

2.3.1 节点选择:过滤 + 评分

节点选择分为两个阶段:

  • 过滤阶段(Filter):硬性约束检查,不满足条件的 Node 被直接排除。常见过滤插件包括:
    • NodeResourcesFit:检查 CPU、内存是否满足 Pod 请求。
    • NodePorts:检查端口是否冲突。
    • NodeAffinity:检查节点亲和性规则。
    • TaintToleration:检查污点容忍。
  • 评分阶段(Score):对通过过滤的 Node 进行打分,选择最高分节点。常见评分插件包括:
    • NodeResourcesBalancedAllocation:优先选择资源分配均衡的节点。
    • ImageLocality:优先选择已缓存所需镜像的节点。
    • InterPodAffinity:优先满足 Pod 间亲和/反亲和规则。
漂移风险: 若集群中多个调度器实例使用不同的评分权重配置,同一 Pod 可能被分配到不同 Node,导致调度结果不一致。Prometheus 可通过 scheduler_pod_scheduling_attempts 和 scheduler_pod_scheduling_duration_seconds 监控调度一致性。

2.3.2 绑定机制:从选择到持久化

绑定机制确保调度决策被可靠写入 API Server,并触发 kubelet 执行 Pod 启动。其核心流程如下:

步骤 操作 失败处理
PreBind 执行绑定前预处理(如 CSI 卷挂载、网络配置) 回滚 Reserve 状态,重新入队
Bind 通过 API Server 创建 Pod 与 Node 的绑定关系(Binding 对象) 重试或回滚
PostBind 清理临时资源,通知其他组件 仅记录日志,不阻塞

绑定操作的伪代码如下:

// 绑定流程简化示例
func (s *Scheduler) bind(ctx context.Context, pod *v1.Pod, node string) error {
    // 1. PreBind 扩展点
    if err := s.runPreBindPlugins(ctx, pod, node); err != nil {
        s.runReservePluginsUnreserve(ctx, pod, node)
        return err
    }
    // 2. 执行绑定
    binding := &v1.Binding{
        ObjectMeta: metav1.ObjectMeta{Name: pod.Name, Namespace: pod.Namespace},
        Target:     v1.ObjectReference{Kind: "Node", Name: node},
    }
    if err := s.client.CoreV1().Pods(pod.Namespace).Bind(ctx, binding, metav1.CreateOptions{}); err != nil {
        s.runPreBindPluginsUnreserve(ctx, pod, node)
        return err
    }
    // 3. PostBind 扩展点
    s.runPostBindPlugins(ctx, pod, node)
    return nil
}
审计指标: 绑定阶段耗时可通过 scheduler_binding_duration_seconds 监控。若绑定耗时突增,通常与 API Server 负载或 PreBind 插件(如 CSI 卷挂载)延迟相关。

2.4 调度器配置与可观测性

调度器配置通过 KubeSchedulerConfiguration 对象管理,支持动态调整插件启用/禁用、评分权重、队列策略等。Prometheus 提供的调度相关指标包括:

指标名称 类型 说明
scheduler_queue_incoming_pods_total Counter 入队 Pod 总数
scheduler_pod_scheduling_attempts Histogram Pod 调度尝试次数分布
scheduler_framework_extension_point_duration_seconds Histogram 各扩展点耗时分布
scheduler_binding_duration_seconds Histogram 绑定阶段耗时分布
scheduler_volume_scheduling_duration_seconds Histogram 卷调度耗时分布
调优建议: 通过 Prometheus 监控 scheduler_framework_extension_point_duration_seconds 的 P99 值,若 Filter 阶段超过 100ms,建议检查节点资源检查插件是否过多或节点数量过大。可考虑启用 NodeResourcesFit 的 LeastAllocated 策略以平衡负载。