nodeSelector 与节点亲和性
本教程共 65 篇 · 第 39 篇 · 更新于 2026-08-14 · 约 9 分钟阅读
本节目标:学会用 nodeSelector 做最简单的节点筛选,理解节点亲和性比它强在哪,区分硬约束和软偏好,能写出带操作符和权重的亲和规则。
大多数时候调度器自己分配就行,但有些场景你得插手:比如”这个 Pod 必须跑在有 SSD 的机器上”,或者”这两个服务通信多,放同一可用区就近”。这类需求靠节点的标签来控制。
节点像其他对象一样能打标签。你可以手动打,Kubernetes 也会给每个节点自动加一批标准标签(如 kubernetes.io/hostname、topology.kubernetes.io/zone)。
39-1 nodeSelector 最省事
nodeSelector 是节点选择里最简单的一种。你在 Pod 里写”目标节点必须有哪些标签”,调度器只把 Pod 放到全部满足的节点上。
先给节点打标签:
kubectl label nodes node-1 disktype=ssd
再让 Pod 认这个标签:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeSelector:
disktype: ssd
只有带了 disktype=ssd 的节点才有资格接这个 Pod。不满足?那就一直 pending。
TipnodeSelector 的缺点是”全有或全无”:列出的标签必须每个都中,没有”优先”一说,也不能按其他 Pod 的标签来算。想要更细的控制,就得上节点亲和性。
39-2 节点亲和性更强
节点亲和性(nodeAffinity)概念上和 nodeSelector 一样,按节点标签挑节点,但表达能力更强,而且能写”软规则”。
它有两种:
requiredDuringSchedulingIgnoredDuringExecution:硬约束。不满足就不调度,相当于加强版 nodeSelector。preferredDuringSchedulingIgnoredDuringExecution:软偏好。尽量满足,找不到也将就调度。
名字里 IgnoredDuringExecution 的意思是:调度之后节点标签变了,已运行的 Pod 不会因此被踢走。
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- antarctica-east1
- antarctica-west1
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-label
operator: In
values:
- preferred-value
这段意思是:节点必须在 east1 或 west1 区(硬要求);同时若节点还有 another-label=preferred-value 就更理想(软偏好,权重 1)。
Note同时写了
nodeSelector和nodeAffinity,两者都得满足。两个nodeSelectorTerms之间是”或”,同一个 term 里多个表达式之间是”与”。
39-3 操作符怎么用
节点亲和性支持的操作符:In、NotIn、Exists、DoesNotExist、Gt、Lt。前四个 Pod 亲和性也能用,Gt/Lt 只能用在节点亲和性,且值必须是整数。
NotIn 和 DoesNotExist 能实现”反亲和”效果——把 Pod 赶离某类节点。当然赶节点更地道的做法是下一章的污点。
operator: NotIn
values: ["gpu-node"]
39-4 软偏好的权重
软偏好可以带 weight,范围 1 到 100。调度器给满足该偏好的节点加分,分数并入总评分。多个软规则时,权重大的影响更明显。
Warning别把硬约束写得过窄,比如要求一个很少见的标签组合。结果可能全集群没节点满足,Pod 永远
pending。先kubectl get nodes --show-labels看看真实有哪些标签再写。
39-5 与 nodeName 的区别
还有个 nodeName 字段,直接写死”跑在 node-1”。它比亲和性更硬,会绕过调度器。
spec:
nodeName: kube-01
TipnodeName 绕过调度器,节点资源不够或名字写错,Pod 直接失败甚至被删。除非写自定义调度器,否则优先用 nodeSelector 或节点亲和性,别直接写 nodeName。