kubebuilder和code-generator使用分享

kubebuilder和k8s.io/code-generator類似屯阀,是一個碼生成工具,用于為你的CRD生成kubernetes-style API實現(xiàn)轴术。目前個人使用Kubebuilder生成CRD和manifests yaml难衰,再使用code-generator生成informers、listers逗栽、clientsets盖袭。

下載kubebuilder

# download kubebuilder and install locally.
curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)
chmod +x kubebuilder && mv kubebuilder /usr/local/bin/

本文中使用的Kubebuilder版本為release-3,code-generator版本為v0.19.2

使用kubebuilder創(chuàng)建項目

go  mod init example
// --skip-go-version-check 跳過Go版本校驗
kubebuilder  init --domain lgy.com --skip-go-version-check
// 設(shè)置后生成的api上層會自動創(chuàng)建Group名文件夾
kubebuilder edit --multigroup=true
kubebuilder create api --version v1 --kind Example--group serving

效果如下:

[root@master example]# go mod init example
go: creating new go.mod: module example
[root@master example]# kubebuilder  init --domain lgy.com --skip-go-version-check
Writing kustomize manifests for you to edit...
Writing scaffold for you to edit...
Get controller runtime:
$ go get sigs.k8s.io/controller-runtime@v0.7.2
Update dependencies:
$ go mod tidy
Next: define a resource with:
$ kubebuilder create api
[root@master example]# kubebuilder edit --multigroup=true
[root@master example]# kubebuilder create api --version v1 --kind Example --group serving
Create Resource [y/n]
y
Create Controller [y/n]
n
Writing kustomize manifests for you to edit...
Writing scaffold for you to edit...
apis/serving/v1/example_types.go
Update dependencies:
$ go mod tidy
Running make:
$ make generate
go: creating new go.mod: module tmp
Downloading sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1
go get: installing executables with 'go get' in module mode is deprecated.
    To adjust and download dependencies of the current module, use 'go get -d'.
    To install using requirements of the current module, use 'go install'.
    To install ignoring the current module, use 'go install' with a version,
    like 'go install example.com/cmd@latest'.
    For more information, see https://golang.org/doc/go-get-install-deprecation
    or run 'go help get' or 'go help install'.
go get: added github.com/fatih/color v1.7.0
go get: added github.com/gobuffalo/flect v0.2.0
go get: added github.com/gogo/protobuf v1.3.1
go get: added github.com/google/gofuzz v1.1.0
go get: added github.com/inconshreveable/mousetrap v1.0.0
go get: added github.com/json-iterator/go v1.1.8
go get: added github.com/mattn/go-colorable v0.1.2
go get: added github.com/mattn/go-isatty v0.0.8
go get: added github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
go get: added github.com/modern-go/reflect2 v1.0.1
go get: added github.com/spf13/cobra v1.0.0
go get: added github.com/spf13/pflag v1.0.5
go get: added golang.org/x/mod v0.2.0
go get: added golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
go get: added golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7
go get: added golang.org/x/text v0.3.2
go get: added golang.org/x/tools v0.0.0-20200616195046-dc31b401abb5
go get: added golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
go get: added gopkg.in/inf.v0 v0.9.1
go get: added gopkg.in/yaml.v2 v2.2.8
go get: added gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966
go get: added k8s.io/api v0.18.2
go get: added k8s.io/apiextensions-apiserver v0.18.2
go get: added k8s.io/apimachinery v0.18.2
go get: added k8s.io/klog v1.0.0
go get: added k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89
go get: added sigs.k8s.io/controller-tools v0.4.1
go get: added sigs.k8s.io/structured-merge-diff/v3 v3.0.0
go get: added sigs.k8s.io/yaml v1.2.0
/opt/lgy/example/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."
[root@master example]# 
[root@master example]# 
[root@master example]# tree
.
├── apis
│   └── serving
│       └── v1
│           ├── example_types.go
│           ├── groupversion_info.go
│           └── zz_generated.deepcopy.go
├── bin
│   └── controller-gen
├── config
│   ├── crd
│   │   ├── kustomization.yaml
│   │   ├── kustomizeconfig.yaml
│   │   └── patches
│   │       ├── cainjection_in_examples.yaml
│   │       └── webhook_in_examples.yaml
│   ├── default
│   │   ├── kustomization.yaml
│   │   ├── manager_auth_proxy_patch.yaml
│   │   └── manager_config_patch.yaml
│   ├── manager
│   │   ├── controller_manager_config.yaml
│   │   ├── kustomization.yaml
│   │   └── manager.yaml
│   ├── prometheus
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   ├── rbac
│   │   ├── auth_proxy_client_clusterrole.yaml
│   │   ├── auth_proxy_role_binding.yaml
│   │   ├── auth_proxy_role.yaml
│   │   ├── auth_proxy_service.yaml
│   │   ├── example_editor_role.yaml
│   │   ├── example_viewer_role.yaml
│   │   ├── kustomization.yaml
│   │   ├── leader_election_role_binding.yaml
│   │   ├── leader_election_role.yaml
│   │   ├── role_binding.yaml
│   │   └── service_account.yaml
│   └── samples
│       └── serving_v1_example.yaml
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│   └── boilerplate.go.txt
├── main.go
├── Makefile
└── PROJECT

