kubebuilder与code generator区别与合作

2022-10-29  本文已影响0人  程序员札记

一、概念简介

1.1 code-generator

k8s.io/client-go for talking to a kubernetes cluster.
k8s.io/client-go 提供了对k8s原生资源的informer和clientset等等,但对于自定义资源的操作则相对低效,需要使用 rest api 和 dynamic client 来操作,并自己实现反序列化等功能。
code-generator 提供了以下工具用于为k8s中的资源生成相关代码,可以更加方便的操作自定义资源:

在文件中添加注释// +k8s:deepcopy-gen=package
为单个类型添加自动生成// +k8s:deepcopy-gen=true
为单个类型关闭自动生成// +k8s:deepcopy-gen=false

pkg/apis/GROUP/{GROUP}/GROUP/{VERSION}/types.go中使用,使用// +genclient标记对应类型生成的客户端, 如果与该类型相关联的资源不是命名空间范围的(例如PersistentVolume), 则还需要附加// + genclient:nonNamespaced标记,
// +genclient - 生成默认的客户端动作函数(create, update, delete, get, list, update, patch, watch以及 是否生成updateStatus取决于.Status字段是否存在)。
// +genclient:nonNamespaced - 所有动作函数都是在没有名称空间的情况下生成
// +genclient:onlyVerbs=create,get - 指定的动作函数被生成.
// +genclient:skipVerbs=watch - 生成watch以外所有的动作函数.
// +genclient:noStatus - 即使.Status字段存在也不生成updateStatus动作函数

  • 一套包含内部类型的程序包,

  • 一套包含外部类型的程序包

  • 单个目标程序包(即,生成的转换函数所在的位置,以及开发人员授权的转换功能所在的位置)。包含内>部类型的包在Kubernetes的常规代码生成框架中扮演着称为peer package的角色。
    标记转换内部软件包 // +k8s:conversion-gen=<import-path-of-internal-package>

  • 标记转换外部软件包// +k8s:conversion-gen-external-types=<import-path-of-external-package>
    标记不转换对应注释或结构 // +k8s:conversion-gen=false

为包含字段的所有类型创建defaulters,// +k8s:defaulter-gen=<field-name-to-flag>
所有都生成// +k8s:defaulter-gen=true|false

  • go-to-protobuf 通过go struct生成pb idl
  • import-boss 在给定存储库中强制执行导入限制
  • openapi-gen 生成openAPI定义使用方法:
    +k8s:openapi-gen=true 为指定包或方法开启
    +k8s:openapi-gen=false 指定包关闭
  • register-gen 生成register
  • set-gen

code-generator整合了这些gen,使用脚本generate-groups.shgenerate-internal-groups.sh可以为自定义资源生产相关代码。

1.2 Kubebuilder

Kubebuilder是用于使用自定义资源定义(CRD)构建Kubernetes API的框架。
类似于Ruby on RailsSpringBoot之类的Web开发框架,Kubebuilder可以提高速度并降低开发人员管理的复杂性,以便在Go中快速构建和发布Kubernetes API。它建立在用于构建核心Kubernetes API的规范技术的基础之上,以提供减少样板和麻烦的简单抽象。

Resource + Controller = Operator,可以利用Kubebuilder编写自定义资源的Operator。

二、结合背景

Kubebuildercode-generator 都可以为CRD生成Kubernetes API相关代码,从代码生成层面来讲, 两者的区别在于:

使用Kubebuilder可以快捷生成CRD以及相关的控制器框架,然而由于Kubebuilder不会生成clientset等包,当别的服务想要操作CRD时将会很麻烦。

两者结合后可以使用Kubebuilder生成CRD和一整套控制器架构,再使用code-generator生成informers、listers、clientsets等。

三、操作步骤

3.1 依赖组件

3.2 初始化项目

安装Kubebuilder:参考官方文档 https://cloudnative.to/kubebuilder/quick-start.html

1、创建一个项目

mkdir -p $GOPATH/src/my.domain/example
cd $GOPATH/src/my.domain/example
kubebuilder init --domain my.domain
tree -CL 2
.
├── bin
│   └── manager
├── config
│   ├── certmanager
│   ├── default
│   ├── manager
│   ├── prometheus
│   ├── rbac
│   └── webhook
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│   └── boilerplate.go.txt
├── main.go
├── Makefile
└── PROJECT

9 directories, 8 files

2、创建一个 API

kubebuilder create api --group example --version v1 --kind Guestbook
Create Resource [y/n]
y
Create Controller [y/n]
n
tree -CL 3
.
├── api
│   └── v1
│       ├── groupversion_info.go
│       ├── guestbook_types.go
│       └── zz_generated.deepcopy.go
......

注意:

如果修改了 api/v1/guestbook_types.go ,需要执行以下命令来更新代码和manifests:

make && make manifests

3.3 使用code-generator

3.3.1 更新依赖版本

初始化项目后的go.mod:

cat go.mod
module my.domain/example

go 1.13

require (
        k8s.io/apimachinery v0.17.2
        k8s.io/client-go v0.17.2
        sigs.k8s.io/controller-runtime v0.5.0
)

需要将初始化的k8s库更新到要使用的版本,如:

K8S_VERSION=v0.17.2
go get k8s.io/client-go@$K8S_VERSION
go get k8s.io/apimachinery@$K8S_VERSION

3.3.2 安装code-generator

K8S_VERSIONgo.mod 中的 k8s.io/client-go 的版本保持一致即可。

注意:需要将依赖复制到vendor中

K8S_VERSION=v0.17.2
go get k8s.io/code-generator@$K8S_VERSION
go mod vendor

3.3.3 创建&修改所需文件

需要在api目录下创建code-generator所需的文件,并添加相关注释。

3.3.4 准备脚本

在项目 hack 目录下准备以下文件:

3.3.5 生成代码

项目根目录下执行make update-codegen 即可,将生成如下代码结构:

.
├── api
│   ├── example
│   │   └── v1
│   │       ├── doc.go
│   │       ├── groupversion_info.go
│   │       ├── guestbook_types.go
│   │       ├── register.go
│   │       └── zz_generated.deepcopy.go
├── generated
│   └── example
│       ├── clientset
│       ├── informers
│       └── listers

之后便可以通过clientset等包对自定义资源对象进行操作。

注意事项:

kubebuilder2.3.2版本生成的api目录结构为 api/v1,而code-generator需要的api目录结构为 api/example/v1,相比较增加了group这一层。

上一篇 下一篇

猜你喜欢

热点阅读