专栏首页颇忒脱的技术博客混合kubebuilder与code generator编写CRD

混合kubebuilder与code generator编写CRD

使用Kubebuilder+k8s.io/code-generator编写CRD。

概览

和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

安装kubebuilder。

第一步:初始化项目

MODULE=example.com/foo-controller
go mod init $MODULE
kubebuilder init --domain example.com
kubebuilder edit --multigroup=true

会生成以下文件:

.
├── Dockerfile
├── Makefile
├── PROJECT
├── bin
│   └── manager
├── config
│   ├── certmanager
│   ├── default
│   ├── manager
│   ├── prometheus
│   ├── rbac
│   └── webhook
├── hack
│   └── boilerplate.go.txt
└── main.go

第二步:生成Resource和manifests

kubebuilder create api --group webapp --version v1 --kind Guestbook
Create Resource [y/n]
y
Create Controller [y/n]
n

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

.
├── 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:

// +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:

make manifests

得到:

config
├── crd
│   └── bases
│       └── webapp.example.com_guestbooks.yaml
└── rbac
    └── role.yaml

注意:

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

make && make manifests

第三步:使用code-generator

1)准备脚本

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

.
└── hack
    ├── tools.go
    ├── update-codegen.sh
    └── verify-codegen.sh

新建hack/tools.go文件:

// +build tools
package tools

import _ "k8s.io/code-generator"

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

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

set -o errexit
set -o nounset
set -o pipefail

# corresponding to go mod init <module>
MODULE=example.com/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(文件内容请看github项目)。

2)下载code-generator

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

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

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

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

3)更新依赖版本

因为code-generator用的是v0.18.5,因此要把其他的k8s库也更新到这个版本:

K8S_VERSION=v0.18.5
go get k8s.io/client-go@$K8S_VERSION
go get k8s.io/apimachinery@$K8S_VERSION
go get sigs.k8s.io/controller-runtime@v0.6.0
go mod vendor

4)生成代码

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

// +genclient
// +kubebuilder:object:root=true

// Guestbook is the Schema for the guestbooks API
type Guestbook struct {

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

// +groupName=webapp.example.com

package v1

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

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

./hack/update-codegen.sh

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

example.com
└── foo-controller
    └── generated
        └── webapp
            ├── clientset
            ├── informers
            └── listers

移动文件:

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

例子程序

先apply manifests yaml:

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

然后执行项目的main.go。

参考资料

  • code-generator client-gen tag references
  • kubebuilder tag references
  • Kubernetes Deep Dive: Code Generation for CustomResources
  • kubebuilder sample project

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何在Tomcat中做TLS客户端认证

    常见的https网站做的是服务端认证(server authentication),浏览器通过证书判断你所访问的https://baidu.com是否真的是百度...

    颇忒脱
  • Haproxy反向代理WebSocket的方法

    WebSocket请求和一般的Http请求不一样,它会长时间保持一个connection,Haproxy反向代理WebSocket请求需要用到timeout t...

    颇忒脱
  • Kublet PLEG不健康问题排障

    现象:某个Node频繁出现“PLEG is not healthy: pleg was last seen active 3m46.752815514s ago...

    颇忒脱
  • [Intellij IDEA]File size exceeds configured limit

        这两天尝试使用 IDEA, 发现一个问题File size exceeds configured limit (2560000). Code insig...

    囚兔
  • 腾讯在上海造了一辆时空列车!8月23日首发

    ? ? 腾讯T-DAY 走过深圳、广州、重庆、西安之后 终于来到了 上海 通往T-DAY上海的“时空列车” 我们已经建造好了 它能带你进入一个你未曾遇见的上海...

    腾讯文旅
  • 腾讯WeTest获三项ISO国际认证,构建顶尖全球化品质标准

    ?   2020年8月1日,国际权威认证机构DNV GL为腾讯旗下质量开放平台腾讯WeTest颁发了ISO9001质量管理体系、ISO27001信息安全管理体...

    WeTest质量开放平台团队
  • 腾讯WeTest获三项ISO国际认证,构建顶尖全球化品质标准

    2020年8月1日,国际权威认证机构DNV GL为腾讯旗下质量开放平台腾讯WeTest颁发了ISO9001质量管理体系、ISO27001信息安全管理体系、ISO...

    WeTest质量开放平台团队
  • 基于Ant Design Pro搭建博客管理后台 第一节

    官网教程:https://pro.ant.design/docs/getting-started-cn github链接:https://github.com...

    祈澈菇凉
  • Tesla半年市值平均超1000亿美元,马斯克开心解锁7亿美元酬劳宝箱

    举个例子,马斯克在2018年作为Tesla的CEO的收入为23亿美元-但Tesla说,他当年实际上赚了0美元。

    新智元
  • Promise最佳实践

    Promise的构造函数,以及被 then 调用执行的函数基本上都可以认为是在 try…catch 代码块中执行的,所以在这些代码中即使使用 throw ,程序...

    IMWeb前端团队

扫码关注云+社区

领取腾讯云代金券