从 v1 迁移到 v2

在继续之前,请务必了解 Kubebuilder v1 和 v2 之间的差异

请确保您已按照安装指南安装所需的组件。

推荐的迁移 v1 项目的方法是创建一个新的 v2 项目,并复制 API 和调整代码。转换后将得到一个看起来像原生 v2 项目的项目。然而,在某些情况下,也可以进行就地升级(即重用 v1 项目布局,升级 controller-runtime 和 controller-tools)。

我们以一个 V1 项目为例,将其迁移到 Kubebuilder v2。最后,我们应该得到的项目应该类似于 示例 v2 项目

准备

我们需要搞清楚组、版本、类型和域是什么。

让我们来看看我们当前的 v1 项目结构:

pkg/
├── apis
│   ├── addtoscheme_batch_v1.go
│   ├── apis.go
│   └── batch
│       ├── group.go
│       └── v1
│           ├── cronjob_types.go
│           ├── cronjob_types_test.go
│           ├── doc.go
│           ├── register.go
│           ├── v1_suite_test.go
│           └── zz_generated.deepcopy.go
├── controller
└── webhook

我们所有的 API 信息都存储在 pkg/apis/batch 中,因此我们可以在那儿找到我们需要了解的内容。

cronjob_types.go 文件中,我们可以找到

type CronJob struct {...}

register.go 中,我们可以找到

SchemeGroupVersion = schema.GroupVersion{Group: "batch.tutorial.kubebuilder.io", Version: "v1"}

将这些组合在一起,我们得到 CronJob 作为类型,batch.tutorial.kubebuilder.io/v1 作为组版本。

初始化一个 v2 项目

现在,我们需要初始化一个 v2 项目。不过,在此之前,如果我们不在 gopath 上,我们需要先初始化一个新的 Go 模块:

go mod init tutorial.kubebuilder.io/project

那么,我们可以使用 kubebuilder 完成项目的初始化:

kubebuilder init --domain tutorial.kubebuilder.io

迁移 API 和控制器

接下来,我们将重新搭建 API 类型和控制器。由于我们都需要这两者,因此在被询问要搭建哪些部分时,我们将对 API 和控制器的提示都选择“是“。

kubebuilder create api --group batch --version v1 --kind CronJob

如果您正在使用多个组,则需要进行一些手动操作来进行迁移。有关更多详细信息,请查看 此链接

迁移API

现在,让我们将 pkg/apis/batch/v1/cronjob_types.go 中的 API 定义复制到 api/v1/cronjob_types.go。我们只需要复制 SpecStatus 字段的实现。

我们可以用 +kubebuilder:object:root=true 来替换 +k8s:deepcopy-gen:interfaces=... 标记(该标记在 kubebuilder 中已被弃用)。

我们不再需要以下标记(它们不再使用,是早期版本的 Kubebuilder 的遗留物):

// +生成客户端
// +k8s:openapi-gen=true

我们的API类型应该如下所示:

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// CronJob 是 cronjobs API 的模式
type CronJob struct {...}

// +kubebuilder:object:root=true

// CronJobList 包含一个 CronJob 列表
type CronJobList struct {...}

迁移控制器

现在,让我们将控制器调整器代码从 pkg/controller/cronjob/cronjob_controller.go 迁移到 controllers/cronjob_controller.go

我们需要进行复制。

  • ReconcileCronJob 结构体中的字段迁移到 CronJobReconciler
  • Reconcile 函数的内容
  • rbac 相关标记 添加到新文件中。
  • 将以下代码从 func add(mgr manager.Manager, r reconcile.Reconciler) error 更改为 func SetupWithManager

迁移 Webhooks

如果您没有 webhook,可以跳过这一部分。

核心类型和外部 CRD 的 Webhook

如果您正在为 Kubernetes 核心类型(例如 Pods)或不属于您的外部 CRD 使用 webhook,您可以参考 controller-runtime 的内置类型示例 并进行类似的操作。Kubebuilder 在这些情况下不会生成很多内容,但您可以使用 controller-runtime 中的库。

为我们的自定义资源定义(CRD)搭建 Webhooks。

现在让我们为我们的 CRD(CronJob)搭建 Webhook。我们需要使用 --defaulting--programmatic-validation 标志运行以下命令(因为我们的测试项目使用了默认值和验证 Webhook):

kubebuilder create webhook --group batch --version v1 --kind CronJob --defaulting --programmatic-validation

根据需要多少个 CRD(自定义资源定义)使用 Webhook,我们可能需要多次运行上述命令,并使用不同的组-版本-类型。

现在,我们需要为每个 webhook 复制逻辑。对于验证 webhook,我们可以将 pkg/default_server/cronjob/validating/cronjob_create_handler.go 中的 func validatingCronJobFn 的内容复制到 api/v1/cronjob_webhook.go 中的 func ValidateCreate,然后更新操作也可以同样处理。

类似地,我们将从 func mutatingCronJobFn 复制到 func Default

Webhook 标记

在搭建 webhooks 时,Kubebuilder v2 添加了以下标记:

`默认的动词是 verbs=create;update。我们需要确保 verbs与我们的需求相匹配。例如,如果我们只想验证创建,就需要将其更改为verbs=create`。

我们还需要确保 failure-policy 仍然保持不变。

以下标记不再需要(因为它们涉及自我部署证书配置,而该配置在 v2 中已被移除):

// v1 标记
// +kubebuilder:webhook:port=9876,cert-dir=/tmp/cert
// +kubebuilder:webhook:service=test-system:webhook-service,selector=app:webhook-server
// +kubebuilder:webhook:secret=test-system:webhook-server-secret
// +kubebuilder:webhook:mutating-webhook-config-name=test-mutating-webhook-cfg
// +kubebuilder:webhook:validating-webhook-config-name=test-validating-webhook-cfg

在 v1 中,一个 webhook 标记可能在同一段落中拆分成多个标记。在 v2 中,每个 webhook 必须由一个单独的标记表示。

其他人

如果在 v1 的 main.go 中有任何手动更新,我们需要将这些更改移植到新的 main.go 中。我们还需要确保所有所需的方案已经注册。

如果在 config 目录下添加了其他清单,也将它们移植过来。

如果需要,请在Makefile中更改图像名称。

验证

最后,我们可以运行 makemake docker-build 来确保一切正常。