DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

两条 NotIn 仍选中被排除节点:检查 nodeSelectorTerms 的 OR

分在不同nodeSelectorTerms的NotIn条件是OR。对照实际模板层级,将需同时成立的条件放同一term,再核对新Pod与合格节点容量。

节点亲和性中写了两条 NotIn:排除某个 hostname,再排除带某个测试标签的节点。新 Pod 却仍落到其中一个节点。若两个条件分别放在不同的 nodeSelectorTerms 条目中,规则实际表达的是“满足任意一组即可”。

不同 term 之间是 OR,同一个 term 内的多条 matchExpressions 是 AND。YAML 里看起来有两条限制,不能证明它们同时生效;列表层级决定组合关系。

拆开看每一组是否成立

例如下面只是所需节点亲和性内部的一段配置:

nodeSelectorTerms:
  - matchExpressions:
      - key: kubernetes.io/hostname
        operator: NotIn
        values: [worker-04]
  - matchExpressions:
      - key: test
        operator: NotIn
        values: [foo]

一个 hostname 为 worker-04、但没有 test=foo 的节点,不满足第一组,却可能满足第二组,所以仍然合格。反过来,带 test=foo、hostname 为其他值的节点,也能通过第一组。

先读取服务器上实际生成的 Pod、所属工作负载模板和节点标签,确认部署工具没有改变列表层级。kubernetes.io/hostname 的标签值还应从节点读取,不默认等于节点对象名称。

kubectl -n team-app get pod worker-abc12 -o yaml
kubectl -n team-app get deployment worker -o yaml
kubectl get nodes --show-labels

以上名称需替换。如果 Pod 已在更新前调度,当前位置也不能用来证明新规则失效;先对齐模板修订与新 Pod 的创建时间。

同时排除两类节点,把条件放进同一组

如果实际目标是同时满足两个排除条件,组合应写成同一个 term:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: NotIn
              values: [worker-04]
            - key: test
              operator: NotIn
              values: [foo]

这是 Pod spec 内的局部示例。合入原工作负载模板时保留其他条件,不把整个 affinity 都替换掉。NotIn 对缺少对应标签的节点也可以成立;若要求节点必须具备某个标签,还要明确加入该键的 Exists,不能把“没有这个值”当作“必须有这个键”。

原来的 nodeSelector 也仍需同时满足。preferredDuringSchedulingIgnoredDuringExecution 只是偏好,即使给很高 weight,也不会成为硬性排除。空 term 不表示允许所有节点,不要通过加入空条目来表达兜底。

检查新 Pod,而不是期待旧副本立即迁移

修改前保存审定模板,确认满足全部条件的节点还有足够容量,并核对卷、污点和资源请求。通过原管理入口发布模板,再观察新 Pod 的节点、就绪状态和业务请求。硬条件收紧后没有合格节点,Pending 可以是规则正常执行的结果,应继续读调度事件。

普通 Deployment 的已运行 Pod 不会只因节点标签变化就被这类调度规则立即驱逐。DaemonSet 还会持续管理节点资格,相关区别见DaemonSet 节点标签变化。不要为验证排除条件强行设置 nodeName,它会绕过正常调度路径。

回退时从原配置来源恢复模板,安排相应的副本替换,并确认实际节点范围。已经发生的进程退出或业务写入不会因为亲和性恢复自动撤销。