Kubebuild and code generator

overview

kubebuilder and k8s.io/code-generator Similarly, it is a code generation tool used to generate code for your CRD kubernetes-style API realization. At present, Kubebuilder generates CRD and manifest yaml, and then code generator generates informers, listers and clientsets. Note that the methods described in this article can no longer be used in Windows environment.

The Kubebuilder version used in this article is 3.2.0 and the code generator version is v0.22.1

1, Creating a project using kubebuilder

Note: when Kubebuilder creates a project, it has strict requirements for the file content in the project, so it's best to start from a new project. If you start with an old project, it takes a lot of effort.

First download 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/

Create a go mod project and enter the project to execute:

kubebuilder init --domain zsy.com 
kubebuilder edit --multigroup=true

2, Generate resources and manifests

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

If you encounter an error in this step, it may be a gcc problem. You need to install or upgrade gcc.

After this step, you can modify the api/v1/groupversion_info.go file. Modify the CRD configuration in this file to the required configuration field. After modification, execute the make command to update the code.

Add the file api/v1/rbac.go, which is used to generate 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

Then generate CRD manifests:

make manifests

3, Using code generator

1) Prepare script

Add the following files in the hack Directory:

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

Create a new hack/tools.go file:

// +build tools
package tools

Create hack/update-codegen.sh, and pay attention to modifying several variables:

  • MODULE is consistent with go.mod

  • API_PKG=api, consistent with api directory

  • OUTPUT_PKG=generated/webapp. The group specified when generating a Resource is the same

  • GROUP_VERSION=webapp:v1 corresponds to the group version specified when generating the Resource

#!/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=api
# 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}

Create hack/verify-codegen.sh

OUTPUT_PKG=generated/webapp. The group specified when generating a Resource is the same

MODULE is a combination of domain and go.mod

#!/usr/bin/env bash
 
set -o errexit
set -o nounset
set -o pipefail
 
OUTPUT_PKG=generated/webapp
MODULE=zsy.com/foo-controller
 
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

2) Update dependency

Edit the project's go.mod file

module foo-controller
 
go 1.16
 
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.22.1
    k8s.io/client-go v0.22.1
    k8s.io/code-generator v0.22.1
    sigs.k8s.io/controller-runtime v0.6.0
)

Then use the vendor tool to update the vendor. Note that do not use the go mod vendor command to update here, because the dependency of k8s.io/code-generator has not been really referenced in the project, so it is impossible to update the dependency to the vendor using go mod vendor, which should be implemented with the help of the third-party tool vendor. https://github.com/nomad-software/vend

Use the command go get github.com/nomad-software/vend To install, and then execute the vend command under the project root directory.

Then add executable permissions to generate-groups.sh:

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

3) Modify code structure

Code generator has certain requirements for code structure, but the structure generated by kubebuild tool does not meet this requirement, so we need to modify the code structure of the project.

Original structure:

├── api
│   └── v1
│       ├── groupversion_info.go
│       ├── guestbook_types.go
│       └── zz_generated.deepcopy.go

Modified structure:

├── api
│   └── webapp
│       └── v1
│           ├── groupversion_info.go
│           ├── guestbook_types.go
│           └── zz_generated.deepcopy.go

That is, add a layer of path in the middle, and the name is the group name.

4) Add comments

Modify Guestbook_ Add tag // +genclient to the types.go file. The annotation content should be added to the k8s object structure. Pay attention to check whether the added position is correct.

// +genclient
// +kubebuilder:object:root=true
 
// Guestbook is the Schema for the guestbooks API
type Guestbook struct {

Create api/webapp/v1/doc.go. Note / / + groupName=webapp.zsy.com:

// +groupName=webapp.zsy.com
 
package v1

Create api/webapp/v1/register.go, which is required for code generated by 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()
}

Execute hack/update-codegen.sh:

./hack/update-codegen.sh

You will get the zsy.com/foo-controller Directory:

foo-controller
└── generated
    └── webapp
        ├── clientset
        ├── informers
        └── listers

At this point, the code generation step is completed.

Reference documents

https://www.jianshu.com/p/82df84131f78

[https://www.cnblogs.com/zhangmingcheng/p/15405022.html](

Keywords: Linux Kubernetes Container

Added by asgerhallas on Fri, 03 Dec 2021 01:04:17 +0200