例子

本文使用例子,过一遍 Kubebuilder 制作 K8S CDR 的流程

例子功能:

  • kubectl apply 创建 CRD 实例时,打印日志
  • kubectl delete 删除 CRD 实例时,打印日志

例子名为: example1

生成 example1 模板文件

mkdir -p example1
pushd example1
go mod init example1
kubebuilder init
kubebuilder create api --group demo --version v1 --kind Example1 --resource true --controller true --namespaced true
popd

主要 3 行命令:

命令说明
go mod initkubebuilder 使用 golang 编程。因此创建一个 golang 项目
kubebuilder init有不少参数,主要填写这个 CRD 一些信息,如工程名、制作者、许可证等等
kubebuilder create api生成 CRD 模板文件

这里着重介绍下 kubebuilder create api 的参数 : group version kind

这 3 个参数,定义了 CRD 的名称,如 example1 完成后,K8S 就多了一种资源:

[fananchong@qa4-haidao kubebuilder_sample]$ kubectl api-resources -o wide | grep demo
example1s                                      demo.my.domain/v1                      true         Example1                         [delete deletecollection get list patch create update watch]

example1 制作流程

包括:

  1. 如何填写 api/v1/example1_types.go ,简单定义一个 GVK
  2. 如何填写 controllers/example1_controller.go ,这里打印下信息
  3. 如何安装 Example1 这个 CRD
  4. 如何调试验证

下面,分别讲解

Step1 填写 api/v1/example1_types.go

这里的例子,定义一个简单 CRD ,主要过一遍流程

目标,能正常 apply/delete 这个 CRD:

apiVersion: demo.my.domain/v1
kind: Example1
metadata:
  name: example-1
  namespace: default
spec:
  custom1: xxxx
  custom2: 10

对应 api/v1/example1_types.go 文件修改:

type Example1Spec struct {
	//+kubebuilder:validation:Required
	//+kubebuilder:validation:Type=string
	Custom1 string `json:"custom1,omitempty"`

	//+kubebuilder:validation:Required
	//+kubebuilder:validation:Type=integer
	//+kubebuilder:validation:Minimum=0
	Custom2 *int32 `json:"custom2,omitempty"`
}

然后执行:

make manifests

会自动生成对应的配置到 config 目录下 config/crd/bases/demo.my.domain_example1s.yaml

注释,如:

//+kubebuilder:validation:Required
//+kubebuilder:validation:Type=string

是可以让 K8S 做些字段检查。参考文档: https://book.kubebuilder.io/reference/markers/crd-validation.html

Step2 填写 controllers/example1_controller.go

同样目的是过一遍流程,主要功能是简单的打印下日志:

func (r *Example1Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
	logger := log.FromContext(ctx)
	example := &v1.Example1{}
	err := r.Get(ctx, req.NamespacedName, example)
	if err != nil {
		if errors.IsNotFound(err) {
			logger.Info(fmt.Sprintf("[delete] Namespace:%v Name:%v", req.Namespace, req.Name))
			return ctrl.Result{}, nil
		}
		logger.Error(err, "Error occurred while fetching the resource")
		return ctrl.Result{}, err
	}
	logger.Info(fmt.Sprintf("[apply] Namespace:%v Name:%v custom1:%v custom2:%v", example.Namespace, example.Name, example.Spec.Custom1, example.Spec.Custom2))
	return ctrl.Result{}, nil
}

代码分析:

  • r.Get 获取 CRD 对象

Step3 安装 CRD Example1

make install
kubectl api-resources -o wide | grep demo
kubectl get crd

Step4 调试验证

  1. 执行 example1 ,能实时查看 CRD 的 log

    make build
    ./bin/manager --metrics-bind-address=":7070" --health-probe-bind-address=":7071"
    
  2. 使用这个 CRD

    kubectl apply -f example1.yaml
    kubectl get example1s
    kubectl get example1s.demo.my.domain
    kubectl delete -f example1.yaml
    

其他

正式部署 CRD 控制器,需要执行:

make docker-build docker-push IMG=<some-registry>/<project-name>:tag
make deploy IMG=<some-registry>/<project-name>:tag

以上

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