3. 默认调度策略详解:节点选择、节点亲和性、Pod亲和性与反亲和性、污点与容忍度
Kubernetes 调度器(kube-scheduler)的核心职责是将待调度的 Pod 绑定到最合适的节点上。默认调度策略并非单一算法,而是一套由 过滤(Predicates) 和 打分(Priorities) 组成的多阶段决策流程。本章深入解析节点选择、节点亲和性、Pod 亲和性与反亲和性、污点与容忍度四大核心机制,帮助 SRE 精准控制 Pod 分布。
3.1 调度两阶段:过滤与打分
调度器对每个待调度 Pod 依次执行两个阶段:
- 过滤阶段(Filtering):遍历所有节点,剔除不满足 Pod 硬性约束的节点(如资源不足、端口冲突、污点不匹配)。
- 打分阶段(Scoring):对通过过滤的节点按优先级策略打分,选出最优节点。
3.2 节点选择:nodeName 与 nodeSelector
节点选择是最基础的调度约束,分为显式指定和标签匹配两种方式。
| 机制 | 描述 | 适用场景 | 限制 |
|---|---|---|---|
| nodeName | 直接指定节点名称,跳过调度器过滤 | 调试、单节点部署、DaemonSet 辅助 | 节点不可用则 Pod 无法调度;不灵活 |
| nodeSelector | 基于节点标签(label)的简单匹配 | 按硬件类型(如 GPU)、环境(如 prod/staging)分组 | 仅支持等值匹配(In/NotIn 需用节点亲和性) |
# nodeName 示例
apiVersion: v1
kind: Pod
metadata:
name: fixed-node-pod
spec:
nodeName: worker-01
containers:
- name: nginx
image: nginx
# nodeSelector 示例
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
nodeSelector:
hardware-type: gpu
containers:
- name: cuda-app
image: nvidia/cuda:12.0
3.3 节点亲和性:精细化节点选择
节点亲和性(Node Affinity)是 nodeSelector 的升级版,支持更丰富的匹配逻辑和调度阶段控制。分为 requiredDuringSchedulingIgnoredDuringExecution(硬约束)和 preferredDuringSchedulingIgnoredDuringExecution(软约束)。
apiVersion: v1
kind: Pod
metadata:
name: node-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: disk-type
operator: In
values:
- ssd
containers:
- name: app
image: myapp:latest
3.4 Pod 亲和性与反亲和性:Pod 间拓扑控制
Pod 亲和性(Pod Affinity)与反亲和性(Pod Anti-Affinity)控制 Pod 之间的相对位置,常用于微服务就近部署或高可用分散。
| 类型 | 语义 | 典型场景 | 性能影响 |
|---|---|---|---|
| Pod 亲和性 | 将 Pod 调度到与目标 Pod 相同的拓扑域 | 缓存与计算服务同节点部署,减少网络延迟 | 增加调度器计算量,需配合 topologyKey |
| Pod 反亲和性 | 将 Pod 调度到与目标 Pod 不同的拓扑域 | 多副本分散到不同节点/可用区,提升容灾 | required 模式可能降低集群利用率 |
# Pod 反亲和性:确保同一 Deployment 的副本分散在不同节点
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
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
3.5 污点与容忍度:节点排斥与 Pod 准入
污点(Taint)是节点对 Pod 的排斥标记,容忍度(Toleration)是 Pod 对污点的豁免声明。两者共同实现节点隔离、专用节点和故障驱逐等场景。
3.5.1 污点三要素
- Key:污点标识符,如
node.kubernetes.io/unreachable - Value:可选,用于更细粒度匹配
- Effect:调度影响,包括:
NoSchedule:不调度新 Pod(已有 Pod 不受影响)PreferNoSchedule:尽量不调度,软约束NoExecute:不调度新 Pod,并驱逐已有不匹配的 Pod
3.5.2 容忍度匹配规则
| 污点 Effect | 容忍度 Operator | 匹配行为 |
|---|---|---|
| NoSchedule | Equal / Exists | Pod 可调度到该节点 |
| PreferNoSchedule | Equal / Exists | 调度器尽量避开,但不强制 |
| NoExecute | Equal / Exists | Pod 可运行;若未容忍,则被驱逐 |
# 给节点添加污点:禁止普通 Pod 调度
kubectl taint nodes worker-02 dedicated=ml:NoSchedule
# Pod 容忍度示例:允许运行在专用 ML 节点
apiVersion: v1
kind: Pod
metadata:
name: ml-pod
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "ml"
effect: "NoSchedule"
containers:
- name: pytorch
image: pytorch/pytorch:latest
3.6 综合调度流程:从过滤到绑定的完整链路
以下 SVG 图展示默认调度策略中节点选择、亲和性、污点容忍度的协同工作流程。
3.7 实战排查:调度失败常见原因
当 Pod 处于 Pending 状态时,按以下步骤快速定位:
- 检查事件:
kubectl describe pod <pod-name>查看 Events 字段 - 验证节点资源:
kubectl describe node <node-name>查看 Allocatable 和 Conditions - 确认污点:
kubectl describe node <node-name> | grep Taints - 检查亲和性规则:确认 labelSelector 和 topologyKey 是否匹配现有节点标签
3.8 性能优化:调度器配置调优
对于大规模集群(节点数 > 500),默认调度策略可能成为瓶颈。以下参数可在 kube-scheduler 配置中调整:
| 参数 | 默认值 | 推荐值(大规模) | 说明 |
|---|---|---|---|
percentageOfNodesToScore |
50% | 10% | 减少打分阶段扫描节点数,降低延迟 |
bindTimeoutSeconds |
100 | 30 | 缩短绑定超时,快速失败重试 |
podInitialBackoffSeconds |
1 | 5 | 调度失败后初始重试间隔 |
通过合理组合节点选择、亲和性规则和污点容忍度,SRE 可以实现从简单隔离到复杂拓扑感知的精细化调度控制,为上层应用提供稳定、高性能的运行环境。