混合kubebuilder与code generator编写CRD

本文详细介绍了如何使用Kubebuilder生成CRD和manifests,然后结合code-generator生成informers、listers和clientsets。Kubebuilder适用于创建资源和控制器,而code-generator则用于生成与Kubernetes API交互的代码。通过这种方式,可以构建自己的Kubernetes Operator,实现更复杂的自动化管理任务。
摘要由CSDN通过智能技术生成

概览

kubebuilder和k8s.io/code-generator类似,是一个码生成工具,用于为你的CRD生成kubernetes-style API实现。区别在于:

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

Resource + Controller = Operator,因此你可以利用Kubebuilder编写你自己的Operator。

总结:如果你不想做Operator,如果你不会直接or间接生成Pod,只是想存取CRD(把K8S当作数据库使用)。那你可以使用Kubebuilder生成CRD和manifests yaml,再使用code-generator生成informers、listers、clientsets。

本文讲的就是这个方法。

第一步:创建项目

创建一个目录,然后在里面运行 kubebuilder init 命令,初始化一个新项目。示例如下。

1

2

3

4

5

6

mkdir $GOPATH/src/foo-controller

cd $GOPATH/src/foo-controller

# 我们将使用zsy.com域,

# 所以所有的 API 组将是<group>.zsy.com.

kubebuilder init --domain zsy.com 

kubebuilder edit --multigroup=true

注意:1、确保你已经安装 Kubebuilder,如果你的项目目录不在 $GOPATH 中,你需要运行 go mod init <modulename> 来告诉 kubebuilder 和 Go module 的基本导入路径。
         2、执行kubebuilder edit --multigroup=true命令,之后通过Kubebuilder创建API生成的Resource将放到项目apis路径下,不执行此条命令默认放到api路径下。

控制台输出类似以下内容:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

apple@appledeMacBook-Pro foo-controller$ kubebuilder init --domain zsy.com

Writing scaffold for you to edit...

Get controller runtime:

$ go get sigs.k8s.io/controller-runtime@v0.5.0

Update go.mod:

$ go mod tidy

Running make:

$ make

/usr/local/go/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."

go fmt ./...

go vet ./...

go build -o bin/manager main.go

Next: define a resource with:

$ kubebuilder create api

会生成以下文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

.

├── Dockerfile

├── Makefile

├── PROJECT

├── bin

│   └── manager

├── config

│   ├── certmanager

│   ├── default

│   ├── manager

│   ├── prometheus

│   ├── rbac

│   └── webhook

├── hack

│   └── boilerplate.go.txt

└── main.go

第二步:生成Resource和manifests

1

2

3

4

5

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

Create Resource [y/n]

y

Create Controller [y/n]

n

会生成以下文件go代码和manifests文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

.

├── apis

│   └── webapp

│       └── v1

│           ├── groupversion_info.go

│           ├── guestbook_types.go

│           └── zz_generated.deepcopy.go

└── config

    ├── crd

    │   ├── kustomization.yaml

    │   ├── kustomizeconfig.yaml

    │   └── patches

    │       ├── cainjection_in_guestbooks.yaml

    │       └── webhook_in_guestbooks.yaml

    ├── rbac

    │   ├── guestbook_editor_role.yaml

    │   ├── guestbook_viewer_role.yaml

    └── samples

        └── webapp_v1_guestbook.yaml

添加文件apis/webapp/v1/rbac.go,这个文件用生成RBAC manifests:

1

2

3

4

// +kubebuilder:rbac:groups=webapp.example.com,resources=guestbooks,verbs=get;list;watch;create;update;patch;delete

// +kubebuilder:rbac:groups=webapp.example.com,resources=guestbooks/status,verbs=get;update;patch

package v1

然后生成CRD manifests:

1

make manifests

得到:

1

2

3

4

5

6

config

├── crd

│   └── bases

│       └── webapp.example.com_guestbooks.yaml

└── rbac

    └── role.yaml

注意:

如果你修改了guestbook_types.go的结构,你需要执行以下命令来更新代码和manifests:

1

make && make manifests

第三步:使用code-generator

1)准备脚本

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

