2024-04-08
技术笔记
00
请注意,本文编写于 41 天前,最后修改于 32 天前,其中某些信息可能已经过时。

目录

kubebuilder
安装
初始化
创建api
修改api定义和controller逻辑
kubebuilder与code generator的区别
code generator
安装
添加脚本
修改代码
生成代码

本文介绍使用kubebuilder搭建一个kubernetes CRD crontroller框架,并使用code generator生产对应的clientset/informers/listers.

kubebuilder

https://book.kubebuilder.io/introduction.html

安装

bash
curl -L -o kubebuilder "https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)"

初始化

bash
mkdir -p ${GOPATH}/guestbook/src/example cd ${GOPATH}/guestbook/src/example kubebuilder init --domain my.domain

如果项目路径没有按照gopath的格式,则需要加上--repo参数:

bash
kubebuilder init --domain my.domain --repo my.domain/guestbook

创建api

bash
kubebuilder create api --group webapp --version v1 --kind Guestbook

INFO Create Resource [y/n] 选y会创建api/v1/guestbook_types.go

INFO Create Controller [y/n]选y会创建internal/controllers/guestbook_controller.go

修改api定义和controller逻辑

使用make manifests更新CRD

如果要创建已有资源的controller,需要指定group为core,参考https://github.com/kubernetes-sigs/kubebuilder/issues/1270
官方参考代码:https://github.com/kubernetes-sigs/controller-runtime/tree/master/examples/builtins

bash
kubebuilder create api --group core --version v1 --kind Node # Create Resource [y/n] 选n # Create Controller [y/n] 选y

kubebuilder与code generator的区别

Kubebuilder不会生成informers、listers、clientsets,而code-generator会。
Kubebuilder会生成Controller、Admission Webhooks,而code-generator不会。
Kubebuilder会生成manifests yaml,而code-generator不会。 Kubebuilder还带有一些其他便利性设施。

ref: https://cloud.tencent.com/developer/article/1656317

code generator

安装

注意K8S_VERSION必须和go.mod里面的一致

bash
K8S_VERSION=v0.29.0 go get k8s.io/code-generator@$K8S_VERSION

添加脚本

hack/update-codegen.sh
参考:https://github.com/kubernetes/code-generator/raw/v0.29.0/examples/hack/update-codegen.sh
最终修改的版本:

点击展开
bash
#!/usr/bin/env bash # Copyright 2017 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -x set -o errexit set -o nounset set -o pipefail SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" SCRIPT_ROOT="${SCRIPT_DIR}/.." CODEGEN_PKG="${CODEGEN_PKG:-"${SCRIPT_ROOT}/.."}" source "${CODEGEN_PKG}/kube_codegen.sh" # generate the code with: # - --output-base because this script should also be able to run inside the vendor dir of # k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir # instead of the $GOPATH directly. For normal projects this can be dropped. kube::codegen::gen_helpers \ --input-pkg-root . \ --output-base ${SCRIPT_ROOT} \ --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" if [[ -n "${API_KNOWN_VIOLATIONS_DIR:-}" ]]; then report_filename="${API_KNOWN_VIOLATIONS_DIR}/codegen_violation_exceptions.list" if [[ "${UPDATE_API_KNOWN_VIOLATIONS:-}" == "true" ]]; then update_report="--update-report" fi fi kube::codegen::gen_openapi \ --input-pkg-root . \ --output-pkg-root . \ --output-base ${SCRIPT_ROOT} \ --report-filename "${report_filename:-"/dev/null"}" \ ${update_report:+"${update_report}"} \ --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" kube::codegen::gen_client \ --with-watch \ --input-pkg-root . \ --output-pkg-root . \ --output-base ${SCRIPT_ROOT} \ --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt"

hack/verify-codegen.sh https://github.com/kubernetes/code-generator/raw/v0.29.0/examples/hack/verify-codegen.sh

hack/kube_codegen.sh https://github.com/kubernetes/code-generator/raw/v0.29.0/kube_codegen.sh
修改一个地方:

