k8s 节点绑定:nodeName 与 nodeSelector 实战
一、方法一:通过 nodeName 指定固定节点
nodeName是最简单直接的节点绑定方式,它通过在 Pod 模板中直接指定节点名称,强制将 Pod 部署到该节点上。这种方式优先级最高,会跳过 Scheduler 的调度逻辑,直接将 Pod 分配到目标节点。
2.1 操作步骤
步骤 1:编辑 Deployment.yaml 文件
示例一个部署 Nginx 的 Deployment,在spec.template.spec下添加nodeName字段,指定目标节点名称(此处以node01为例):
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-nodename
namespace: default
spec:
selector:
matchLabels:
app: nginx-nodename
replicas: 3
template:
metadata:
labels:
app: nginx-nodename
spec:
nodeName: node01 # 核心配置:指定Pod必须部署到node01节点
containers:
- name: nginx
image: nginx:1.24
ports:
- containerPort: 80
步骤 2:部署 Deployment
使用kubectl apply命令部署上述 yaml 文件:
bash
kubectl apply -f nginx-deployment-nodename.yaml
步骤 3:验证部署效果
部署完成后,通过kubectl get pods查看 Pod 的运行节点:
bash
kubectl get pods -o wide
2.2 预期效果
输出结果中,NODE列显示为node01,说明 Nginx Pod 成功部署到node01节点上。
2.3 注意事项
-
节点名称必须准确 :需确保
nodeName指定的节点名称在集群中存在(可通过kubectl get nodes查看),否则 Pod 会处于Pending状态; -
跳过 Scheduler 调度 :使用
nodeName后,Scheduler 不会参与 Pod 调度,若目标节点资源不足(如 CPU / 内存不够),Pod 会部署失败; -
适用场景有限:通常用于临时测试、节点维护等简单场景,不适合大规模、动态调整的业务场景。
二、方法二:通过 nodeSelector 标签匹配节点
nodeSelector是更灵活的节点绑定方式,它通过 "节点标签 + Pod 选择器" 的方式,让 Pod 自动调度到带有指定标签的节点上。这种方式支持多个节点匹配,且能通过标签动态管理节点分组,适合大规模、需要灵活调整的业务场景。
3.1 操作逻辑
-
给目标节点打上相同的标签(如
type=select); -
在 Pod 模板中通过
nodeSelector指定需要匹配的标签; -
Scheduler 会自动将 Pod 调度到带有该标签的节点上(若有多个符合条件的节点,会按默认调度策略分配)。
3.2 详细操作步骤
步骤 1:查看集群节点列表
首先确认集群中的节点名称,避免标签打错节点:
bash
kubectl get nodes -o wide
输出示例(假设集群中有node01和node02两个节点):
bash
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
node01 Ready <none> 43h v1.21.0 192.168.1.10 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://20.10.12
node02 Ready <none> 43h v1.21.0 192.168.1.11 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://20.10.12
步骤 2:给目标节点打标签
给node01和node02打上标签type=select,表示这两个节点属于 "可被选择" 的分组:
# 给单个节点打标签(若需批量操作,可连续指定节点名称)
kubectl label nodes node01 node02 type=select
步骤 3:验证标签是否生效
通过kubectl get nodes -l 标签键=标签值查看带有指定标签的节点,确认标签已成功添加:
kubectl get nodes -l type=select
输出示例(仅显示带有type=select标签的节点):
NAME STATUS ROLES AGE VERSION
node01 Ready <none> 43h v1.21.0
node02 Ready <none> 43h v1.21.0
步骤 4:编写带有 nodeSelector 的 Deployment.yaml
创建另一个 Nginx Deployment,在spec.template.spec下添加nodeSelector字段,指定匹配标签type=select:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-nodeselector
namespace: default
spec:
selector:
matchLabels:
app: nginx-nodeselector
replicas: 3
template:
metadata:
labels:
app: nginx-nodeselector
spec:
nodeSelector:
type: select # 核心配置:匹配标签为type=select的节点
containers:
- name: nginx
image: nginx:1.24
ports:
- containerPort: 80
步骤 5:部署并验证效果
- 部署 Deployment:
bash
kubectl apply -f nginx-deployment-nodeselector.yaml
- 查看 Pod 的运行节点:
bash
kubectl get pods -o wide -l app=nginx-nodeselector
3.3 预期效果
Pod 会被随机分配到node01和node02节点上。
3.4 补充-节点标签的常用操作
在实际使用中,可能需要修改、查看或删除节点标签,以下是常用命令:
1.修改节点标签 :使用--overwrite参数覆盖已有的标签值(如将type=select改为type=webtest):
bash
kubectl label nodes node01 node02 type=webtest --overwrite
2.查看节点所有标签 :使用--show-labels参数查看指定节点的全部标签:
bash
kubectl get nodes node01 node02 --show-labels
2.删除节点标签 :在标签键后加-即可删除指定标签(如删除type标签):
bash
kubectl label nodes node01 node02 type-
三、节点绑定方法的对比
| 对比维度 | nodeName | nodeSelector |
|---|---|---|
| 绑定逻辑 | 直接指定节点名称 | 标签匹配节点 |
| 灵活性 | 低(仅单个节点) | 高(支持多节点分组) |
| 是否依赖 Scheduler | 不依赖(跳过调度) | 依赖(Scheduler 调度) |
| 资源检查 | 不检查(资源不足会失败) | 检查(资源不足会 Pending) |
| 适用场景 | 临时测试、节点维护 | 业务分组、大规模部署 |
四、常见问题与排查技巧
-
Pod 处于 Pending 状态,提示 "node (s) had taint {xxx}, that the pod didn't tolerate"
原因:目标节点存在污点(Taint),Pod 未配置容忍(Toleration)。
排查:使用
kubectl describe node 节点名称查看节点污点,在 Pod 模板中添加对应的tolerations配置。 -
nodeSelector 匹配不到节点,Pod 处于 Pending 状态
原因:① 节点标签打错或未打标签;② 标签键值对不匹配。
排查:执行
kubectl get nodes -l 标签键=标签值确认是否有符合条件的节点,重新检查标签配置。 -
使用 nodeName 时,Pod 提示 "node not found"
原因:
nodeName指定的节点名称不存在或拼写错误。排查:执行
kubectl get nodes确认节点名称,修正nodeName字段。