I. Concept introduction

1.1 code-generator

k8s.io/client-go for talking to a kubernetes cluster.

K8s. IO /client-go provides the informer and clientset of k8S native resources, but the operation of custom resources is relatively inefficient. It needs to use REST API and Dynamic Client to operate, and realize deserialization and other functions by itself.

Code-generator provides the following tools to generate code for resources in K8S, making it easier to customize resources:

  • deepcopy-gen: Generates a deep copy object
  • client-gen: Generate standard operation methods for resources (get; list; watch; create; update; patch; delete)
  • informer-gen: generate informer, provide the event mechanism (AddFunc UpdateFunc, DeleteFunc) in response to a kubernetes event
  • lister-gen: provides a read-only cache layer for get and list methods

Code-generator integrates these gen’s and generates code for custom resources using the scripts generate-groups.sh and generate-internal-groups.sh.

1.2 Kubebuilder

Kubebuilder is a framework for building the Kubernetes API using Custom Resource Definitions (CRDS).

Similar to Web development frameworks like Ruby on Rails and SpringBoot, Kubebuilder can speed up and reduce developer management complexity to quickly build and publish the Kubernetes API in Go. It builds on the canonical techniques used to build the core Kubernetes API to provide simple abstractions that reduce boilerplate and hassle.

Resource + Controller = Operator, you can use Kubebuilder to write a custom Resource Operator.

Two, combined with the background

Both Kubebuilder and code-Generator can generate Kubernetes API code for CRD. In terms of code generation, the difference between the two is:

  • Kubebuilder does not generate informers, Listers, clientsets, whereas code-Generator does.
  • Kubebuilder generates Controller, Admission Webhooks, code-Generator does not.
  • Kubebuilder generates sse YAMl, code-generator does not.
  • Kubebuilder also comes with some other conveniences.

Using Kubebuilder can quickly generate CRD and the associated controller framework. However, since Kubebuilder does not generate clientset and other packages, it will be difficult for other services to manipulate CRD.

Together, you can use Kubebuilder to generate CRDS and a complete controller architecture, and code-Generator to generate Informers, Listers, Clientsets, and so on.

Three, operation steps

3.1 Dependent Components

  • Go version V1.15 +, v1.15.2
  • V3.8.8 kustomize v3.1.0 +
  • V2.3.2 kubebuilder v2.3.0 +
  • The controller – gen, v0.2.5

3.2 Initializing the Project

Install Kubebuilder: refer to the official document cloudnative. To/Kubebuilder…

1. Create a project

mkdir -p $GOPATH/src/my.domain/example
cd $GOPATH. / SRC/my domain/example kubebuilder init - domain. My domain tree - CL 2. ├ ─ ─ bin │ └ ─ ─ manager ├ ─ ─ the config │ ├ ─ ─ Certmanager │ ├ ─ ─ the default │ ├ ─ ─ manager │ ├ ─ ─ Prometheus │ ├ ─ ─ rbac │ └ ─ ─ webhook ├ ─ ─ Dockerfile ├ ─ ─. Mod ├ ─ ─. Sum ├── ├─ ├─ Exclude.org.txt └── PROJECT exclude.org.txtCopy the code

2. Create an API

kubebuilder create api --group example --version v1 --kind Guestbook Create Resource [y/n] y Create Controller [y/n] n ├── ├─ ├─ ├─ ├─ guestBook_types. go......Copy the code

Note:

If API /v1/guestbook_types.go is modified, execute the following command to update the code and manifests:

make && make manifests
Copy the code

3.3 use the code – the generator

3.3.1 Updating dependent versions

Go.mod after initializing the project:

Cat go.mod module my.domain/example go 1.13 require (k8s. IO /apimachinery v0.17.2k8s. IO /client-go v0.17.2 Sigs. K8s. IO/controller - the runtime v0.5.0)Copy the code

You need to update the initialized K8S library to the version you want to use, for example:

K8S_VERSION = v0.17.2 go get k8s. IO/client - go @$K8S_VERSION
go get k8s.io/apimachinery@$K8S_VERSION
Copy the code

