掌握节点调度的核心机制:nodeSelector、nodeName、Affinity 和 Tolerations

Kubernetes Pod 调度概述

在 Kubernetes 中,Pod 调度是一个至关重要的功能,它决定了 Pod 在集群中的哪个节点上运行。合理的调度策略能够优化资源利用率、提高应用性能并确保系统稳定性。

Kubernetes 调度器负责根据资源需求、策略和约束条件,自动将 Pod 分配到合适的节点上。当需要更精细的控制时,可以使用以下四种主要调度机制:

调度流程

1. 创建 Pod 时,用户可以通过各种机制指定调度偏好

2. 调度器过滤掉不满足条件的节点

3. 调度器对剩余节点进行评分

4. 选择得分最高的节点运行 Pod

nodeSelector:基础节点选择器

nodeSelector 是 Kubernetes 中最简单的节点调度方式,它允许您通过节点标签来选择特定的节点。

使用方式

pod-nodeSelector.yaml复制代码

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
  nodeSelector:
    disktype: ssd
    environment: production

工作原理

  • 为节点添加标签:kubectl label nodes <node-name> disktype=ssd
  • Pod 只会被调度到具有匹配标签的节点上
  • 如果没有任何节点拥有匹配的标签,Pod 将保持 Pending 状态

注意: nodeSelector 提供的是"硬性"要求,必须完全匹配所有指定的标签。

nodeName:直接指定节点

nodeName 是更为直接的调度方式,它明确指定 Pod 应该运行在哪个节点上。

使用方式

pod-nodeName.yaml复制代码

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
  nodeName: k8s-node-1

注意事项

  • 绕过正常的调度器,直接指定目标节点
  • 如果指定的节点不存在或资源不足,Pod 将无法运行
  • 通常用于测试或特定场景,生产环境中应谨慎使用

注意: 使用 nodeName 会绕过调度器的所有过滤和评分逻辑,可能导致资源利用不均衡。

Affinity:高级亲和性调度

节点亲和性(Affinity)提供了比 nodeSelector 更强大的调度能力,支持更复杂的调度规则。

节点亲和性类型

硬亲和性(Required)

pod-affinity-required.yaml复制代码

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
            - nvme
  containers:
  - name: nginx
    image: nginx:1.14.2
软亲和性(Preferred)

pod-affinity-preferred.yaml复制代码

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: environment
            operator: In
            values:
            - production
  containers:
  - name: nginx
    image: nginx:1.14.2

操作符类型

  • In:标签值在列表中
  • NotIn:标签值不在列表中
  • Exists:标签存在
  • DoesNotExist:标签不存在
  • Gt:标签值大于指定值(用于数值)
  • Lt:标签值小于指定值(用于数值)

提示: 亲和性规则还支持 Pod 间亲和性和反亲和性,用于控制 Pod 之间的部署关系。

Tolerations:容忍度机制

容忍度(Tolerations)允许 Pod 调度到带有污点(Taints)的节点上,与节点的污点机制配合使用。

污点和容忍度的工作机制

首先为节点添加污点:

命令复制代码

kubectl taint nodes node1 key=value:NoSchedule

然后在 Pod 中配置容忍度:

pod-tolerations.yaml复制代码

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"

污点效果类型

  • NoSchedule:不会调度新 Pod(已运行的不受影响)
  • PreferNoSchedule:尽量避免调度
  • NoExecute:不会调度新 Pod,且会驱逐已运行的 Pod

高级容忍度配置

pod-tolerations-advanced.yaml复制代码

tolerations:
- key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 6000
- key: "dedicated"
  operator: "Equal"
  value: "gpu"
  effect: "NoSchedule"

注意: 容忍度不会保证 Pod 一定会被调度到有污点的节点上,只是允许这种可能性。

调度机制对比

机制使用场景优点缺点
nodeSelector简单的标签匹配简单易用,配置直观功能有限,只支持硬性要求
nodeName直接指定节点完全控制 Pod 位置绕过调度器,可能导致资源不均
Affinity复杂的调度需求功能强大,支持软硬规则配置相对复杂
Tolerations专用节点或故障隔离与污点配合实现节点专用需要与污点配合使用

更多推荐