本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
介绍 Suspended Jobs
Jobs 是 Kubernetes API 的一个重要组成部分。虽然其他类型的工作负载,例如 Deployments、ReplicaSets、StatefulSets 和 DaemonSets 解决了需要 Pod 永久运行的用例,但当 Pod 需要运行完成时,Jobs 非常有用。Jobs 通常用于并行批处理,可用于各种应用程序,从视频渲染和数据库维护到发送批量电子邮件和科学计算。
虽然 Job 完成的并行度和条件是可配置的,但 Kubernetes API 缺乏暂停和恢复 Job 的能力。当集群资源有限,并且更高优先级的 Job 需要取代另一个 Job 执行时,通常需要这种能力。删除低优先级的 Job 是一种糟糕的变通方法,因为 Pod 完成历史记录和与 Job 相关的其他指标都将丢失。
随着 Kubernetes 1.21 版本的发布,您将能够通过更新 Job 的 spec 来暂停 Job。该功能目前处于 alpha 阶段,需要您在 API 服务器和 控制器管理器上启用 SuspendJob
Feature Gate 才能使用它。
API 变更
我们在 Job 的 .spec
中引入了一个新的布尔字段 suspend
。假设我创建了以下 Job:
apiVersion: batch/v1
kind: Job
metadata:
name: my-job
spec:
suspend: true
parallelism: 2
completions: 10
template:
spec:
containers:
- name: my-container
image: busybox
command: ["sleep", "5"]
restartPolicy: Never
默认情况下,Jobs 不会暂停,因此我在上述 Job 清单的 .spec
中明确将 suspend
字段设置为 true。在上面的示例中,Job 控制器将避免创建 Pod,直到我准备好启动 Job,我可以通过将 suspend
更新为 false 来实现。
再举一个例子,考虑一个创建时省略了 suspend
字段的 Job。Job 控制器将乐于创建 Pod 以完成 Job。但是,在 Job 完成之前,如果我通过 Job 更新将该字段明确设置为 true,Job 控制器将终止所有正在运行的活跃 Pod,并将无限期地等待该标志翻转回 false。通常,Pod 终止是通过向 Pod 中的所有容器进程发送 SIGTERM 信号来完成的;Pod spec 中定义的优雅终止期将得到遵守。以这种方式终止的 Pod 不会被 Job 控制器计为失败。
重要的是要理解,暂停 Job 后,过去已成功和失败的 Pod 将继续存在。也就是说,一旦您恢复 Job,它们将计入 Job 的完成。您可以通过查看暂停前后 Job 的状态来验证这一点。
阅读文档以全面了解此新功能。
这有什么用?
假设我是一个大型集群的运营商。我有许多用户向集群提交 Jobs,但并非所有 Jobs 都是平等的——有些 Jobs 比其他 Jobs 更重要。集群资源也不是无限的,因此所有用户都必须共享资源。如果所有 Jobs 都以暂停状态创建并放入待处理队列中,我可以通过按正确顺序恢复 Jobs 来实现基于优先级的 Job 调度。
另一个激励性的用例是,考虑一个云计算提供商,其计算资源在晚上比早上便宜。如果我有一个需要多天才能完成的长时间运行的 Job,每天早上暂停 Job,然后在晚上恢复 Job 可以降低成本。
由于此字段是 Job 规范的一部分,因此 CronJobs 也自动免费获得了此功能。
参考资料和下一步
如果您对该功能背后的原理和我们所做的决定感兴趣,可以阅读增强提案。有关Job文档中暂停和恢复 Job 的更多详细信息。
如前所述,此功能目前处于 alpha 阶段,仅当您通过 SuspendJob
功能门明确选择启用时才可用。如果您对此功能感兴趣,请考虑在您的集群中测试暂停的 Job 并提供反馈。您可以在 GitHub 上讨论此增强功能。SIG Apps 社区也定期开会,可以通过 Slack 或邮件列表联系。除非 API 发生意外更改,否则我们打算在 Kubernetes 1.22 中将该功能升级到 beta 版,以便该功能默认可用。