bash
done < <( ( kube::codegen::internal::git_grep -l \ -e '+genclient' \ ":(glob)${in_root}"/'**/*types.go' \ //这里types.go前面加上星号 || true \ ) | LC_ALL=C sort -u )

修改代码

修改api/v1/guestbook_types.go,在type Guestbook struct上面添加:

go
//+genclient

如果要全局生效,可以创建一个doc.go文件,把注释写在里面:

go
// +groupName=my.domain/guestbook // +genclient package v1

各种注释的作用(来自chatgpt):

  • genclient
    注释 +genclient 用于指示 Kubernetes 的代码生成工具 client-gen 为特定的 API 类型生成客户端代码。这个客户端代码包含了与 Kubernetes API 交互所需的方法,例如创建、获取、更新和删除资源对象。 当你在 API 类型定义文件中添加了 +genclient 注释时,client-gen 工具会为该类型生成一个客户端接口,这个接口包含了一系列标准的客户端操作方法。这些方法对应于 Kubernetes API 的操作,使得开发者可以在他们的应用程序中方便地管理 Kubernetes 资源。
    此外,+genclient 注释还可以与其他选项一起使用,以定制生成的客户端代码的行为。例如:
    +genclient:noStatus:即使 .Status 字段存在,也不生成 updateStatus 方法。
    +genclient:nonNamespaced:为集群范围的资源(不属于任何命名空间的资源)生成客户端代码。
    +genclient:onlyVerbs=create,get:只为指定的动作生成客户端方法。
    +genclient:skipVerbs=watch:生成除 watch 之外的所有客户端方法。

  • deecopy-gen
    注释 +k8s:deepcopy-gen 用于指示 Kubernetes 的代码生成工具为特定的 Go 包中的类型生成 DeepCopy 方法。这是 Kubernetes 自定义资源定义(CRD)开发过程中的一个重要步骤,因为它确保了类型的每个实例都可以被安全地复制,这对于 Kubernetes 的许多操作来说是必需的。
    由于kubebuilder已经为crd生成了deepcopy函数,所以这个注释可以不用

  • defaulter-gen
    注释 +k8s:defaulter-gen 是 Kubernetes 代码生成工具中使用的一个标记,它用于为特定的 Go 包中的类型生成默认值设置函数。这些函数通常在 API 对象被创建或更新时调用,以确保所有未设置的字段都有合适的默认值。当你在包的 doc.go 文件或类型定义文件中添加了 +k8s:defaulter-gen=TypeMeta 注释时,code-generator 工具会为该包中的所有公开类型生成默认值设置函数。如果你想为特定的类型生成默认值设置函数,可以在类型定义上使用 +k8s:defaulter-gen=true 注释。

  • conversion-gen
    注释 +k8s:conversion-gen 用于指导 Kubernetes 的代码生成工具 conversion-gen 自动生成在内部和外部类型之间转换的函数。这些转换函数对于 Kubernetes API 中的多版本支持非常重要,因为它们允许不同版本的 API 对象之间进行转换。
    具体来说,conversion-gen 工具会生成函数,这些函数能够高效地在具有相同名称的类型之间进行转换,无论这些类型是定义在内部包还是外部包中。生成的函数包括 autoConvert_<pkg1>_<type>_To_<pkg2>_<type>,这些函数会递归地处理数据类型的结构。对于结构体,它会根据名称匹配源字段和目标字段;如果源字段没有对应的目标字段,或者字段类型存在根本的不匹配,那么生成的 autoConvert_... 函数将只包含一个关于该字段的警告注释。

  • openapi-gen
    注释 +k8s:openapi-gen 用于指导 Kubernetes 代码生成工具 openapi-gen 为 Go 包中的类型生成 OpenAPI 规范。这个规范定义了 RESTful API 的接口,使得人类和计算机都能理解服务的功能,而无需接触源代码或监控网络通信。
    当你在包的 doc.go 文件或类型定义文件中添加了 +k8s:openapi-gen 注释时,openapi-gen 工具会扫描该包下的所有类型,并为它们生成 OpenAPI 定义。这样,Kubernetes 就可以使用文档生成工具来展示其 API,使用代码生成工具来自动生成服务器端和客户端的代码,以及使用自动测试工具进行测试。

生成代码

bash
export CODEGEN_PKG=./hack/ ./hack/update-codegen.sh

如果报错: /data/go/pkg/mod/k8s.io/code-generator@v0.29.0/cmd/openapi-gen/main.go:37:43: undefined: generatorargs.NewDefaults

需要更新kube-openapi

bash
go get k8s.io/kube-openapi@v0.0.0-20231010175941-2dd684a91f00

版本是从code-generator的go.mod拿到的

执行完,会得到clientset informers listers三个目录

本文作者:renbear

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC 2.0 许可协议。转载请注明出处!