① 背景与问题(解决了什么痛点)

在 Kubernetes 中,节点调度是一个核心功能。通过 nodeSelectoraffinitytoleration 等机制,我们可以控制 Pod 在哪些节点上运行。然而,在实际生产环境中,我们常常遇到一些复杂的调度场景,例如:

  • 某些节点因为硬件限制或特殊配置,无法承载某些类型的 Pod;
  • 需要对特定的节点状态进行更细粒度的控制,比如 GPU 可用性、网络延迟、磁盘类型等;
  • 现有的 toleration 机制在处理复杂节点条件时不够灵活,导致调度策略难以实现。

这些问题在 Kubernetes v1.34 及之前版本中较为突出。虽然已有 nodeSelectoraffinity 提供了基本的调度能力,但在面对更复杂的节点条件时,往往需要手动干预或编写自定义调度器,这增加了运维成本和复杂度。

Kubernetes v1.35 引入了一个重要的更新:扩展了 toleration 的 operator 支持新的 node conditions,使得我们可以在 toleration 中使用更丰富的节点状态判断逻辑,从而实现更加精细化的调度控制。

这个特性不仅提升了调度的灵活性,还简化了多维条件下的调度策略配置,是当前 Kubernetes 生态中一个非常实用的技术升级。


② 核心概念/技术原理

2.1 Toleration 与 Node Condition 的关系

在 Kubernetes 中,toleration 是用于容忍节点上某些不可满足的条件,让 Pod 能够被调度到这些节点上。例如,如果某个节点带有 node-role.kubernetes.io/control-plane 标签,那么默认情况下,普通 Pod 是不会被调度到该节点上的。但如果我们为 Pod 添加一个 toleration,就可以允许它被调度到该节点。

Kubernetes v1.35 扩展了 toleration 的 operator 支持,使其可以支持 新的 node condition 类型,如:

  • NodeSchedulable
  • NodeReady
  • NodeUnreachable
  • NodeDiskFull
  • NodeMemoryPressure
  • NodePIDPressure
  • NodeNetworkUnavailable

这意味着,我们可以根据节点的健康状态、资源压力、网络可用性等条件来更精细地控制 Pod 的调度行为。

2.2 新增的 Operator 行为

在 Kubernetes v1.35 前,tolerationoperator 支持以下几种:

  • Equal
  • Exists
  • NotEqual
  • DoesNotExist

从 v1.35 开始,新增了对 NodeCondition 的支持,可以通过 operator 来判断节点是否处于某种状态。例如:

toleration:
  key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoSchedule"

这条 toleration 表示:如果节点处于 unreachable 状态,则允许 Pod 被调度到该节点。

此外,还可以结合 value 字段进行更精确的匹配:

toleration:
  key: "node.kubernetes.io/network-unavailable"
  operator: "Equal"
  value: "true"
  effect: "NoSchedule"

表示只有当节点的 network-unavailable 条件为 true 时,才允许 Pod 被调度。

2.3 优势总结

  • 更加灵活的调度控制;
  • 减少对自定义调度器的依赖;
  • 提高了调度策略的可读性和可维护性;
  • 更好地适应多云、混合云环境中的复杂调度需求。

③ 实战案例/代码示例(重点章节,占比 40%)

3.1 场景一:基于节点网络状态的调度

在某些场景下,我们需要确保某些 Pod 只能运行在 网络可用性高的节点 上。例如,AI 推理服务可能对网络延迟非常敏感,因此需要避免部署到网络不稳定或不可达的节点。

3.1.1 配置示例
apiVersion: v1
kind: Pod
metadata:
  name: ai-inference-pod
spec:
  containers:
  - name: ai-container
    image: ai-model-server:latest
  tolerations:
  - key: "node.kubernetes.io/network-unavailable"
    operator: "Equal"
    value: "false"
    effect: "NoSchedule"

在这个配置中,Pod 会拒绝调度到任何 network-unavailabletrue 的节点上,从而保证其运行在网络稳定的节点上。

3.1.2 验证方式

你可以使用以下命令查看节点的状态:

kubectl describe node <node-name>

在输出中查找 Conditions 部分,确认是否有 NetworkUnavailable 条件。

3.1.3 多条件组合示例

你也可以组合多个条件,例如同时检查节点是否可调度且网络正常:

tolerations:
- key: "node.kubernetes.io/unreachable"
  operator: "DoesNotExist"
  effect: "NoSchedule"
- key: "node.kubernetes.io/network-unavailable"
  operator: "Equal"
  value: "false"
  effect: "NoSchedule"

这样,Pod 将只被调度到既不是 unreachable,也不是 network-unavailable 的节点上。


3.2 场景二:GPU 节点的专属调度

在 AI 训练任务中,通常需要使用 GPU 节点。然而,有些 Pod 可能不需要 GPU,但如果误调度到 GPU 节点上,可能会造成资源浪费。

Kubernetes v1.35 提供了对 node.kubernetes.io/gpu 条件的支持,我们可以利用这个条件来控制哪些 Pod 可以调度到 GPU 节点上。

