首页/云/Kubernetes 速查/nodeAffinity 与 required/preferred
调度与资源52 条

nodeAffinity 与 required/preferred

比 nodeSelector 更细:required 是硬约束(不满足不调度),preferred 是加权软偏好;支持 In/NotIn/Gt/Lt 等操作符。

Kubernetes 速查云更新于 2026-10-13

概念定位

nodeAffinity 是 nodeSelector 的加强版:用 matchExpressions 写条件,支持 In、NotIn、Exists、DoesNotExist、Gt、Lt 等操作符,并且分成硬约束(required,不满足就不调度)与软偏好(preferred,按权重打分)。适用平台是 Kubernetes。字段名里的 IgnoredDuringExecution 说明它在 Pod 运行后不生效——节点标签变了也不会触发重新调度,这点在评估变更影响时必须记住。

基本信息

适用平台Kubernetes,Pod 级字段 spec.affinity.nodeAffinity
硬约束requiredDuringSchedulingIgnoredDuringExecution
软偏好preferredDuringSchedulingIgnoredDuringExecution,每项带 weight
操作符In、NotIn、Exists、DoesNotExist、Gt、Lt

典型使用场景

  • 限定可用区:把服务固定到指定 zone,满足数据本地性或合规要求
  • 绑定机型:只调度到带 GPU、SSD 或特定实例类型标签的节点
  • 成本优化:用软偏好优先选低成本节点池,容量不足时再落到其他池
  • 灰度迁移:新节点池打上新标签,用软偏好逐步引流,验证后改成硬约束
  • 排除节点:用 NotIn 避开正在维护或有已知问题的节点

affinity 示例

affinity 示例
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values: [cn-hangzhou-b, cn-hangzhou-c]
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 80
          preference:
            matchExpressions:
              - key: disktype
                operator: In
                values: [ssd]

核对与排查

核对与排查
kubectl get nodes -L topology.kubernetes.io/zone -L disktype   # 节点标签现状
kubectl describe pod web-x | grep -i -A5 'Node-Selectors'      # 解析后的约束
kubectl get events --field-selector reason=FailedScheduling --sort-by=.lastTimestamp | tail -3
kubectl get pod web-x -o jsonpath='{.spec.affinity.nodeAffinity}'   # 与清单比对

硬软约束对照

写法不满足时适用场景
requiredPod 停在 Pending,事件里提示不匹配合规与数据本地性等不能妥协的约束
preferred(带 weight)仍会调度到其他节点成本与性能偏好,需要留退路
多个 nodeSelectorTerms任一条满足即可通过多套可接受方案
多个 matchExpressions同一 term 内需全部满足组合条件,逐项校验
字段尾部的 IgnoredDuringExecution 表示 Pod 运行后节点标签变化不会触发重新调度,调整节点标签不会自动迁移存量 Pod。
nodeSelector 是 nodeAffinity 的简化写法,二者同时存在时都必须满足,维护时避免两处写重复约束。

落地时的核对清单

  • 先在节点侧确认标签真的存在:kubectl get nodes -L <键> 一看便知,避免照着模板写约束
  • 硬约束优先用 In 收敛取值范围,NotIn 组合过多时容易在扩容时突然全不匹配
  • 软偏好给不同节点池分配不同权重,权重相同时调度结果会变得不确定
  • 约束改动牵涉现有副本时,用滚动更新或重建让新模板生效,不要指望已运行 Pod 自己迁移

易错点

  • 把硬约束写成 preferred:不满足照样调度上去,需要等故障才被发现,语义与预期不符
  • required 条件与节点池标签长期不同步,扩缩容或换机型时容易踩空导致 Pod 大面积 Pending
  • 忽略 IgnoredDuringExecution:改节点标签不会迁移已有 Pod,必须重建或滚动更新才能生效
  • Gt/Lt 只能用于数值型标签且语义是整数比较,用在字符串标签上会被 API 拒绝,写之前确认标签类型

数据来源与参考

  • Kubernetes 官方文档 · 节点亲和性
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