3. Pod 调度基础:Kubernetes 调度器工作原理、调度策略、节点亲和性与反亲和性
Pod 调度是 Kubernetes 集群管理的核心环节,决定了工作负载在集群节点上的分布。理解调度器的工作原理与策略,是进行节点池滚动升级、实现 Pod 平滑迁移与调度优化的前提。本节将系统讲解调度器的调度流程、核心调度策略以及节点亲和性与反亲和性的配置方法。
3.1 Kubernetes 调度器工作原理
Kubernetes 默认调度器(kube-scheduler)采用两阶段调度模型:过滤(Predicates / Filtering) 和 打分(Priorities / Scoring)。调度器为每个待调度的 Pod 寻找一个最合适的节点,整个过程是确定性的,且支持可插拔的调度框架。
调度流程核心步骤:
- 监听队列:调度器通过 Informer 机制监听 API Server,将未调度的 Pod 加入调度队列。
- 过滤阶段:遍历所有节点,应用预选策略(Predicates),筛选出满足 Pod 资源请求、端口冲突、污点容忍等条件的候选节点集合。
- 打分阶段:对候选节点执行优选策略(Priorities),根据资源利用率、亲和性规则、节点拓扑分布等维度进行加权评分。
- 绑定阶段:选择得分最高的节点,将 Pod 与节点的绑定关系写入 etcd,完成调度。
3.2 核心调度策略
调度策略分为预选策略和优选策略两大类。在节点池滚动升级场景中,预选策略决定了 Pod 能否迁移到目标节点,优选策略则影响 Pod 在节点间的分布均衡性。
| 策略类别 | 策略名称 | 作用说明 | 升级场景影响 |
|---|---|---|---|
| 预选策略 | PodFitsResources | 检查节点剩余 CPU/内存是否满足 Pod 请求 | 目标节点资源不足时 Pod 无法迁移 |
| PodToleratesNodeTaints | 检查 Pod 是否容忍节点污点 | 节点池升级时需临时容忍 NoSchedule 污点 | |
| CheckNodeUnschedulable | 检查节点是否被标记为不可调度 | 升级节点需先 cordon 隔离 | |
| 优选策略 | LeastRequestedPriority | 优先调度到资源利用率低的节点 | 促进节点间负载均衡 |
| BalancedResourceAllocation | 优先选择 CPU/内存使用率均衡的节点 | 避免单一资源瓶颈 | |
| NodeAffinityPriority | 根据节点亲和性规则加权 | 确保 Pod 调度到指定拓扑的节点 |
升级实践提示:在节点池滚动升级前,建议通过
kubectl cordon <node> 将节点标记为不可调度,此时调度器预选策略中的 CheckNodeUnschedulable 会阻止新 Pod 调度到该节点,确保升级过程中不会产生新的工作负载。
3.3 节点亲和性与反亲和性
节点亲和性(Node Affinity)和反亲和性(Node Anti-Affinity)是 Kubernetes 提供的精细化调度控制机制,允许用户基于节点标签(Label)来约束 Pod 的调度位置。在节点池升级治理中,合理使用亲和性规则可以控制 Pod 在节点池间的迁移路径,避免流量冲击和资源倾斜。
3.3.1 节点亲和性(Node Affinity)
节点亲和性通过 nodeSelectorTerms 定义,支持两种语义:
- requiredDuringSchedulingIgnoredDuringExecution:硬约束,调度时必须满足,否则 Pod 无法调度。
- preferredDuringSchedulingIgnoredDuringExecution:软约束,调度时优先满足,但不强制。
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-pool-type
operator: In
values:
- "stable"
- "canary"
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
preference:
matchExpressions:
- key: zone
operator: In
values:
- "zone-a"
containers:
- name: app
image: nginx:1.25
3.3.2 节点反亲和性(Node Anti-Affinity)
节点反亲和性用于避免同一工作负载的多个副本调度到同一节点或同一拓扑域,提升高可用性。常见于 StatefulSet 或 Deployment 的多副本部署。
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: web
image: nginx:1.25
升级风险提示:在节点池滚动升级时,如果 Pod 配置了
requiredDuringSchedulingIgnoredDuringExecution 的节点亲和性,且目标节点池的标签与规则不匹配,Pod 将无法被调度到新节点,导致升级阻塞。建议在升级前将硬约束改为软约束,或确保新节点池的标签与规则一致。
3.4 调度策略在节点池升级中的应用
在节点池滚动升级场景中,调度策略的合理配置直接影响升级效率和业务稳定性。以下是关键应用建议:
| 升级阶段 | 调度策略调整 | 操作说明 |
|---|---|---|
| 升级前准备 | 设置节点污点(Taint) | 对旧节点添加 node.kubernetes.io/unschedulable:NoSchedule 污点,阻止新 Pod 调度 |
| Pod 迁移 | 调整亲和性规则 | 将硬约束改为软约束,或更新 matchExpressions 中的 values 指向新节点池标签 |
| 升级中 | 启用 PodDisruptionBudget | 设置 PDB 限制同时中断的 Pod 数量,配合反亲和性保证最小可用副本 |
| 升级后验证 | 恢复调度策略 | 移除旧节点污点,恢复原始亲和性规则,确保新 Pod 按预期分布 |
核心要点总结:
- 调度器两阶段模型(过滤+打分)是 Pod 调度的基础,升级时需关注预选策略中的资源检查和污点容忍。
- 节点亲和性控制 Pod 调度到指定节点池,反亲和性保证多副本分散部署,两者在升级中需协同调整。
- 升级前通过 cordon 和 taint 隔离旧节点,升级中通过 PDB 和软约束保障业务连续性,升级后恢复策略完成收敛。