3.2.1 配置示例
apiVersion: v1
kind: Pod
metadata:
  name: training-job
spec:
  containers:
  - name: training-container
    image: tensorflow-training:latest
  tolerations:
  - key: "node.kubernetes.io/gpu"
    operator: "Equal"
    value: "true"
    effect: "NoSchedule"

此配置表示:只有当节点的 gpu 条件为 true 时,Pod 才会被调度到该节点。

3.2.2 非 GPU 节点的隔离

对于不需要 GPU 的应用,可以设置反向 toleration:

tolerations:
- key: "node.kubernetes.io/gpu"
  operator: "NotEqual"
  value: "true"
  effect: "NoSchedule"

这样,非 GPU 节点就不会被选中作为该 Pod 的运行位置。


3.3 场景三:基于节点资源压力的调度

有时候,我们希望某些关键任务优先运行在资源压力较小的节点上。例如,数据库服务应避免运行在内存或 PID 压力较大的节点上。

3.3.1 配置示例
tolerations:
- key: "node.kubernetes.io/memory-pressure"
  operator: "DoesNotExist"
  effect: "NoSchedule"
- key: "node.kubernetes.io/pid-pressure"
  operator: "DoesNotExist"
  effect: "NoSchedule"

此配置表示:Pod 不会被调度到处于内存压力或 PID 压力状态的节点上。

3.3.2 验证方式

你可以使用以下命令查看节点的资源压力情况:

kubectl get nodes
kubectl describe node <node-name>

Conditions 中查找 MemoryPressurePIDPressure 是否为 True


3.4 架构图说明

下面是一个简化的调度流程图,展示了 Kubernetes v1.35 中 toleration 与 node condition 的交互过程:

Pod Spec

Scheduler

Check Node Conditions

Apply Toleration Rules

Select Suitable Node

Schedule Pod

此流程表明,调度器会根据 toleration 的规则,结合节点的当前状态(如 memory pressure、network status 等),最终决定将 Pod 调度到哪个节点。


④ 架构设计/方案对比

方案优点缺点适用场景
原始 nodeSelector简单易用不支持动态条件仅需按标签选择节点
affinity + nodeSelector支持多种选择逻辑配置较复杂需要多维度选择节点
toleration + node condition(v1.35)灵活、支持复杂条件需要熟悉新 API需要精细控制调度策略
自定义调度器完全可控高维护成本需要高度定制化调度逻辑

对比分析

  • nodeSelector 是最基础的调度方式,适合简单的标签匹配。
  • affinity 提供了更复杂的匹配逻辑,但仍然不支持动态条件。
  • toleration 在 v1.35 后引入了对 node condition 的支持,使得调度策略可以基于节点的实时状态进行调整,是目前最推荐的方式。
  • 自定义调度器虽然强大,但需要额外开发和维护,适用于有特殊需求的场景。

⑤ 优劣势评估/选型建议

5.1 优势

  • 灵活性提升:支持基于节点的多种状态(如网络、内存、PID 压力等)进行调度。
  • 减少对自定义调度器的依赖:无需开发额外调度逻辑即可实现复杂调度策略。
  • 提高调度准确性:通过更精确的条件判断,减少误调度风险。
  • 兼容性强:与现有调度机制无缝集成,无需重构现有架构。

5.2 劣势

  • 学习成本:需要理解 node condition 的含义和使用方式。
  • 配置复杂度增加:相比之前的 toleration 机制,新的配置更复杂。
  • 调试难度上升:若配置错误,可能导致 Pod 无法调度,排查较为困难。

5.3 选型建议

场景推荐方案说明
简单标签匹配nodeSelector快速实现,适合小规模集群
多维度节点选择affinity + nodeSelector适用于中等复杂度的调度需求
精细化调度toleration + node condition(v1.35)适用于大规模、复杂环境下的调度控制
特殊调度需求自定义调度器适用于需要完全控制调度逻辑的场景

⑥ 总结与延伸

Kubernetes v1.35 的 Extended Toleration Operators 是一项非常实用的更新,它极大地增强了调度策略的灵活性和可控制性。通过引入对 node condition 的支持,我们可以在 toleration 中实现更细粒度的调度控制,从而更好地适配不同业务场景的需求。

在实际使用中,建议结合 node conditiontoleration 的组合,构建更加智能和高效的调度策略。同时,需要注意配置的准确性和调试的及时性,避免因配置错误导致 Pod 无法调度的问题。

未来,随着 Kubernetes 生态的持续发展,我们预计会有更多关于节点状态和调度策略的增强功能出现。建议关注官方文档和社区动态,及时掌握最新特性和最佳实践。


📌 附录:常用 Node Condition 列表

  • NodeSchedulable: 节点是否可调度
  • NodeReady: 节点是否处于 ready 状态
  • NodeUnreachable: 节点是否不可达
  • NodeDiskFull: 节点磁盘是否已满
  • NodeMemoryPressure: 节点内存是否不足
  • NodePIDPressure: 节点 PID 是否不足
  • NodeNetworkUnavailable: 节点网络是否不可用
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