3.3.2 rainfall distribution on 10-12 installation code generator

The K8S_VERSION must be the same as the k8s. IO /client-go version in go.mod.

** Note: ** needs to copy dependencies into vendor

K8S_VERSION = v0.17.2 go get k8s. IO/code - the generator @$K8S_VERSION
go mod vendor
Copy the code

3.3.3 Create and modify required files

You need to create the files required for code-generator in the API directory and add comments.

  • The new API/v1 / doc. Go

    ** Note: ** change groupName, package is consistent with API version.

    // +k8s:deepcopy-gen=package
    
    // Package v1 is the v1alpha1 version of the API.
    // +groupName=example.my.domain
    package v1
    Copy the code
  • The new API/v1 / register. Go

    ** Note: **package is consistent with the version of the API.

    package v1
    
    import (
    	"k8s.io/apimachinery/pkg/runtime/schema"
    )
    
    // SchemeGroupVersion is group version used to register these objects.
    var SchemeGroupVersion = GroupVersion
    
    // Resource takes an unqualified resource and returns a Group qualified GroupResource
    func Resource(resource string) schema.GroupResource {
    	return SchemeGroupVersion.WithResource(resource).GroupResource()
    }
    Copy the code
  • Modify the API /v1/{CRD}_types.go file to add a comment // + genClient

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

3.3.4 Preparing scripts

Prepare the following files in the project hack directory:

  • Create a hack/tools.go file

    // +build tools
    
    package tools
    
    import _ "k8s.io/code-generator"
    Copy the code
  • Create hack/update-codegen.sh, modify the corresponding variables according to the project:

    • MODULEgo.modconsistent
    • API_PKG=api, andapiKeep directories consistent
    • OUTPUT_PKG=generated/example, consistent with the group specified when generating Resource
    • GROUP=exampleIs the same as the group specified when Resource is generated
    • VERSION=v1Is the same as the version specified when the Resource was generated
    #! /usr/bin/env bash
    
    set -o errexit
    set -o nounset
    set -o pipefail
    
    # note:
    Kubebuilder2.3.2 API directory structure code-generator cannot be used directly (API /${GROUP}/${VERSION})
    
    # corresponding to go mod init <module>
    MODULE=my.domain/example
    # api package
    APIS_PKG=api
    # generated output package
    OUTPUT_PKG=generated/example
    # group-version such as foo:v1alpha1
    GROUP=example
    VERSION=v1
    GROUP_VERSION=${GROUP}:${VERSION}
    
    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)}
    
    rm -rf ${OUTPUT_PKG}/{clientset,informers,listers}
    
    # 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,informer,lister" \
    bash "${CODEGEN_PKG}"/generate-groups.sh all \
      ${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}/.. /.. /.."
    Copy the code

    Note:

    1. The API directory structure code-generator generated by kubebuilder2.3.2 cannot be used directly (the API is provided byapi/${VERSION}Moving toapi/${GROUP}/${VERSION})
  • Modify the Makefile to add build commands

    update-codegen:
    	chmod +x ./hack/update-codegen.sh
    	./hack/update-codegen.sh
    Copy the code

3.3.5 Generating code

Make update-codeGen at the root of the project to generate the following code structure:

. ├ ─ ─ API │ ├ ─ ─ example │ │ └ ─ ─ v1 │ │ ├ ─ ─ doc. Go │ │ ├ ─ ─ groupversion_info. Go │ │ ├ ─ ─ guestbook_types. Go │ │ ├ ─ ─ Register. Go │ │ └ ─ ─ zz_generated. Deepcopy. Go ├ ─ ─ generated │ └ ─ ─ example │ ├ ─ ─ clientset │ ├ ─ ─ informers │ └ ─ ─ listersCopy the code

Custom resource objects can then be manipulated through packages such as Clientset.

Matters needing attention:

The API directory structure generated by kubebuilder2.3.2 is API /v1, while the API directory structure required by code-Generator is API /example/v1, which adds a group layer.

reference

Github.com/kubernetes-…

Github.com/kubernetes/…

Cloud.tencent.com/developer/a…

Blog.csdn.net/sixinchao_1…