例子
本文使用例子,过一遍 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 init | kubebuilder 使用 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 制作流程
包括:
- 如何填写 api/v1/example1_types.go ,简单定义一个 GVK
- 如何填写 controllers/example1_controller.go ,这里打印下信息
- 如何安装 Example1 这个 CRD
- 如何调试验证
下面,分别讲解
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 调试验证
-
执行 example1 ,能实时查看 CRD 的 log
make build ./bin/manager --metrics-bind-address=":7070" --health-probe-bind-address=":7071"
-
使用这个 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
以上