1. Kubernetes 调度器概述:调度器在 K8s 架构中的位置、核心职责、调度流程简介
1.1 调度器在 Kubernetes 架构中的位置
Kubernetes 是一个以 声明式 API 驱动的容器编排平台,其控制平面由多个独立组件协同工作。调度器(kube-scheduler)是控制平面的核心组件之一,位于 API Server 与 Node 之间,负责将待调度的 Pod 绑定到最合适的节点上。
下图展示了调度器在 Kubernetes 控制平面中的位置及其与周边组件的交互关系:
关键认知:调度器不直接与 kubelet 或容器运行时通信。它只负责做出调度决策,并将决策结果(Pod 与 Node 的绑定)写入 API Server。kubelet 通过 Watch 机制感知到绑定关系后,再在本地启动容器。
1.2 调度器的核心职责
调度器的本质是一个 决策引擎,其核心职责可以归纳为以下四点:
| 职责 | 说明 | 关键动作 |
|---|---|---|
| 1. 监听未调度 Pod | 通过 API Server 的 Watch 接口,持续监听 spec.nodeName 为空的 Pod |
将 Pod 加入调度队列 |
| 2. 过滤可行节点 | 根据 Pod 的资源请求、节点选择器、亲和性、污点容忍等约束,筛选出满足条件的节点集合 | Predicates(预选)阶段 |
| 3. 评分与排序 | 对过滤后的节点进行优先级打分,选出最优节点 | Priorities(优选)阶段 |
| 4. 绑定 Pod 到节点 | 将 Pod 与选定节点的绑定关系写入 API Server 的 etcd 中 | Bind(绑定)阶段 |
调度粒度:调度器以 Pod 为最小调度单元,而非容器或容器组。一个 Pod 内的所有容器始终被调度到同一节点上。
1.3 调度流程简介
Kubernetes 调度器的调度流程是一个 串行 + 并行 的流水线模型。从 Pod 进入调度队列到最终绑定,主要经历以下三个阶段:
- 调度队列(Scheduling Queue):未调度的 Pod 按优先级和创建时间进入队列,等待调度。
- 过滤阶段(Filtering / Predicates):并行执行多个预选策略,快速剔除不满足条件的节点。常见策略包括:
PodFitsResources(资源是否充足)、MatchNodeSelector(节点选择器匹配)、PodToleratesNodeTaints(污点容忍)等。 - 评分阶段(Scoring / Priorities):对通过过滤的节点进行加权评分,选出得分最高的节点。常见评分策略包括:
LeastRequestedPriority(资源利用率最低优先)、BalancedResourceAllocation(资源均衡分配)、NodeAffinityPriority(节点亲和性)等。
以下流程图直观展示了调度器从监听 Pod 到完成绑定的完整流水线:
1.4 调度器的工作模式
Kubernetes 调度器支持两种工作模式,以满足不同场景的需求:
| 模式 | 描述 | 适用场景 |
|---|---|---|
| 默认调度器 | 使用内置的调度框架(Scheduling Framework),包含一组默认的过滤和评分插件 | 大多数通用工作负载,无需自定义调度逻辑 |
| 自定义调度器 | 用户可编写独立的调度器程序,或通过调度框架的扩展点(Extender / Plugin)注入自定义逻辑 | 特殊硬件调度、GPU 拓扑感知、大数据作业等复杂场景 |
注意:一个集群中可以同时运行多个调度器。Pod 可以通过
spec.schedulerName 字段指定使用哪个调度器。如果未指定,默认使用 default-scheduler。
1.5 调度器与污点容忍的关系
污点(Taint)与容忍(Toleration)是调度器在 过滤阶段 使用的重要机制之一。节点可以设置污点来排斥某些 Pod,而 Pod 可以通过声明容忍来允许被调度到带有特定污点的节点上。
调度器在处理污点容忍时的逻辑如下:
- 如果节点上存在 NoSchedule 污点,且 Pod 没有对应的容忍,则该节点会被过滤掉。
- 如果节点上存在 PreferNoSchedule 污点,调度器会尽量避免将 Pod 调度到该节点,但不强制。
- 如果节点上存在 NoExecute 污点,不仅会影响调度,还会驱逐节点上已有的未容忍该污点的 Pod。