2. Kubernetes 调度基础:调度器工作原理、调度流程、节点选择与亲和性
2.1 调度器核心职责与架构
Kubernetes 调度器(kube-scheduler)是控制平面的核心组件之一,负责将待调度的 Pod 绑定到最合适的 Node 上。其本质是一个资源匹配与约束满足引擎,在集群资源碎片化、节点故障、拓扑约束等复杂场景下做出最优决策。
| 组件 | 职责 | 关键特性 |
|---|---|---|
| kube-scheduler | 监听未调度的 Pod,执行调度算法,写入绑定记录 | 可插拔调度框架,支持多调度器共存 |
| 调度队列 | 按优先级、抢占、重试策略管理待调度 Pod | PriorityQueue + 背压机制 |
| 调度框架 | 定义扩展点(Filter/Score/Normalize/Reserve/Permit) | v1.19+ 稳定,支持自定义插件 |
| Cache | 缓存集群 Node 与 Pod 快照,减少 API Server 压力 | 增量更新,一致性校验 |
调度器可观测性要点: 生产环境中建议开启
--v=4 日志级别,并通过 /metrics 端点监控 scheduler_pod_scheduling_duration_seconds 和 scheduler_queue_incoming_pods_total 指标,快速定位调度瓶颈。
2.2 调度流程:从 Pod 创建到绑定
调度流程分为两个阶段:过滤(Filtering) 和 打分(Scoring)。过滤阶段选出所有满足 Pod 资源请求、亲和性、污点容忍等硬约束的 Node;打分阶段对候选 Node 按优先级排序,最终选择最优节点。
调度流程关键步骤(按顺序):
- PreFilter: 检查 Pod 的调度周期、抢占策略,执行 Pod 级别的预过滤。
- Filter: 并行执行所有过滤插件,剔除不满足硬约束的 Node。
- PostFilter: 若无可行 Node,触发抢占逻辑或标记调度失败。
- PreScore: 运行评分前的预处理,如计算 Pod 间亲和性缓存。
- Score: 对每个候选 Node 打分(0-100),支持加权组合。
- NormalizeScore: 对分数进行归一化处理,确保插件间分数可比。
- Reserve: 在 Cache 中预留资源,防止并发调度冲突。
- Permit: 等待外部准入条件(如资源配额、多调度器协调)。
- Bind: 写入 API Server 的 Binding 对象,完成调度。
2.3 节点选择机制:NodeSelector 与 NodeName
节点选择是调度器最基础的硬约束机制,通过标签匹配直接限定 Pod 可调度的节点范围。
| 机制 | 定义方式 | 匹配逻辑 | 适用场景 |
|---|---|---|---|
| NodeName | spec.nodeName |
精确匹配节点名称,跳过调度器 | 调试、DaemonSet 固定节点 |
| NodeSelector | spec.nodeSelector |
键值对精确匹配(AND 逻辑) | 简单环境隔离(如 GPU 节点) |
| NodeAffinity(required) | spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution |
支持 In/NotIn/Exists/DoesNotExist/Gt/Lt 操作符 | 复杂标签匹配,多条件组合 |
# NodeSelector 示例:仅调度到 GPU 节点
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
nodeSelector:
accelerator: nvidia-tesla-v100
containers:
- name: cuda-container
image: nvidia/cuda:12.0-base
NodeSelector 局限性: 仅支持精确键值对匹配,无法表达“不在某组节点上”或“标签值大于某个数”等语义。生产环境建议优先使用 NodeAffinity 替代 NodeSelector,以获得更丰富的匹配操作符。
2.4 节点亲和性(NodeAffinity)
节点亲和性分为 required(硬约束) 和 preferred(软约束) 两种类型。硬约束在过滤阶段执行,不满足则 Pod 无法调度;软约束在打分阶段执行,权重越高越优先选择。
# NodeAffinity 完整示例:硬约束 + 软约束组合
apiVersion: v1
kind: Pod
metadata:
name: affinity-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- us-east-1a
- us-east-1b
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
preference:
matchExpressions:
- key: instance-type
operator: In
values:
- c5.2xlarge
- weight: 20
preference:
matchExpressions:
- key: disk-type
operator: In
values:
- ssd
containers:
- name: app
image: nginx:latest
生产最佳实践: 将关键约束(如合规、安全)设为
required,将性能优化(如实例类型、磁盘类型)设为 preferred 并合理分配权重。权重值建议控制在 1-100 之间,避免极端值导致调度倾斜。
2.5 Pod 间亲和性与反亲和性
Pod 间亲和性(PodAffinity)与反亲和性(PodAntiAffinity)控制 Pod 与集群中其他 Pod 的相对位置关系,常用于微服务就近部署、故障域隔离等场景。
| 类型 | 语义 | 拓扑键(topologyKey) | 典型场景 |
|---|---|---|---|
| PodAffinity | Pod 倾向于与目标 Pod 部署在同一拓扑域 | kubernetes.io/hostname、topology.kubernetes.io/zone |
缓存与计算节点就近部署,降低延迟 |
| PodAntiAffinity | Pod 倾向于与目标 Pod 分散在不同拓扑域 | kubernetes.io/hostname、topology.kubernetes.io/zone |
高可用部署,避免单点故障 |
# PodAntiAffinity 示例:确保同一应用的两个副本不在同一节点
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname
containers:
- name: nginx
image: nginx:1.25
反亲和性性能警告:
requiredDuringScheduling 的反亲和性会显著增加调度器计算开销,当集群规模超过 1000 节点时,建议改用 preferredDuringScheduling 或通过拓扑分布约束(TopologySpreadConstraints)替代,避免调度器性能退化。
2.6 调度器扩展:自定义调度器与调度框架插件
Kubernetes 支持多调度器共存和调度框架插件扩展,满足 GitOps 场景下的特殊调度需求(如金丝雀发布、流量感知调度)。
- 多调度器: 通过
spec.schedulerName指定自定义调度器,实现不同工作负载使用不同调度策略。 - 调度框架插件: 实现
FilterPlugin、ScorePlugin、BindPlugin等接口,注入自定义逻辑。 - GitOps 集成: 在 ArgoCD/Flux 的 Application 中通过
spec.syncPolicy控制调度策略的灰度发布,结合preferredDuringScheduling实现渐进式调度。
# 自定义调度器声明示例
apiVersion: v1
kind: Pod
metadata:
name: custom-scheduler-pod
spec:
schedulerName: my-custom-scheduler
containers:
- name: app
image: nginx:latest
GitOps 调度优化要点:
- 使用
preferredDuringScheduling实现金丝雀节点的软偏好,避免硬约束导致调度失败。 - 结合
topologySpreadConstraints实现跨可用区的均匀分布,提升回滚后的快速恢复能力。 - 在调度器插件中注入
Prometheus指标,监控调度延迟与失败率,为 GitOps 自动化回滚提供数据支撑。