什么是Kubebuilder

Kubebuilder 是一个基于 CRD(Custom Resource Definitions,自定义资源定义)构建 Kubernetes API 的框架。它允许开发者使用 CRD 来构建 Kubernetes API、Controller 和 Admission Webhook。Kubebuilder 的主要目的是简化 Kubernetes API 和工具的构建过程,减少样板代码的编写,使得开发者可以更专注于业务逻辑的实现。

Kubebuilder 的工作流程大致如下:

创建一个新的工程目录。 创建一个或多个资源 API CRD 并将字段添加到资源中。 在控制器中实现协调循环(reconcile loop),watch 额外的资源。 在集群中运行测试(自动安装 CRD 并自动启动控制器)。 更新引导集成测试测试新字段和业务逻辑。 使用用户提供的 Dockerfile 构建和发布容器。

什么是code-generator

Kubernetes code-generator 是一个代码生成工具集合,它位于 Kubernetes 代码库中的 staging/src/k8s.io/code-generator 包中,这个工具的主要目的是自动化生成与 Kubernetes 相关的客户端库、API 服务器(API server)和其他与 Kubernetes 相关的代码,以提高代码的可维护性和一致性,减少重复代码的开发工作。

code-generator 的主要功能包括:

自动生成客户端库 clientset:通过定义自定义资源的 API 规范,code-generator 可以自动生成用于访问和操作这些自定义资源的客户端库。 自动生成 API 服务器代码:可以根据自定义资源的 API 规范,自动生成与之对应的 API 服务器代码,使得开发者可以快速构建自己的自定义资源的 API 服务器,并将其部署到 Kubernetes 集群中。 自动生成 DeepCopy 方法:对于 Kubernetes 对象,深拷贝是一种常见的操作,用于创建对象的副本。 自动生成其他辅助代码:除了上述功能外,code-generator 还可以生成其他与 Kubernetes 相关的辅助代码,如列表(List)、转换器(Converter)等。 code-generator 包含多个生成工具(gen tools),例如:

deepcopy-gen:为每个类型生成 DeepCopy 方法。 client-gen:生成类型化客户端集合(typed client sets)。 informer-gen:生成基于 Kubernetes API 资源的 Informer。 lister-gen:生成 Kubernetes API 资源的 Lister。 register-gen:自动生成 API 资源类型的注册表代码。 conversion-gen:用于生成 Kubernetes 对象之间的转换器(Converter)。 openapi-gen:用于生成 Kubernetes API 的 OpenAPI 规范。

综上,这两个工具都可以提升我们管理CRD的效率。首先我们使用Kubebuilder生成我们想要的crd对应的type和对应的crd文件。code-generator可以帮助我们生成与api交互需要的资源,比如lister。

接下来老高会讲解如何使用kubebuilder和code-generator构建你的crd套件。

使用kubebuilder生成骨架

骨架就是一个项目的雏形,kubebuilder为我们提供了相对合理的目录结构,所以赶紧参考Quick Start准备好kubebuilder的运行环境,下一步就开始生成我们的测试项目了。

初始化项目

# 创建目录
mkdir my-crd && cd my-crd
# 初始化
kubebuilder init --domain github.com --repo github.com/phpgao/crd
# 修改项目支持多group
kubebuilder edit --multigroup=true

如果出现类似invalid go version '1.22.0': must match format 1.23的提示,请升级go的版本到最新

此时,我们的项目结构应该如下(忽略了不重要的文件)

.
├── Dockerfile
├── Makefile
├── PROJECT
├── README.md
├── bin
├── config
│   ├── default
│   │   ├── kustomization.yaml
│   │   ├── manager_metrics_patch.yaml
│   │   └── metrics_service.yaml
│   ├── manager
│   │   ├── kustomization.yaml
│   │   └── manager.yaml
│   ├── network-policy
│   │   ├── allow-metrics-traffic.yaml
│   │   └── kustomization.yaml
│   ├── prometheus
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   └── rbac
│       ├── kustomization.yaml
│       ├── leader_election_role.yaml
│       ├── leader_election_role_binding.yaml
│       ├── metrics_auth_role.yaml
│       ├── metrics_auth_role_binding.yaml
│       ├── metrics_reader_role.yaml
│       ├── role.yaml
│       ├── role_binding.yaml
│       └── service_account.yaml
├── go.mod
├── go.sum
└── hack
    └── boilerplate.go.txt

创建第一个API(GVK)

此时老高希望生成两个版本的Kind=Job,version=v1+v1alpha1,group=task。 然后再生成一个Kind=CronJob,version=v1,group=apps。

# 是否创建资源(yes) 是否生成控制器(no)
# INFO Create Resource [y/n]
# y
# INFO Create Controller [y/n]
# n
kubebuilder create api --group task --version v1 --kind Job --controller=false --resource
kubebuilder create api --group task --version v1alpha1 --kind Job --controller=false --resource
kubebuilder create api --group apps --version v1 --kind CronJob --controller=false --resource

根据Changing things up的描述,当存在多个api版本的时候需要指定一个版本作为storage版本,storage 字段用于标识哪个版本的自定义资源是存储在 etcd 中的版本。当你有多个版本的 CRD 时,Kubernetes 需要知道哪个版本应该用于存储在其底层的 etcd 数据库中。所以我们需要在生成的api/task/v1/job_types.go给Job结构体添加// +kubebuilder:storageversion的注释,否则make manifests时会报错。

生成相关定义

# 修改api/apps/v1/cronjob_types.go
// CronJobStatus defines the observed state of CronJob
type CronJobStatus struct {
	// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
	// Important: Run "make" to regenerate code after modifying this file

	// Foo is an example field of CronJob. Edit cronjob_types.go to remove/update
	Foo string `json:"foo,omitempty"`
}

# 然后执行
make manifests
cat config/crd/bases/apps.phpgao.com_cronjobs.yaml
# 可以发现对应的字段已经更新

至此,我可能已经可以部署crd到集群中了。

下一节我们让crd"动起来",生成clientset,lister,informer。

code-generator

准备工作

我们把code-generator项目克隆到本地

git submodule add https://github.com/kubernetes/code-generator.git

补充文件

这个文件放到util下,保存为gen.go

mkdir util
wget https://gist.githubusercontent.com/phpgao/9404c323fe2c74d2862701ac4c6e4dc8/raw/cce6d8096e32fb6755f459a038e120523ea87005/gen.go -O gen.go
mv gen.go util

# 在项目根目录执行下面的命令
go run util/gen.go

下载并执行update.sh

wget https://gist.githubusercontent.com/phpgao/9404c323fe2c74d2862701ac4c6e4dc8/raw/ecb1c008432dbd22f75a39a30b352c6fa2401ec3/update-codegen.sh -O update-codegen.sh

# 第一个参数为包名+pkg
bash update-codegen.sh github.com/phpgao/crd/pkg

标签: k8s

添加新评论