13 directories, 35 files

添加文件apis/serving/v1/rbac.go彼宠,這個文件用生成RBAC manifests:
注意修改kubebuilder:rbac:groups和resources為你的

// +kubebuilder:rbac:groups=serving.lgy.com,resources=examples,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=serving.lgy.com,resources=examples/status,verbs=get;update;patch
 
package v1

生成CRD manifests

[root@master example]# make manifests
/opt/lgy/example/bin/controller-gen "crd:trivialVersions=true,preserveUnknownFields=false" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
[root@master example]# 

使用code-generator

1)準(zhǔn)備腳本

在hack目錄下添加以下文件:

[root@master hack]# tree
.
├── boilerplate.go.txt
├── tools.go
├── update-codegen.sh
└── verify-codegen.sh

0 directories, 4 files

tools.go

// +build tools
package tools

update-codegen.sh
注意:
MODULE和go.mod保持一致
API_PKG=apis鳄虱,和apis目錄保持一致
OUTPUT_PKG=generated/serving,生成Resource時指定的group一樣
GROUP_VERSION=serving:v1和生成Resource時指定的group version對應(yīng)

#!/usr/bin/env bash

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

# corresponding to go mod init <module>
MODULE=example
# api package
APIS_PKG=apis
# generated output package
OUTPUT_PKG=generated/serving
# group-version such as foo:v1alpha1
GROUP_VERSION=serving: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}"

verify-codegen.sh
注意:
OUTPUT_PKG=generated/serving凭峡,生成Resource時指定的group一樣
MODULE是domain和go.mod的結(jié)合

#!/usr/bin/env bash

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

OUTPUT_PKG=generated/serving
MODULE=lgy.com/example

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

DIFFROOT="${SCRIPT_ROOT}/${OUTPUT_PKG}"
TMP_DIFFROOT="${SCRIPT_ROOT}/_tmp/${OUTPUT_PKG}"
_tmp="${SCRIPT_ROOT}/_tmp"

cleanup() {
  rm -rf "${_tmp}"
}
trap "cleanup" EXIT SIGINT

cleanup

