api/v1/application_types.go
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // Important: Run "make" to regenerate code after modifying this file // Product 该应用所属的产品 Product string `json:"product,omitempty"` }修改之后执行一下 make manifests generate 可以发现已经生成了相关的字段,并且代码中的字段注释也就是 yaml 文件中的注释
# make manifests generate /Users/zisefeizhu/linkun/goproject/kubedev/bin/controller-gen "crd:trivialVersions=true,preserveUnknownFields=false" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases /Users/zisefeizhu/linkun/goproject/kubedev/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."config/crd/bases/apps.lailin.xyz_applications.yaml
properties: product: description: Product 该应用所属的产品 type: string 实现 controllerkubebuilder 已经实现了 Operator 所需的大部分逻辑,所以只需要在 Reconcile 中实现业务逻辑就行了
./controllers/application_controller.go
func (r *ApplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { _ = log.FromContext(ctx) _ = r.Log.WithValues("application", req.NamespacedName) // your logic here r.Log.Info("app changed", "ns", req.Namespace) //r.Log.Info(fmt.Sprintf("1. %v", req)) // 打印入参 //r.Log.Info(fmt.Sprintf("2. %s", debug.Stack())) // 打印堆栈 return ctrl.Result{}, nil }逻辑修改好之后,先执行 make install 安装 CRD,然后执行 make run运行 controller
make run /Users/zisefeizhu/linkun/goproject/kubedev/bin/controller-gen "crd:trivialVersions=true,preserveUnknownFields=false" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases /Users/zisefeizhu/linkun/goproject/kubedev/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..." go fmt ./... go vet ./... go run ./main.go I0210 16:23:51.408872 35770 request.go:655] Throttling request took 1.029677459s, request: GET:https://192.168.101.45:6443/apis/storage.k8s.io/v1beta1?timeout=32s 2022-02-10T16:23:52.683+0800 INFO controller-runtime.metrics metrics server is starting to listen {"addr": ":8080"} 2022-02-10T16:23:52.684+0800 INFO setup starting manager 2022-02-10T16:23:52.684+0800 INFO controller-runtime.manager starting metrics server {"path": "/metrics"} 2022-02-10T16:23:52.684+0800 INFO controller-runtime.manager.controller.application Starting EventSource {"reconciler group": "apps.zise.feizhu", "reconciler kind": "Application", "source": "kind source: /, Kind="} 2022-02-10T16:23:52.786+0800 INFO controller-runtime.manager.controller.application Starting Controller {"reconciler group": "apps.zise.feizhu", "reconciler kind": "Application"} 2022-02-10T16:23:52.786+0800 INFO controller-runtime.manager.controller.application Starting workers {"reconciler group": "apps.zise.feizhu", "reconciler kind": "Application", "worker count": 1}部署一个测试的 crd kubectl apply -f config/samples/apps_v1_application.yaml
apiVersion: apps.lailin.xyz/v1 kind: Application metadata: name: application-sample spec: # Add fields here product: test然后可以看到之前写的日志逻辑已经触发
022-02-10T16:25:27.946+0800 INFO controllers.Application app changed {"ns": "default"} Kubebuilder 注释在生成的代码当中我们可以看到很多 //+kubebuilder:xxx 开头的注释,对 Go 比较熟悉的同学应该知道这些注释是给对应的代码生成器服务的,在 Go 中有一个比较常用的套路就是利用 go gennerate生成对应的 go 代码。
kubebuilder 使用 controller-gen(https://github.com/kubernetes-sigs/controller-tools/blob/master/cmd/controller-gen/main.go)生成代码和对应的 yaml 文件,这其中主要包含 CRD 生成、验证、处理还有 WebHook 的 RBAC 的生成功能,下面我简单介绍一下,完整版可以看 kubebuilder 的官方文档(https://master.book.kubebuilder.io/quick-start.html)
CRD 生成
//+kubebuilder:subresource:status 开启 status 子资源,添加这个注释之后就可以对 status进行更新操作了
//+groupName=nodes.lailin.xyz 指定 groupname
//+kubebuilder:printcolumn 为 kubectl get xxx 添加一列,这个挺有用的
……
CRD 验证,利用这个功能,只需要添加一些注释,就给可以完成大部分需要校验的功能
//+kubebuilder:default:= 给字段设置默认值
//+kubebuilder:validation:Pattern:=string 使用正则验证字段
……
Webhook
//+kubebuilder:webhook 用于指定 webhook 如何生成,例如我们可以指定只监听 Update 事件的 webhook
RBAC 用于生成 rbac 的权限
//+kubebuilder:rbac
参考文档:https://lailin.xyz/post/operator-01-overview.html
https://blog.csdn.net/boling_cavalry/article/details/113089414