nodeSelector 是 Kubernetes 中一种典型的“硬性约束”调度方式:只有当节点同时满足你配置的全部标签条件时,Pod 才会被成功调度到该节点;只要任意一个标签条件不匹配,Pod 就会持续处于 Pending 状态。在使用前,需要先通过 kubectl label 为节点添加小写标签(标签仅允许包含字母、数字、-、.),然后再在 Pod 或 Deployment 的 spec.template.spec 中声明 nodeSelector。这里的关键在于:配置中的所有键值对都必须完全匹配,缺少任何一项都不行。

如果你想在 Kubernetes 中将应用调度到指定节点,直接使用 nodeSelector 就可以实现。它不是“优先建议”,而是强制匹配规则:Pod 只会被安排到同时具备所有目标标签的节点上,否则就会一直停留在 Pending 状态,无法完成调度。
给目标节点打上标签
先确认你准备将 Pod 调度到哪台节点(例如 node-01),然后使用 kubectl label 为该节点添加自定义标签:
kubectl label nodes node-01 disktype=ssdkubectl label nodes node-01 env=prodkubectl label nodes node-01 role=ingress
执行完成后,可以运行 kubectl get nodes --show-labels 或 kubectl describe node node-01,确认节点标签是否已经成功写入。需要特别注意的是:标签的键和值都**必须使用小写**,并且只允许包含字母、数字、- 和 .,不能出现空格,也不能包含大写字母。
在 Pod 或 Deployment 中声明 nodeSelector
nodeSelector 不是写在最外层 spec 中,而是写在 spec 下;如果是 Deployment,则应配置在 spec.template.spec 中:
- 单标签 Pod 示例:
spec: nodeSelector: disktype: ssd containers: - name: nginx image: nginx
- 多标签 Deployment 示例(生产环境中更常见):
spec: template: spec: nodeSelector: disktype: ssd env: prod containers: - name: app image: myapp:v1
⚠️ 这里要再次强调:所有标签键值对都必须同时命中,缺一不可。只要集群里没有任何节点同时带有 disktype=ssd 和 env=prod 这两个标签,这个 Deployment 创建出来的新 Pod 就不会被成功调度。
验证是否调度成功
部署完成后,建议立即进行检查:
kubectl get pod -o wide—— 查看NODE列是否为你预期的节点名称kubectl describe pod—— 查看 Pod 实际绑定到哪台节点| grep Node: kubectl get pod—— 直接输出当前节点名-o jsonpath='{.spec.nodeName}'
如果 Pod 状态始终显示为 Pending,可以优先排查以下问题:节点是否存在、标签名称和标签值拼写是否完全一致(注意大小写敏感)、是否遗漏了某个必需标签。
它和 nodeName 的区别
nodeName 的含义更直接:把 Pod 强制指定到某一台具体机器上,例如 spec.nodeName: node-01。一旦这样配置,实际上就等于绕过了 Kubernetes 调度器,连资源是否充足都不会先经过正常调度判断。相比之下,nodeSelector 仍然会遵循标准调度流程,资源评估、污点与容忍等机制都会继续生效,只是在这些基础上额外增加了一层“节点标签筛选”条件。因此,在日常 Kubernetes 节点调度场景中,如果你的目标只是将工作负载稳定安排到某一类节点上,通常更推荐使用 nodeSelector;除非你的需求非常明确,就是必须跳过常规调度策略,才考虑使用 nodeName。