mkdir -p "${TMP_DIFFROOT}"
cp -a "${DIFFROOT}"/* "${TMP_DIFFROOT}"

"${SCRIPT_ROOT}/hack/update-codegen.sh"
echo "copying generated ${SCRIPT_ROOT}/${MODULE}/${OUTPUT_PKG} to ${DIFFROOT}"
cp -r "${SCRIPT_ROOT}/${MODULE}/${OUTPUT_PKG}"/* "${DIFFROOT}"

echo "diffing ${DIFFROOT} against freshly generated codegen"
ret=0
diff -Naupr "${DIFFROOT}" "${TMP_DIFFROOT}" || ret=$?
cp -a "${TMP_DIFFROOT}"/* "${DIFFROOT}"
if [[ $ret -eq 0 ]]
then
  echo "${DIFFROOT} up to date."
else
  echo "${DIFFROOT} is out of date. Please run hack/update-codegen.sh"
  exit 1
fi

修改文件權(quán)限:

[root@master hack]# chmod 755 update-codegen.sh 
[root@master hack]# chmod 755 verify-codegen.sh 
[root@master hack]#

2)添加注釋

修改example_types.go文件拙已,添加上tag // +genclient,這個注釋內(nèi)容要加在Example結(jié)構(gòu)體上面摧冀,

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

// Example is the Schema for the examples API
type Example struct {
        metav1.TypeMeta   `json:",inline"`

新建apis/serving/v1/doc.go
// +groupName更換成自己的

// +groupName=serving.lgy.com
package v1

新建apis/serving/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()
}

3)更新依賴

新增 k8s.io/code-generator,需和 k8s.io/client-go版本一致

module example

go 1.15

require (
        k8s.io/apimachinery v0.19.2
        k8s.io/client-go v0.19.2
        k8s.io/code-generator v0.19.2
        sigs.k8s.io/controller-runtime v0.7.2
)

然后使用vend工具更新vendor索昂,注意這里不要用go mod vendor命令來更新惭适,因為k8s.io/code-generator這個依賴在項目中并沒有真正被引用過,所以使用go mod vendor是無法將這個依賴更新到vendor中楼镐,要借助第三方工具vend來實現(xiàn)癞志。https://github.com/nomad-software/vend
使用命令go getgithub.com/nomad-software/vend來安裝,然后再項目根目錄下執(zhí)行vend命令
然后給generate-groups.sh添加可執(zhí)行權(quán)限:

[root@master example]# chmod 755 vendor/k8s.io/code-generator/generate-groups.sh
[root@master example]# 

執(zhí)行hack/update-codegen.sh:

[root@master example]# ./hack/update-codegen.sh 
Generating clientset for serving:v1 at example/generated/serving/clientset
Generating listers for serving:v1 at example/generated/serving/listers
Generating informers for serving:v1 at example/generated/serving/informers
[root@master example]# 

當(dāng)前目錄下生成example文件夾

[root@master example]# pwd
/opt/lgy/example/example
[root@master example]# tree -CL 6
.
└── generated
    └── serving
        ├── clientset
        │   └── versioned
        │       ├── clientset.go
        │       ├── doc.go
        │       ├── fake
        │       │   ├── clientset_generated.go
        │       │   ├── doc.go
        │       │   └── register.go
        │       ├── scheme
        │       │   ├── doc.go
        │       │   └── register.go
        │       └── typed
        │           └── serving
        ├── informers
        │   └── externalversions
        │       ├── factory.go
        │       ├── generic.go
        │       ├── internalinterfaces
        │       │   └── factory_interfaces.go
        │       └── serving
        │           ├── interface.go
        │           └── v1
        └── listers
            └── serving
                └── v1
                    ├── example.go
                    └── expansion_generated.go

16 directories, 13 files
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末框产,一起剝皮案震驚了整個濱河市凄杯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秉宿,老刑警劉巖戒突,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異描睦,居然都是意外死亡膊存,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門忱叭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來隔崎,“玉大人,你說我怎么就攤上這事韵丑【糇洌” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵撵彻,是天一觀的道長钓株。 經(jīng)常有香客問我实牡,道長,這世上最難降的妖魔是什么轴合? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任创坞,我火速辦了婚禮,結(jié)果婚禮上受葛,老公的妹妹穿的比我還像新娘摆霉。我一直安慰自己,他們只是感情好奔坟,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著搭盾,像睡著了一般咳秉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鸯隅,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天澜建,我揣著相機與錄音,去河邊找鬼蝌以。 笑死炕舵,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的跟畅。 我是一名探鬼主播咽筋,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼徊件!你這毒婦竟也來了奸攻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤虱痕,失蹤者是張志新(化名)和其女友劉穎睹耐,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體部翘,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡硝训,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了新思。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窖梁。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖夹囚,靈堂內(nèi)的尸體忽然破棺而出窄绒,到底是詐尸還是另有隱情,我是刑警寧澤崔兴,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布彰导,位于F島的核電站蛔翅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏位谋。R本人自食惡果不足惜山析,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掏父。 院中可真熱鬧笋轨,春花似錦、人聲如沸赊淑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽陶缺。三九已至钾挟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間饱岸,已是汗流浹背掺出。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留苫费,地道東北人汤锨。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子读宙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345