1. Kubernetes 调度器基础:调度器架构、调度流程、调度策略概述
Kubernetes 调度器(kube-scheduler)是控制平面中负责将 Pod 分配到合适 Node 的核心组件。它不负责运行 Pod,而是通过一系列算法和策略,为每个待调度的 Pod 选择最匹配的节点。理解调度器的架构、流程和策略,是掌握亲和性调度优化的前提。
1.1 调度器架构
kube-scheduler 以插件化架构设计,核心组件包括调度队列、调度框架(Scheduling Framework)和缓存。调度框架定义了扩展点,允许用户通过调度插件(Plugin)注入自定义逻辑。
架构要点: 调度器通过 Informer 机制 监听 API Server 中的 Pod 和 Node 变化,将未调度的 Pod 加入调度队列,然后循环执行调度周期和绑定周期。
1.2 调度流程
调度流程分为两个主要阶段:调度周期(Scheduling Cycle)和 绑定周期(Binding Cycle)。调度周期为 Pod 选择一个节点,绑定周期将选择结果持久化到 API Server。
| 阶段 | 步骤 | 说明 |
|---|---|---|
| 调度周期 | 1. 过滤 (Filter) | 排除不满足 Pod 资源请求、节点污点、端口冲突等硬性条件的节点 |
| 2. 打分 (Score) | 对通过过滤的节点进行优先级评分,选择最优节点 | |
| 3. 预留 (Reserve) | 在缓存中预留资源,防止并发调度冲突 | |
| 绑定周期 | 4. 允许 (Permit) | 等待所有 Permit 插件批准,支持延迟绑定 |
| 5. 绑定 (Bind) | 将 Pod 与 Node 的绑定关系写入 etcd |
关键概念: 调度周期是 串行 的,同一时间只为一个 Pod 执行调度;绑定周期是 并行 的,多个 Pod 可以同时进行绑定操作。这种设计提高了整体吞吐量。
1.3 调度策略概述
调度策略通过调度框架的扩展点实现,主要分为 过滤策略(Predicates)和 打分策略(Priorities)。Kubernetes 内置了大量策略,用户也可以通过调度插件自定义。
1.3.1 过滤策略(硬约束)
过滤策略决定 Pod 可以调度到哪些节点。如果节点不满足任何一条过滤条件,则被直接排除。
- NodeResourcesFit:检查节点剩余 CPU、内存是否满足 Pod 请求。
- NodeName:检查 Pod 是否指定了
spec.nodeName。 - PodTopologySpread:检查拓扑分布约束是否满足。
- NodeUnschedulable:排除被标记为
unschedulable的节点。 - TaintToleration:检查 Pod 是否能容忍节点的污点。
- NodeAffinity:检查节点亲和性规则(
requiredDuringScheduling)。
1.3.2 打分策略(软偏好)
打分策略对通过过滤的节点进行评分,分数越高优先级越高。调度器最终选择分数最高的节点。
| 策略名称 | 权重 | 评分依据 |
|---|---|---|
| NodeResourcesBalancedAllocation | 1 | CPU 和内存使用率越均衡,分数越高 |
| NodeResourcesLeastAllocated | 1 | 资源剩余越多,分数越高(分散调度) |
| NodeResourcesMostAllocated | 1 | 资源使用率越高,分数越高(集中调度) |
| ImageLocality | 1 | 节点上已有 Pod 所需镜像,分数越高 |
| InterPodAffinity | 2 | 满足 Pod 间亲和/反亲和规则加分 |
| NodeAffinity | 2 | 满足节点亲和性软规则(preferredDuringScheduling)加分 |
1.4 调度器扩展机制
Kubernetes 调度框架提供了多个扩展点,允许开发者编写自定义调度插件。常见的扩展点包括:
- QueueSort:定义调度队列中 Pod 的排序方式。
- PreFilter / Filter / PostFilter:过滤阶段的扩展点。
- PreScore / Score / NormalizeScore:打分阶段的扩展点。
- Reserve / Permit / PreBind / Bind / PostBind:绑定阶段的扩展点。
注意: 自定义调度插件需要编译到 kube-scheduler 二进制中,或者通过 调度器配置(Scheduler Configuration)以 扩展资源 方式加载。在生产环境中修改调度器行为时,建议先使用 调度器策略(Scheduler Policy)或 调度器配置 进行灰度验证。
1.5 调度器配置示例
以下是一个使用调度器配置启用自定义打分权重的示例:
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
score:
enabled:
- name: NodeResourcesLeastAllocated
weight: 2
- name: ImageLocality
weight: 1
disabled:
- name: NodeResourcesMostAllocated
pluginConfig:
- name: NodeResourcesLeastAllocated
args:
resources:
- name: cpu
weight: 1
- name: memory
weight: 2
通过调整权重和启用/禁用插件,可以灵活控制调度行为,为后续的亲和性调度优化打下基础。