3. 节点选择与标签机制:节点标签、节点选择器与节点亲和性基础概念
在 Kubernetes 集群中,Pod 被调度到哪个节点运行,并非完全随机。调度器(kube-scheduler)通过一套灵活的标签与选择器机制,实现从“被动分配”到“主动引导”的调度控制。本章深入解析节点标签(Node Labels)、节点选择器(nodeSelector)和节点亲和性(nodeAffinity)三个核心概念,为后续网络拓扑感知调度奠定基础。
3.1 节点标签(Node Labels)—— 调度的“元数据基石”
节点标签是附着在 Node 对象上的键值对(Key-Value),用于标识节点的属性,如硬件配置、地理位置、可用区、磁盘类型等。标签本身不直接决定调度行为,但它是所有选择器和亲和性规则的操作对象。
3.1.1 常用节点标签示例
| 标签键(Key) | 标签值(Value)示例 | 说明 |
|---|---|---|
kubernetes.io/hostname |
node-01 |
节点主机名,由系统自动添加 |
topology.kubernetes.io/zone |
us-east-1a |
节点所在的可用区(云环境) |
node.kubernetes.io/instance-type |
g4dn.xlarge |
云实例类型,标识计算/GPU能力 |
disktype |
ssd / hdd |
自定义标签,标识磁盘类型 |
accelerator |
nvidia-tesla-t4 |
自定义标签,标识GPU加速器 |
3.1.2 节点标签操作命令
# 为节点添加标签
kubectl label node node-01 disktype=ssd
# 查看节点标签(以列表形式)
kubectl get node node-01 --show-labels
# 覆盖已有标签值
kubectl label node node-01 disktype=nvme --overwrite
# 删除节点标签(键名后加减号)
kubectl label node node-01 disktype-
topology.kubernetes.io/)避免冲突;值应使用小写字母、数字和连字符,保持语义清晰。避免使用含义模糊的标签如 type=good。
3.2 节点选择器(nodeSelector)—— 最简单的约束方式
nodeSelector 是 Pod 规范中的一个字段,它使用键值对精确匹配节点标签。调度器只会将 Pod 分配到包含所有指定标签的节点上。这是 Kubernetes 最早提供的节点选择机制,简单直接,但表达能力有限——仅支持“等于”(Equality)匹配。
3.2.1 nodeSelector 使用示例
apiVersion: v1
kind: Pod
metadata:
name: ssd-pod
spec:
nodeSelector:
disktype: ssd # 只调度到 disktype=ssd 的节点
containers:
- name: app
image: nginx
3.2.2 nodeSelector 的局限性
- 仅支持精确匹配:无法表达“不在某组节点上”或“值大于某个数”等逻辑。
- 不支持多条件组合:多个标签之间是 AND 关系,无法表达 OR 或 NOT。
- 无软性偏好:要么必须满足(硬约束),要么不调度,没有“尽量满足”的选项。
nodeSelector 条件时,Pod 将一直处于 Pending 状态,直到有符合条件的节点加入或标签被修改。生产环境中应避免过度依赖单一标签。
3.3 节点亲和性(nodeAffinity)—— 灵活且强大的调度规则
节点亲和性是 nodeSelector 的进化版,属于调度策略的一部分,定义在 Pod 的 spec.affinity.nodeAffinity 字段下。它支持更丰富的匹配运算符(In、NotIn、Exists、DoesNotExist、Gt、Lt),并区分硬性要求(required)和软性偏好(preferred)两种语义。
3.3.1 节点亲和性核心结构
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬约束
nodeSelectorTerms:
- matchExpressions:
- key: accelerator
operator: In
values:
- nvidia-tesla-t4
- nvidia-a100
preferredDuringSchedulingIgnoredDuringExecution: # 软约束
- weight: 80
preference:
matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- us-east-1a
containers:
- name: gpu-app
image: tensorflow:latest
3.3.2 两种调度语义对比
| 语义类型 | 字段名 | 行为说明 | 调度失败后果 |
|---|---|---|---|
| 硬约束 | requiredDuringSchedulingIgnoredDuringExecution |
Pod 必须调度到满足条件的节点;不满足则不调度 | Pod 处于 Pending |
| 软约束 | preferredDuringSchedulingIgnoredDuringExecution |
调度器优先选择满足条件的节点;不满足时仍可调度到其他节点 | Pod 正常调度,但优先级较低 |
3.3.3 支持的运算符
- In:标签值在给定的值列表中(等价于 nodeSelector 的等值匹配)
- NotIn:标签值不在给定的值列表中(排除特定节点)
- Exists:节点存在该标签键(无论值是什么)
- DoesNotExist:节点不存在该标签键
- Gt / Lt:标签值(数值型字符串)大于或小于给定值
nodeSelector 只支持 In 运算符(隐式),而 nodeAffinity 支持 6 种运算符,且可以组合多个 matchExpressions 实现复杂的调度逻辑。
3.4 节点选择机制对比总览
| 特性 | nodeSelector | nodeAffinity(硬约束) | nodeAffinity(软约束) |
|---|---|---|---|
| 匹配方式 | 精确键值对 | 表达式 + 运算符 | 表达式 + 运算符 + 权重 |
| 运算符支持 | 仅 In(隐式) | In, NotIn, Exists, DoesNotExist, Gt, Lt | 同左 |
| 多条件组合 | AND(多个标签) | AND(多个 matchExpressions) | 加权求和(多个 preference) |
| 是否强制 | 是 | 是 | 否(尽量满足) |
| 适用场景 | 简单固定分配 | 严格硬件/合规要求 | 性能优化、负载均衡 |
3.5 节点选择与亲和性工作流程
下图展示了从节点标签定义到 Pod 调度决策的完整流程,以及三种选择机制在调度器中的执行顺序。
3.6 实际应用场景与案例
3.6.1 场景一:GPU 工作负载严格绑定
要求 AI 训练 Pod 必须运行在带有 NVIDIA A100 GPU 的节点上,且优先选择可用区 us-east-1a。
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: accelerator
operator: In
values:
- nvidia-a100
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 90
preference:
matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- us-east-1a
3.6.2 场景二:避免将 Pod 调度到特定节点组
使用 NotIn 运算符排除已标记为 maintenance=true 的节点。
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: maintenance
operator: NotIn
values:
- "true"
3.6.3 场景三:按磁盘类型软性分流
希望日志 Pod 优先调度到 SSD 节点,但如果没有 SSD 节点,HDD 节点也可以接受。
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 70
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
topology.kubernetes.io/zone、node.kubernetes.io/instance-type),避免后期临时打标导致调度混乱。对于关键业务 Pod,始终使用硬约束保证合规性;对于非关键 Pod,使用软约束配合权重实现负载均衡。
3.7 本章小结
- 节点标签是调度的元数据基础,通过
kubectl label管理,支持自定义键值对。 - nodeSelector 提供最简单的精确匹配,适合快速约束,但表达能力有限。
- nodeAffinity 提供硬约束和软约束两种模式,支持 6 种运算符和权重机制,是生产环境的首选方案。
- 三种机制可以组合使用,调度器按
nodeSelector → 硬约束 → 软约束的顺序执行决策。