72·调度与资源进阶

节点选择器

kubernetesschedulernode-selector

节点选择器

学习目标

  1. 理解 nodeSelector 的作用和使用场景
  2. 掌握如何使用标签选择节点
  3. 了解 nodeSelector 的局限性

核心概念

一句话解释

nodeSelector 通过标签匹配,将 Pod 调度到具有特定标签的节点上。

基本用法

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  nodeSelector:                    # 指定节点选择器
    disktype: ssd                  # 要求节点有 disktype=ssd 标签
    zone: east                     # 要求节点有 zone=east 标签
  containers:
  - name: app
    image: nginx

调度流程

┌─────────────────────────────────────────────────────────┐
│                    调度过程                              │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Pod: nodeSelector: {disktype: ssd, zone: east}        │
│                         │                               │
│                         v                               │
│  ┌─────────────┬─────────────┬─────────────┐           │
│  │   Node A    │   Node B    │   Node C    │           │
│  │ disktype=hdd│ disktype=ssd│ disktype=ssd│           │
│  │ zone=east   │ zone=west   │ zone=east   │           │
│  │      X      │      X      │     ✓       │           │
│  └─────────────┴─────────────┴─────────────┘           │
│                                       │                 │
│                                       v                 │
│                              Pod 调度到 Node C          │
└─────────────────────────────────────────────────────────┘

节点标签管理

# 查看节点标签
kubectl get nodes --show-labels

# 给节点添加标签
kubectl label nodes node1 disktype=ssd
kubectl label nodes node1 zone=east

# 删除节点标签
kubectl label nodes node1 disktype-

# 修改标签值
kubectl label nodes node1 disktype=hdd --overwrite

常用节点标签

# 内置标签
kubernetes.io/hostname: node1           # 主机名
topology.kubernetes.io/zone: zone-a     # 可用区
topology.kubernetes.io/region: us-east  # 区域
node.kubernetes.io/instance-type: t3.medium  # 实例类型

# 自定义标签示例
disktype: ssd                          # 磁盘类型
gpu: "true"                            # 是否有 GPU
environment: production                # 环境
workload: compute                      # 工作负载类型

多条件匹配

# 所有条件都必须满足(AND 关系)
spec:
  nodeSelector:
    disktype: ssd
    zone: east
    gpu: "true"
# 节点必须同时具有这三个标签

使用场景

1. 硬件要求
   - GPU 工作负载调度到 GPU 节点
   - 高性能计算调度到大内存节点

2. 环境隔离
   - 生产环境调度到专用节点
   - 测试环境调度到测试节点

3. 合规要求
   - 数据本地化(调度到特定区域)
   - 特定硬件要求

4. 成本优化
   - 使用 Spot 实例运行非关键工作负载

实践练习

练习 1:创建带标签的节点

# 给节点添加标签
kubectl label nodes node1 disktype=ssd
kubectl label nodes node1 zone=east
kubectl label nodes node2 disktype=hdd
kubectl label nodes node2 zone=west

# 验证标签
kubectl get nodes --show-labels

练习 2:使用 nodeSelector 调度

# pod-nodeselector.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-ssd
spec:
  nodeSelector:
    disktype: ssd
  containers:
  - name: nginx
    image: nginx
# 部署并验证
kubectl apply -f pod-nodeselector.yaml
kubectl get pod nginx-ssd -o wide
# 应该被调度到 node1(disktype=ssd)

练习 3:验证不匹配情况

# pod-nodeselector-fail.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-gpu
spec:
  nodeSelector:
    gpu: "true"
    disktype: ssd
    zone: north  # 不存在这个标签
  containers:
  - name: nginx
    image: nginx
# 部署并观察
kubectl apply -f pod-nodeselector-fail.yaml
kubectl get pod nginx-gpu
# 状态应该是 Pending

# 查看调度失败原因
kubectl describe pod nginx-gpu | grep -A 5 Events

练习 4:Deployment 中使用 nodeSelector

# deployment-nodeselector.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      nodeSelector:
        environment: production
      containers:
      - name: web
        image: nginx

nodeSelector 的局限性

1. 硬性约束
   - 必须匹配所有标签(AND 关系)
   - 不支持"偏好"或"软性"要求

2. 不支持复杂逻辑
   - 不支持 OR 条件
   - 不支持 NOT 条件
   - 不支持 in/notin 操作符

3. 缺乏灵活性
   - 无法表达"优先但不强制"
   - 无法指定权重

替代方案:
   - nodeAffinity:支持复杂逻辑和软性约束
   - podAffinity/podAntiAffinity:Pod 间亲和性

常见问题

1. Pod 一直 Pending

# 检查节点标签
kubectl get nodes --show-labels

# 检查 Pod 的 nodeSelector
kubectl get pod <pod-name> -o yaml | grep -A 5 nodeSelector

# 检查是否有匹配的节点
kubectl get nodes -l disktype=ssd,zone=east

2. 标签命名规范

# 标签键格式
prefix/name: value

# 示例
app.kubernetes.io/name: myapp
kubernetes.io/hostname: node1

# 规则:
# - 前缀可选,最多 253 字符
# - 名称最多 63 字符
# - 只能包含字母、数字、-、_、.
# - 值最多 63 字符

小结

要点说明
nodeSelector通过标签选择节点
匹配方式所有条件必须满足(AND)
使用场景硬件要求、环境隔离、合规要求
局限性只支持硬性约束,逻辑简单
替代方案nodeAffinity 支持更复杂的调度策略

练习编辑器

bash
Loading...

继续学习

完成本课后,建议继续学习下一课「节点亲和性」 以巩固所学知识。