3. K8s 调度基础:调度器工作原理、节点选择、Pod 调度流程
在 GitOps 流水线中,每一次代码合并都可能触发新的 Pod 部署。理解 Kubernetes 调度器(kube-scheduler)的工作原理,是优化同步窗口、控制 Pod 分布、避免资源争抢的前提。本章从调度器架构、节点选择机制、Pod 调度全流程三个维度展开,为后续“调度优化与同步窗口集成”打下基础。
3.1 调度器工作原理
Kubernetes 调度器是一个独立的控制平面组件,负责将未调度的 Pod(spec.nodeName 为空)绑定到最合适的 Node 上。其核心是一个“过滤 → 打分 → 绑定”的三阶段循环。
关键概念:调度器不直接启动 Pod,而是通过 API Server 更新 Pod 的
nodeName 字段,由目标节点的 kubelet 负责实际创建。
3.1.1 调度器架构组件
| 组件 | 职责 | 可扩展性 |
|---|---|---|
| 调度队列 | 管理待调度 Pod,支持优先级排序、重试、回退 | 可自定义队列排序策略 |
| 过滤阶段 | 从所有 Node 中选出满足 Pod 硬性约束的节点 | 通过 Predicate 扩展点注入自定义过滤逻辑 |
| 打分阶段 | 对过滤后的 Node 进行优先级评分,选出最优节点 | 通过 Priority 扩展点注入自定义打分算法 |
| 绑定阶段 | 将 Pod 与选定 Node 的绑定关系写入 API Server | 支持异步绑定、多调度器协调 |
3.1.2 调度器工作流程(内联 SVG)
3.2 节点选择机制
节点选择是调度器在过滤阶段的核心工作。Kubernetes 提供了多种机制让用户控制 Pod 可以调度到哪些节点上,这些机制在 GitOps 流水线中常用于隔离环境、绑定硬件、实现合规性。
3.2.1 节点选择机制对比
| 机制 | 匹配方式 | 典型场景 | 调度阶段 |
|---|---|---|---|
| nodeSelector | 精确匹配 Label 键值对 | 简单环境隔离(如 env=prod) | 过滤 |
| 节点亲和性 | 支持 In/NotIn/Exists/Gt/Lt 等操作符 | 复杂拓扑约束、硬件类型选择 | 过滤 + 打分 |
| Pod 亲和性/反亲和性 | 基于已有 Pod 的 Label 分布 | 服务就近部署、故障域隔离 | 过滤 + 打分 |
| 污点与容忍 | Node 标记污点,Pod 声明容忍 | 专用节点(GPU)、节点维护 | 过滤 |
GitOps 实践提示:在 Helm Chart 或 Kustomize 中,将环境标签(如
env: staging)作为 nodeSelector 的默认值,可以防止流水线误将测试 Pod 调度到生产节点。
3.2.2 节点选择决策树(内联 SVG)
3.3 Pod 调度流程
一个 Pod 从创建到运行在节点上,经历了完整的调度生命周期。理解这个流程,有助于在 GitOps 流水线中定位调度延迟、资源不足、调度失败等问题。
3.3.1 完整调度流程步骤
- Pod 创建:用户或控制器(Deployment/Job)通过 API Server 创建 Pod 对象,
spec.nodeName为空。 - 调度器监听:kube-scheduler 通过 Watch 机制发现未调度的 Pod,将其加入调度队列(activeQ)。
- 过滤阶段:调度器遍历所有 Node,执行 Predicate 函数(节点选择器、污点容忍、资源充足、端口冲突等),生成候选节点列表。
- 打分阶段:对候选节点执行 Priority 函数(资源均衡、亲和性加分、自定义策略),每个节点获得 0-100 分。
- 选定节点:选择最高分节点;若多个节点同分,随机选择一个。
- 绑定:调度器通过 API Server 创建 Binding 对象,将 Pod 的
nodeName设置为选定节点。 - kubelet 响应:目标节点的 kubelet 监听到 Pod 更新,调用容器运行时(containerd/CRI-O)启动容器。
- 状态上报:kubelet 将 Pod 状态更新为
Running,调度流程结束。
常见调度失败原因:
- 资源不足(CPU/Memory 请求超过节点剩余容量)
- 节点选择器/亲和性无匹配节点
- 节点存在未容忍的污点(如
node.kubernetes.io/unschedulable) - 端口冲突(Pod 使用
hostPort且端口已被占用) - 存储卷挂载冲突(PVC 被绑定到特定节点拓扑)
3.3.2 调度流程时序图(内联 SVG)
3.4 调度器扩展点与 GitOps 集成
Kubernetes 调度器支持通过 Scheduling Framework 注入自定义扩展点。在 GitOps 流水线中,可以利用这些扩展点实现调度策略的声明式管理。
3.4.1 主要扩展点
| 扩展点 | 阶段 | 典型用途 |
|---|---|---|
| PreFilter | 过滤前 | 预处理 Pod 信息,提前排除无效节点 |
| Filter | 过滤 | 自定义节点过滤逻辑(如 GPU 型号匹配) |
| PreScore | 打分前 | 计算全局评分上下文 |
| Score | 打分 | 自定义权重评分(如网络延迟、成本) |
| Reserve | 绑定前 | 预留资源,防止并发冲突 |
| Permit | 绑定前 | 批准或延迟绑定(实现调度门控) |
GitOps 集成建议:将自定义调度器扩展(如
scheduler-config.yaml)作为 GitOps 仓库中的版本化资源,通过 Argo CD 或 Flux 同步到集群。当需要调整调度策略(如增加成本权重、修改节点过滤规则)时,只需修改 Git 仓库中的配置,流水线自动完成更新。
3.5 本章小结
- 调度器核心是 过滤 → 打分 → 绑定 三阶段循环,所有扩展点都围绕这三个阶段展开。
- 节点选择机制包括 nodeSelector、节点亲和性、Pod 亲和性/反亲和性、污点与容忍,在 GitOps 中应声明式定义。
- Pod 调度流程涉及 API Server、调度器、kubelet、容器运行时 四个角色,理解时序有助于排查调度延迟。
- 调度器扩展点(Scheduling Framework)允许自定义调度逻辑,适合通过 GitOps 进行版本化管理。