从 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
。我们只需要复制 Spec
和 Status
字段的实现。
我们可以用 +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中更改图像名称。
验证
最后,我们可以运行 make
和 make docker-build
来确保一切正常。