将自定义 Job 与 Kueue 集成
Kueue 为多种 Job 类型提供了内置集成,包括 Kubernetes batch Job、MPIJob、RayJob 和 JobSet。
使用 Kueue 管理缺乏内置集成的类 Job CRD 有三种选择:
- 通过将自定义 Job 实例包装在 AppWrapper 中来利用内置的 AppWrapper 集成。 详情请参阅运行包装的自定义工作负载。
- 作为 Kueue 仓库的一部分构建新的集成。
- 作为外部控制器构建新的集成。
本指南面向平台开发者,描述如何构建新的集成。
集成应该使用 Kueue 的 jobframework
包提供的 API 来构建。
这既会简化开发,也会确保如果你的 Job 类型被社区广泛使用,
你的控制器将被正确构造以成为核心内置集成。
需求概览
Kueue 使用 controller-runtime。 我们建议在开始构建 Kueue 集成之前,先熟悉它和 Kubebuilder。
无论你是构建外部集成还是内置集成,你的主要任务如下:
要与 Kueue 配合工作,你的自定义 Job CRD 应该有一个类似暂停的字段, 其语义类似于 Kubernetes Job 中的
suspend
字段。 该字段需要在你的 CRD 的spec
中,而不是在其status
中, 以便可以从 webhook 设置其值。你的 CRD 的主控制器必须响应此字段值的更改, 通过暂停或恢复其拥有的资源。你需要将你的 CRD 的 GroupVersionKind 注册为 Kueue 的集成。
你需要为你的 CRD 实例化 Kueue 的
jobframework
包的各个部分:- 你需要为你的 CRD 实现 Kueue 的
GenericJob
接口 - 你需要实例化一个
ReconcilerFactory
并将其注册到 controller runtime。 - 你需要为你的 CRD 添加
+kubebuilder:rbac
指令,以便 Kueue 被允许管理它。 - 你需要注册 webhook,在你的 CRD 实例中设置
suspend
字段的初始值, 并在创建和更新操作时验证 Kueue 不变量。 - 你需要为你的 CRD 实例化一个
Workload
索引器。
- 你需要为你的 CRD 实现 Kueue 的
构建内置集成
首先,在 ./pkg/controller/jobs/
中添加一个新文件夹来承载集成的实现。
以下是你可以学习的已完成的内置集成:
注册
在 controller_manager_config.yaml
的 .integrations.frameworks
中添加你的框架名称。
使用 kubebuilder 标记注释 为你的 CRD 添加 RBAC 授权。
编写一个调用 jobframework RegisterIntegration()
函数的 go func init()
。
Job Framework
在你的文件夹中的 mycrd_controller.go
文件中,实现 GenericJob
接口,
以及框架定义的其他可选接口。
在你的文件夹中的 mycrd_webhook.go
文件中,提供调用 jobframework 中的辅助方法的 webhook,
以设置创建的作业的初始暂停状态并验证不变量。
为控制器和 webhook 添加测试文件。你可以查看 ./pkg/controller/jobs/
其他子文件夹中的测试文件来学习如何实现它们。
开发变更和验证 webhook
一旦你实现了 GenericJob
接口,你可以通过使用 pkg/controller/jobframework
中的 BaseWebhookFactory
为该类型注册 webhook。此 webhook 确保作业在暂停状态下创建,
并且队列名称在作业被准入时不会更改。你可以阅读
MPIJob
集成作为示例。
对于某些用例,你可能需要注册专用的 webhook。在这种情况下,你应该使用
Kueue 的 LosslessDefaulter
,它确保默认器与 CRD 的未来版本兼容,
前提是默认器不会从原始对象中删除任何字段。你可以阅读
BatchJob
集成作为如何使用 LosslessDefaulter
的示例。
如果上述建议与你的用例不兼容,请注意 使用 controller-runtime 的 CustomDefaulter 时的潜在问题。
调整构建系统
添加编译代码所需的依赖项。例如,使用 go get github.com/kubeflow/mpi-operator@0.4.0
。
更新 Makefile 进行测试。
- 添加将你的自定义作业的 CRD 复制到 Kueue 项目的命令。
- 将你的自定义作业操作器 CRD 依赖项添加到
test-integration
中。
构建外部集成
构建外部集成类似于构建内置集成,
不同之处在于你将在单独的可执行文件中为你的 CRD 实例化 Kueue 的 jobframework
。
你对主要 Kueue 管理器所做的唯一更改是部署时配置更改,
以使其能够识别你的 CRD 正在由与 Kueue 兼容的管理器管理。
以下是你可以学习的已完成的外部集成:
注册
通过将你的框架的 GroupVersionKind 添加到
controller_manager_config.yaml
的 .integrations.externalFrameworks
中来配置 Kueue。
Job Framework
对你的 CRD 的现有基于 controller-runtime 的管理器进行以下更改。
在你的 go.mod
中添加对 Kueue 的依赖项,以便你可以将 jobframework
作为 go 库导入。
在新的 mycrd_workload_controller.go
文件中,实现 GenericJob
接口,
以及框架定义的其他可选接口。
扩展你的 CRD 的现有 webhook 以调用 Kueue 的 webhook 辅助方法:
- 你的默认器应该调用 defaults.go
中的
jobframework.ApplyDefaultForSuspend
- 你的验证器应该调用 validation.go
中的
jobframework.ValidateJobOnCreate
和jobframework.ValidateJobOnUpdate
扩展你的管理器的启动程序以执行以下操作:
- 使用
jobframework.NewGenericReconcilerFactory
方法, 为你的 CRD 创建 Kueue 的 JobReconciler 实例并将其注册到 controller-runtime 管理器。 - 调用
jobframework.SetupWorkloadOwnerIndex
为你的 CRD 拥有的 Workload 创建索引器。
扩展你现有的 RBAC 授权以包括 Kueue 的 JobReconciler 所需的权限:
// +kubebuilder:rbac:groups=scheduling.k8s.io,resources=priorityclasses,verbs=list;get;watch
// +kubebuilder:rbac:groups="",resources=events,verbs=create;watch;update;patch
// +kubebuilder:rbac:groups=kueue.x-k8s.io,resources=workloads,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=kueue.x-k8s.io,resources=workloads/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=kueue.x-k8s.io,resources=workloads/finalizers,verbs=update
// +kubebuilder:rbac:groups=kueue.x-k8s.io,resources=resourceflavors,verbs=get;list;watch
// +kubebuilder:rbac:groups=kueue.x-k8s.io,resources=workloadpriorityclasses,verbs=get;list;watch
有关具体示例,请参考 AppWrapper 控制器的以下部分:
反馈
这个页面有帮助吗?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.