中文内容
Kubernetes v1.35:扩展容忍度运算符以支持数值比较(Alpha)
许多生产 Kubernetes 集群会混合使用按需(更高 SLA)节点和竞价/可抢占(较低 SLA)节点,以便在维护关键工作负载可靠性的同时优化成本。平台团队需要一种安全的默认设置,使大多数工作负载远离有风险的容量,同时允许特定工作负载通过明确阈值选择加入,例如“我可以容忍故障概率最高为 5% 的节点”。
目前,Kubernetes 污点和容忍度可以匹配精确值或检查是否存在,但无法比较数值阈值。你需要创建离散的污点类别、使用外部准入控制器,或者接受不够理想的放置决策。
在 Kubernetes v1.35 中,我们将以 alpha 功能引入扩展容忍度运算符。此增强功能向 spec.tolerations 添加 Gt(大于)和 Lt(小于)运算符,从而支持基于阈值的调度决策,为基于 SLA 的放置、成本优化以及感知性能的工作负载分布开辟新的可能性。
容忍的演进
从历史上看,Kubernetes 支持两种主要的容忍运算符:
- Equal:如果键和值完全相等,则该容忍与污点匹配
- Exists:如果键存在,则该容忍与污点匹配,无论其值如何
虽然这些功能在分类场景中表现良好,但在数值比较方面仍有不足。从 v1.35 开始,我们正在弥补这一差距。
请考虑以下真实场景:
- SLA 要求:仅将高可用性工作负载调度到故障概率低于某一阈值的节点上
- 成本优化:允许对成本敏感的批处理作业在每小时成本超过特定值的更便宜节点上运行
- 性能保障:确保对延迟敏感的应用程序仅在磁盘 IOPS 或网络带宽高于最低阈值的节点上运行
如果没有数值比较运算符,集群运维人员不得不采用变通办法,例如创建多个离散的污点值,或使用外部准入控制器;这些方法既难以良好扩展,也无法提供基于动态阈值调度所需的灵活性。
你可能会想:NodeAffinity 已经支持数值比较运算符,为什么还要扩展 tolerations?虽然 NodeAffinity 在表达 Pod 偏好方面很强大,但 taints 和 tolerations 提供了关键的运维优势:
- 策略导向:NodeAffinity 是按 Pod 配置的,要求每个工作负载都显式选择避开有风险的节点。Taints 则反转了控制方式——节点声明其风险级别,只有具有匹配 tolerations 的 Pod 才能调度到那里。这提供了更安全的默认行为;除非大多数 Pod 明确选择加入,否则会避开 spot/preemptible 节点。
- 驱逐语义:NodeAffinity 不具备驱逐能力。Taints 支持带有 tolerationSeconds 的 NoExecute 效果,使运维人员能够在节点的 SLA 降级或竞价实例收到终止通知时腾空节点并驱逐 Pod。
- 运维易用性:集中式的节点侧策略与 disk-pressure 和 memory-pressure 等其他安全 taints 保持一致,使集群管理更加直观。
此增强保留了 taints 和 tolerations 广为理解的安全模型,同时支持基于阈值的放置,以实现感知 SLA 的调度。
引入 Gt 和 Lt 运算符
Kubernetes v1.35 为容忍度引入了两个新的运算符:
- Gt(大于):如果污点的数值大于容忍度的值,则该容忍度匹配
- Lt(小于):如果污点的数值小于容忍度的值,则该容忍度匹配
当一个 Pod 容忍带有 Lt 的污点时,它是在表示“我可以容忍该指标低于我的阈值的节点”。由于容忍度允许调度,该 Pod 可以在污点值大于容忍度值的节点上运行。可以这样理解:“我容忍高于我的最低要求的节点”。
这些运算符使用数值型污点值,使调度器能够基于连续指标而非离散类别做出复杂的放置决策。
注意:
Gt 和 Lt 运算符的数值必须是不带前导零的正 64 位整数。例如,"100" 是有效的,但 "0100"(带前导零)和 "0"(零值)不被允许。
Gt 和 Lt 运算符适用于所有污点效果:NoSchedule、NoExecute 和 PreferNoSchedule。
使用场景和示例
让我们探讨扩展容忍操作符如何解决现实中的调度挑战。
示例 1:具有 SLA 阈值的 Spot 实例保护
许多集群混合使用按需节点和 Spot/可抢占节点以优化成本。Spot 节点可显著节省成本,但故障率更高。你希望大多数工作负载默认避开 Spot 节点,同时允许特定工作负载在明确的 SLA 边界内选择使用。
首先,使用故障概率为竞价实例节点添加污点(例如,年故障率为 15%):
apiVersion: v1
kind: Node
metadata:
name: spot-node-1
spec:
taints:
- key: "failure-probability"
value: "15"
effect: "NoExecute"
按需节点的故障率要低得多:
apiVersion: v1
kind: Node
metadata:
name: ondemand-node-1
spec:
taints:
- key: "failure-probability"
value: "2"
effect: "NoExecute"
关键工作负载可以指定严格的 SLA 要求:
apiVersion: v1
kind: Pod
metadata:
name: payment-processor
spec:
tolerations:
- key: "failure-probability"
operator: "Lt"
value: "5"
effect: "NoExecute"
tolerationSeconds: 30
containers:
- name: app
image: payment-app:v1
该 Pod 只会被调度到 failure-probability 小于 5 的节点上(这意味着可以调度到故障率为 2% 的 ondemand-node-1,但不会调度到故障率为 15% 的 spot-node-1)。带有 tolerationSeconds: 30 的 NoExecute effect 表示,如果某个节点的 SLA 下降(例如,云服务提供商更改了污点值),该 Pod 将有 30 秒时间进行优雅终止,然后才会被强制驱逐。
同时,一个容错的批处理作业可以明确选择使用竞价实例:
apiVersion: v1
kind: Pod
metadata:
name: batch-job
spec:
tolerations:
- key: "failure-probability"
operator: "Lt"
value: "20"
effect: "NoExecute"
containers:
- name: worker
image: batch-worker:v1
该批处理作业可容忍故障概率高达 20% 的节点,因此它可以在按需节点和竞价节点上运行,在接受更高风险的同时最大化节省成本。
AI 和机器学习工作负载通常有特定的硬件要求。借助 Extended Toleration Operators,你可以创建 GPU 节点层级,并确保工作负载落在具备相应算力的硬件上。
使用 GPU 节点的计算能力评分对其添加污点:
apiVersion: v1
kind: Node
metadata:
name: gpu-node-a100
spec:
taints:
- key: "gpu-compute-score"
value: "1000"
effect: "NoSchedule"
---
apiVersion: v1
kind: Node
metadata:
name: gpu-node-t4
spec:
taints:
- key: "gpu-compute-score"
value: "500"
effect: "NoSchedule"
繁重的训练工作负载可能需要高性能 GPU:
apiVersion: v1
kind: Pod
metadata:
name: model-training
spec:
tolerations:
- key: "gpu-compute-score"
operator: "Gt"
value: "800"
effect: "NoSchedule"
containers:
- name: trainer
image: ml-trainer:v1
resources:
limits:
nvidia.com/gpu: 1
这可确保训练 Pod 只调度到计算评分高于 800 的节点(例如 A100 节点)上,避免被放置到会降低训练速度的低端 GPU 上。
与此同时,需求较低的推理工作负载可以使用任何可用的 GPU:
apiVersion: v1
kind: Pod
metadata:
name: model-inference
spec:
tolerations:
- key: "gpu-compute-score"
operator: "Gt"
value: "400"
effect: "NoSchedule"
containers:
- name: inference
image: ml-inference:v1
resources:
limits:
nvidia.com/gpu: 1
对于批处理或非关键工作负载,你可能希望通过在更便宜的节点上运行来最大限度降低成本,即使这些节点的性能特征较低。
节点可以用其成本评级进行污点标记:
spec:
taints:
- key: "cost-per-hour"
value: "50"
effect: "NoSchedule"
成本敏感型批处理作业可以表达其对高成本节点的容忍度:
tolerations:
- key: "cost-per-hour"
operator: "Lt"
value: "100"
effect: "NoSchedule"
该批处理作业将调度到成本低于 100 美元/小时的节点上,但会避开更昂贵的节点。结合 Kubernetes 调度优先级,这可以实现复杂的成本分层策略,使关键工作负载使用高端节点,而批处理工作负载高效利用经济型资源。
示例 4:基于性能的放置
存储密集型应用通常需要最低磁盘性能保障。借助 Extended Toleration Operators,你可以在调度层面强制执行这些要求。
tolerations:
- key: "disk-iops"
operator: "Gt"
value: "3000"
effect: "NoSchedule"
此容忍度可确保该 Pod 仅调度到 disk-iops 超过 3000 的节点上。Gt 运算符表示“我需要大于此最低值的节点”。
如何使用此功能
Extended Toleration Operators 是 Kubernetes v1.35 中的 alpha 功能。要试用它:
- 在 API server 和 scheduler 上启用该功能门控:--feature-gates = TaintTolerationComparisonOperators = true
- 使用表示与你的调度需求相关指标的数值来为节点添加污点:kubectl taint nodes node-1 failure-probability = 5:NoSchedule kubectl taint nodes node-2 disk-iops = 5000:NoSchedule
- 在你的 Pod 规范中使用新的运算符:spec : tolerations : - key : "failure-probability" operator : "Lt" value : "1" effect : "NoSchedule"
注意:
As an alpha feature, Extended Toleration Operators may change in future releases and should be used with caution in production environments. Always test thoroughly in non-production clusters first.接下来是什么?
这个 alpha 版本只是一个开始。随着我们收集社区的反馈,我们计划:
- 在容忍度和节点亲和性中添加对 CEL(Common Expression Language)表达式的支持,以实现更加灵活的调度逻辑,包括语义版本比较
- 改进与集群自动扩缩容的集成,以支持具备阈值感知能力的容量规划
- 将该功能推进到 beta 阶段,并最终以生产就绪的稳定性达到 GA。
我们特别希望了解您的使用场景!您是否有一些场景可以通过基于阈值的调度来解决问题?您希望看到其他运算符或功能吗?
参与其中
该功能由 SIG Scheduling 社区推动。欢迎加入我们,与社区建立联系,并分享您关于该功能及其他方面的想法和反馈。
你可以通过以下方式联系此功能的维护者:
- Slack:Kubernetes Slack 上的 #sig-scheduling
- 邮件列表:kubernetes-sig-scheduling@googlegroups.com
如有与 Extended Toleration Operators 相关的问题或具体咨询,请联系 SIG Scheduling 社区。我们期待收到你的消息!
我怎样才能了解更多?
- 污点和容忍度,用于了解基础知识
- 数值比较运算符,了解使用 Gt 和 Lt 运算符的详细信息
- KEP-5471:用于基于阈值放置的扩展容忍度运算符
- ← 上一页
- 下一页 →