1

2

3

4

5

.

└── hack

    ├── tools.go

    ├── update-codegen.sh

    └── verify-codegen.sh

新建hack/tools.go文件:

1

2

// +build tools

package tools

新建hack/update-codegen.sh,注意修改几个变量:

  • MODULEgo.mod保持一致
  • API_PKG=apis,和apis目录保持一致
  • OUTPUT_PKG=generated/webapp,生成Resource时指定的group一样
  • GROUP_VERSION=webapp:v1和生成Resource时指定的group version对应

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

#!/usr/bin/env bash

set -o errexit

set -o nounset

set -o pipefail

# corresponding to go mod init <module>

MODULE=foo-controller

# api package

APIS_PKG=apis

# generated output package

OUTPUT_PKG=generated/webapp

# group-version such as foo:v1alpha1

GROUP_VERSION=webapp:v1

SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/..

CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)}

# 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.

bash "${CODEGEN_PKG}"/generate-groups.sh "client,lister,informer" \

  ${MODULE}/${OUTPUT_PKG} ${MODULE}/${APIS_PKG} \

  ${GROUP_VERSION} \

  --go-header-file "${SCRIPT_ROOT}"/hack/boilerplate.go.txt \

  --output-base "${SCRIPT_ROOT}"

#  --output-base "${SCRIPT_ROOT}/../../.." \

新建hack/verify-codegen.sh

+ View Code

2)下载code-generator

先把code-generator下载下来,注意这里的K8S版本号,得和go.mod里的k8s.io/client-go的版本一致:

1

2

3

K8S_VERSION=v0.18.6

go get k8s.io/code-generator@$K8S_VERSION

go mod vendor

然后给generate-groups.sh添加可执行权限:

1

chmod +x vendor/k8s.io/code-generator/generate-groups.sh

3)更新依赖版本

因为code-generator用的是v0.18.6,因此要把其他的k8s库也更新到这个版本,修改项目go.mod文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

module foo-controller

go 1.13

require (

    github.com/go-logr/logr v0.1.0

    github.com/onsi/ginkgo v1.11.0

    github.com/onsi/gomega v1.8.1

    k8s.io/apimachinery v0.18.6

    k8s.io/client-go v0.18.6

    k8s.io/code-generator v0.18.6

    sigs.k8s.io/controller-runtime v0.6.0

)

执行下面命令更新vendor目录

1

go mod vendor

4)生成代码

你需要修改guestbook_types.go文件,添加上tag // +genclient

1

2

3

4

5

// +genclient

// +kubebuilder:object:root=true

// Guestbook is the Schema for the guestbooks API

type Guestbook struct {

新建apis/webapp/v1/doc.go,注意// +groupName=webapp.zsy.com

1

2

3

// +groupName=webapp.zsy.com

package v1

新建apis/webapp/v1/register.go,code generator生成的代码需要用到它:

1

2

3

4

5

6

7

8

9

10

11

12

package v1

import (

    "k8s.io/apimachinery/pkg/runtime/schema"

)

// SchemeGroupVersion is group version used to register these objects.

var SchemeGroupVersion = GroupVersion

func Resource(resource string) schema.GroupResource {

    return SchemeGroupVersion.WithResource(resource).GroupResource()

}

执行hack/update-codegen.sh:

1

./hack/update-codegen.sh

会得到zsy.com/foo-controller目录:

1

2

3

4

5

6

foo-controller

└── generated

    └── webapp

        ├── clientset

        ├── informers

        └── listers

移动文件:

  • foo-controller/generated直接移出来,放到项目根下面generated

例子程序

先apply manifests yaml:

1

2

kubectl apply -f config/crd/bases/webapp.example.com_guestbooks.yaml

kubectl apply -f config/samples/webapp_v1_guestbook.yaml

然后执行项目的main.go

参考:https://segmentfault.com/a/1190000023097945

         https://github.com/chanjarster/kubebuilder-mix-codegen-how-to

         https://chanjarster.github.io/post/k8s/use-code-generator/

         https://cloudnative.to/kubebuilder/cronjob-tutorial/cronjob-tutorial.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值