K8S 1.26 这个新特性,支持大规模并行批处理工作负载
关注公众号并添加到“星标⭐”,防止错过消息
后台回复【资料包】获取学习资料
Kubernetes 1.26 版本包括一个稳定的 Job[1] 控制器实现,可以可靠地跟踪大量具有高并行度的作业。自 Kubernetes 1.22 以来, SIG Apps[2] 和WG Batch[3] 一直致力于这项基础改进。经过多次迭代和规模验证,现在这是 Job 控制器的默认实现。
与 Indexed completion mode[4]配合使用,Job controller 可以处理大规模并行批处理作业,支持多达 100k 个并发 Pod。
新的实现还使Pod 故障策略[5]的开发成为可能,该策略在 1.26 版本中处于 beta 阶段。
如何使用此功能?
要将作业跟踪与终结器一起使用,请升级到 Kubernetes 1.25 或更新版本并创建新作业。如果您有能力启用JobTrackingWithFinalizers
feature gate[6] ,您也可以在 v1.23 和 v1.24 中使用此功能。
如果您的集群运行 Kubernetes 1.26,则使用终结器进行作业跟踪是一项稳定的功能。对于 v1.25,它位于功能门之后,您的集群管理员可能已明确禁用它 - 例如,如果您有不使用 beta 功能的策略。
升级前创建的作业仍将使用旧行为进行跟踪。这是为了避免向正在运行的 Pod 追溯添加终结器,这可能会引入竞争条件。
为了在大型作业上获得最佳性能,Kubernetes 项目建议使用Indexed completion mode[7]。在这种模式下,控制平面能够通过较少的 API 调用来跟踪作业进度。
如果您是批处理、HPC[8]、 AI[9]、ML[10] 或相关工作负载的运算符开发人员,我们鼓励您使用 Job API 将准确的进度跟踪委托给 Kubernetes。如果 Job API 中缺少某些东西迫使您管理普通 Pod,Working Group Batch[11] 欢迎您提供反馈和贡献。
弃用通知
在该功能的开发过程中,控制平面将注释添加 `batch.kubernetes.io/job-tracking`[12] 到启用该功能时创建的作业中。
在 1.26 版本中,我们弃用了注解batch.kubernetes.io/job-tracking
,控制平面将停止在 Kubernetes 1.27 中添加它。随着这一变化,我们将删除遗留的作业跟踪实施。因此,Job 控制器将跟踪所有使用终结器的 Job,它会忽略没有上述终结器的 Pod。
在将集群升级到 1.27 之前,我们建议您确认没有 annotation 的正在运行的作业,或者等待这些作业完成。否则,您可能会观察到控制平面重新创建了一些 Pod。我们希望这不会影响任何用户,因为该功能自 Kubernetes 1.25 以来默认启用,为旧作业提供足够的缓冲区来完成。
新的实施解决了什么问题?
通常,Kubernetes 工作负载控制器(例如 ReplicaSet 或 StatefulSet)依赖于 Pod 或 API 中其他对象的存在来确定工作负载的状态以及是否需要替换。例如,如果属于 ReplicaSet 的 Pod 终止或不复存在,ReplicaSet 控制器需要创建一个替换 Pod 以满足所需的副本数 ( .spec.replicas
)。
从一开始,Job 控制器也依赖 API 中 Pod 的存在来跟踪 Job 状态。Job 有完成[13] 和失败处理[14] 策略,需要完成的 Pod 的结束状态来确定是否创建替换 Pod 或将 Job 标记为已完成或失败。因此,Job 控制器依赖于 Pod,甚至是终止的 Pod,以保留在 API 中以跟踪状态。
这种依赖性使得对 Job 状态的跟踪变得不可靠,因为可以出于多种原因从 API 中删除 Pod,包括:
垃圾收集器在节点宕机时移除孤立的 Pod。 垃圾收集器在达到阈值时移除已终止的 Pod。 Kubernetes 调度程序抢占 Pod 以容纳更高优先级的 Pod。 污点管理器驱逐一个不能容忍 NoExecute
污点的 Pod。外部控制器,不包含在 Kubernetes 中,或人工删除 Pod。
新的实施
当控制器需要在删除对象之前对对象采取操作时,它应该 向它管理的对象添加终结器。[15]终结器可防止对象从 API 中删除,直到移除终结器为止。一旦控制器完成清理并记录已删除的对象,它就可以从对象中删除终结器,并且控制平面从 API 中删除对象。
这就是新的 Job 控制器正在做的事情:在 Pod 创建期间添加终结器,并在 Pod 终止并在 Job 状态中说明后删除终结器。然而,事情并没有那么简单。
主要的挑战是至少涉及两个对象:Pod 和 Job。虽然终结器存在于 Pod 对象中,但执行状态存在于 Job 对象中。没有任何机制可以自动删除 Pod 中的终结器并更新 Job 状态中的计数器。此外,在给定的时间可能有多个终止的 Pod。
为了解决这个问题,我们实施了一个三阶段的方法,每个阶段都转化为一个 API 调用。
对于每个终止的 Pod,将 Pod 的唯一 ID (UID) 添加到存储在拥有作业的 .status
( .status.uncountedTerminatedPods[16] )中的列表中。从 Pod 中移除终结器。 原子地执行以下操作:
从列表中删除 UID 在作业的 status
中增加succeeded
和failed
计数器总数。
作业控制器可能会在第 1 步和第 2 步中乱序接收 API 更改的结果,从而使问题更加复杂。我们通过为删除的终结器添加内存缓存来解决这个问题。
尽管如此,我们在测试阶段仍然遇到了一些问题,在某些情况下,一些 pod 会被终结器卡住(#108645[17]、 #109485[18]和 #111646[19])。因此,我们决定将 1.23 和 1.24 版本的功能门控切换为默认禁用。
解决后,我们重新启用了 1.25 版本的功能。从那时起,我们收到了客户通过 Job API 在他们的集群中同时运行数万个 Pod 的报告。看到这一成功,我们决定在 1.26 中将该功能升级到稳定版,作为我们长期承诺的一部分,使 Job API 成为在 Kubernetes 集群中运行大批量作业的最佳方式。
要了解有关该功能的更多信息,您可以阅读KEP[20]。
参考资料
Job: https://kubernetes.io/docs/concepts/workloads/controllers/job/
[2]自 Kubernetes 1.22 以来, SIG Apps: https://github.com/kubernetes/community/tree/master/sig-apps
[3]WG Batch: https://github.com/kubernetes/community/tree/master/wg-batch
[4]completion mode: https://kubernetes.io/docs/concepts/workloads/controllers/job/#completion-mode
[5]Pod 故障策略: https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-failure-policy
[6]feature gate: https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/
[7]Indexed completion mode: https://kubernetes.io/docs/concepts/workloads/controllers/job/#completion-mode
[8]HPC: https://en.wikipedia.org/wiki/High-performance_computing
[9]AI: https://en.wikipedia.org/wiki/Artificial_intelligence
[10]ML: https://en.wikipedia.org/wiki/Machine_learning
[11]Working Group Batch: https://github.com/kubernetes/community/tree/master/wg-batch
[12]batch.kubernetes.io/job-tracking
: https://kubernetes.io/docs/reference/labels-annotations-taints/#batch-kubernetes-io-job-tracking
完成: https://kubernetes.io/docs/concepts/workloads/controllers/job/#completion-mode
[14]失败处理: https://kubernetes.io/docs/concepts/workloads/controllers/job/#handling-pod-and-container-failures
[15]终结器。: https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/
[16].status.uncountedTerminatedPods: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/job-v1/#JobStatus
[17]#108645: https://github.com/kubernetes/kubernetes/issues/108645
[18]#109485: https://github.com/kubernetes/kubernetes/issues/109485
[19]#111646: https://github.com/kubernetes/kubernetes/pull/111646
[20]KEP: https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/2307-job-tracking-without-lingering-pods
作者: Aldo Culquicondor
出处: https://goo.gs/iz1ht译者: #公众号: 进击云原生
后台回复“加群”,带你进入高手交流群
Kubernetes 1.26 正式发布,所有变化都在这儿了!
Docker Desktop 4.15 正式发布,这些新功能值得看
图解 K8S 1.26 新功能 Pod 调度就绪特性解析
16 张图实战 Prometheus 自定义告警规则Kubernetes 1.26 中更简单的准入控制实战
云原生年终强势总结,这套资料简直是K8s/Docker/DevOps的命脉
开源网关 Apache APISIX 认证鉴权精细化实战讲解
保姆级 Prometheus PromQL 讲解与实战操作
38 张图硬核高性能服务器架构设计与调优
20 张图详细理清 K8S Istio Gateway 与实战操作
GitOps 新手入门到专家进阶实战详细教程
8 张图详解 Prometheus AlertManager 实战操作
6 张配图通俗易懂说透 K8S 请求和限制
提高 K8S 监控可观察性最佳方式实战教程Kubernetes 1.26 中的删除、弃用和主要更改46 张图详解 Zabbix 分布式监控平台建设
这 11 张图把 K8S 权限认证说的很清楚了
10 张图解 K8S CNI Calico 网络模型原理与功能实战19 张图详解 Rsync 远程同步K8S 1.25 中的重大更改和删除18 张图 Java 容器化最佳实践总结17 张图实战 + 理清 K8S 网络排错思路,硬核!16 张图硬核讲解 Kubernetes 网络模型