将自定义作业与 Kueue 集成

将自定义作业与 Kueue 集成。

Kueue 为多种作业类型内置了集成,包括 Kubernetes 批处理作业、MPIJob、RayJob 和 JobSet。

为类似作业的 CRD 添加 Kueue 附加集成有两种选择

  • 作为 Kueue 存储库的一部分
  • 编写外部控制器

本指南适用于 平台开发者,并介绍如何构建新的集成。集成应使用 Kueue 的 jobframework 包提供的 API 构建。这将简化开发,并确保如果社区广泛使用你的作业类型,你的控制器将被正确构建为核心内置集成。

需求概述

Kueue 使用 controller-runtime。我们建议在开始构建 Kueue 集成之前熟悉它和 Kubebuilder

无论您是在构建外部集成还是内置集成,您的主要任务如下

  1. 要使用 Kueue,您的自定义作业 CRD 应具有类似于 Kubernetes 作业中的suspend 字段 的暂停字段。该字段需要在 CRD 的spec 中,而不是其status 中,以便允许从 webhook 设置其值。您的 CRD 的主控制器必须通过暂停或取消暂停其拥有的资源来响应此字段值的变化。

  2. 您需要将 CRD 的 GroupVersionKind 注册到 Kueue 中作为集成。

  3. 您需要为您的 CRD 实例化 Kueue 的 jobframework 包的各个部分

    • 您需要为您的 CRD 实现 Kueue 的 GenericJob 接口
    • 您需要实例化一个 ReconcilerFactory 并将其注册到控制器运行时。
    • 您需要为您的 CRD 添加一个 +kubebuilder:rbac 指令,以便 Kueue 被允许管理它。
    • 您需要注册 webhook,这些 webhook 设置您的 CRD 实例中 suspend 字段的初始值,并在创建和更新操作中验证 Kueue 不变量。
    • 您需要为您的 CRD 实例化一个 Workload 索引器。

构建内置集成

首先,在 ./pkg/controller/jobs/ 中添加一个新文件夹来托管集成的实现。

以下是您可以从中学习的已完成的内置集成

注册

将框架名称添加到 controller_manager_config.yaml 中的 .integrations.frameworks

使用 kubebuilder 标记注释为你的 CRD 添加 RBAC 授权。

编写一个调用 jobframework RegisterIntegration() 函数的 go func init()

作业框架

在文件夹中的 mycrd_controller.go 文件中,实现 GenericJob 接口,以及框架定义的其他可选 接口

在文件夹中的 mycrd_webhook.go 文件中,提供调用 jobframework 中的帮助程序方法的 webhook,以设置创建的作业的初始暂停状态并验证不变量。

为控制器和 webhook 添加测试文件。你可以查看 ./pkg/controller/jobs/ 的其他子文件夹中的测试文件,了解如何实现它们。

调整构建系统

添加编译代码所需的依赖项。例如,使用 go get github.com/kubeflow/mpi-operator@0.4.0

更新 Makefile 以进行测试。

  • 添加将自定义作业的 CRD 复制到 Kueue 项目的命令。
  • 将自定义作业运算符 CRD 依赖项添加到 test-integration 中。

构建外部集成

以下是你可从中学习的已完成外部集成

注册

将框架的 GroupVersionKind 添加到 controller_manager_config.yaml 中的 .integrations.externalFrameworks

RBAC 增强

Kueue 需要获得、列出和监视 CRD 实例的权限。

如果您正在构建自定义 Kueue 部署,只需将 kubebuilder:rbac 注释添加到源代码文件(例如 integrationmanager.go)并重新生成清单。

如果您正在部署 Kueue 版本,请修改 charts/kueue/templates/rbac/role.yamlconfig/components/rbac/role.yaml 以添加所需的权限。

作业框架

将对 Kueue 的依赖项添加到您的 go.mod 中,导入 jobframework 并按上述说明使用它来创建控制器和 webhook 实现。在控制器的 main 函数中,实例化控制器运行时管理器并注册您的 webhook、索引器和控制器。

有关具体示例,请参阅 AppWrapper 控制器中的以下部分