多版本 API 开发
背景
随着 controller 的不断迭代,可能需要新增或变更某些功能,此时一般需要新增 API 版本进行支持,我们就需要管理多个 API 版本,本文介绍用 kubebuilder 开发 controller 时如何高效且优雅的管理多个 API 版本。
新增 API 版本
如果要对某个 API 新增版本,先用 kubebuilder 操作新建一下,如:
kubebuilder create api --group webapp --version v1beta2 --kind Guestbook
然后将上一个版本的 API 的 xx_types.go (如 guestbook_types.go) 文件拷贝覆盖到新版本的 xx_types.go 文件中,并修改新版本 xx_types.go 文件中的包名为新版本的包名。
在新版本的 API 结构体中上面加上下面的注释标记并移出其它版本 API 结构体的这个标记(如果有的话),表示后续新增的对象使用该版本 API 进行存储(存量的还是用旧版本存储):
// +kubebuilder:storageversion
API 自动转换
客户端(如kubectl、client-go)在请求 API 时,会指定 API 版本,当存储的 API 版本与请求的版本不一致时,APIServer 可以调用 controller 提供的 webhook 进行自动转换,下面是实现自动转换 API 版本的 webhook 的方法。
首先使用 kubebuilder 创建 webhook(假设是希望将 v1alpha1 的 Guestbook 转换成 v1beta1):
kubebuilder create webhook --group webapp --version v1beta1 --kind Guestbook --conversion --spoke v1alpha1
--version指定 Hub 版本(存储的 API 版本),通常是最新版本。--spoke指定请求的要被自动转换的其它 API 版本,通常是旧版本。
- 以上只是实现 API 自动转换需要的 create webhook 参数,如果还有其他 webhook 需求(如 ValidatingWebhook
--programmatic-validation,自动设置默认值--defaulting)也需要带上,相同 API 版本的 webhook 创建后不能重新执行 create webhook 命令来追加功能,需一次性到位。
执行后可以看到:
- v1beta1 下新增了
xx_conversion.go文件,为 API 结构体新增了Hub空函数,实现 Hub 接口,用于标记该 API 版本是 Hub 版本,其它版本的 API 将会自动转换成这个版本。 - v1alpha1 下也新增了
xx_conversion.go文件,为 API 结构体新增了ConvertTo和ConvertFrom函数,实现 Convertible 接口,将会被 webhook 自动调用用于转换 API 版本。
然后将旧版本 API 下的 xx_webhook.go(包含 SetupWebhookWithManager) 和 xx_webhook_test.go 移动到新版本 API 下,并修改包名为新版本的包名,调用 SetupWebhookWithManager 的地方也跟着改一下引用到新版本。Webhook 中的其它相关逻辑如果需要改动也要改一下(比如 ValidateXXX, Default 等),围绕新版本 API 来改动相关逻辑。