Kubebuilder 使用教程
Kubebuilder 是什么
kubebuilder 是使用自定义资源(CRD)构建 Kubernetes API 的框架。Kubebuilder提高了开发人员在Go中快速构建和发布Kubernetes api的速度,降低了开发管理的复杂性。
Kubebuilder 如何使用
我们通过向 Kubernetes 集群添加一个自定义 Cluster 来了解 Kubebuilder 如何使用。 其主要步骤如下:
- 创建一个项目
- 创建一个API
- 定义CRD
- 实现controller
- 测试
创建项目
创建目录ipes-cmp 并进入执行 go mod init ipes-cmp 来告诉 kubebuilder 和 Go module 的基本导入路径。
执行 kubebuilder init 命令,初始化一个新项目。示例如下。 kubebuilder init --domain ipes-cmp
--domain: 项目的域名
创建一个API
运行下面的命令,创建一个新的 API(组/版本)为 “cluster/v1”,并在上面创建新的 Kind(CRD) “Cluster”。
1 kubebuilder create api --group cluster --version v1 --kind Cluster
目录结构:
1
2在 Create Resource [y/n] 和 Create Controller [y/n] 中按y,创建文件 api/v1/cluster_types.go ,
3该文件中定义相关 API ,而针对于这一类型 (CRD) 的对账业务逻辑生成在 controller/cluster_controller.go 文件中。
4.
5├── Dockerfile
6├── Makefile # 这里定义了很多脚本命令,例如运行测试,开始执行等
7├── PROJECT # 这里是 kubebuilder 的一些元数据信息
8├── api
9│ └── v1
10│ ├── cluster_types.go #定义 Spec 和 Status
11│ ├── groupversion_info.go # 包含了关于 group-version 的一些元数据
12│ └── zz_generated.deepcopy.go
13├── bin
14│ └── controller-gen
15├── config
16│ ├── crd # 部署 crd 所需的 yaml, 自动生成, 只需要修改了 v1 中的 go 文件之后执行 make generate 即可
17│ │ ├── kustomization.yaml
18│ │ ├── kustomizeconfig.yaml
19│ │ └── patches
20│ │ ├── cainjection_in_clusters.yaml
21│ │ └── webhook_in_clusters.yaml
22│ ├── default # 一些默认配置
23│ │ ├── kustomization.yaml
24│ │ ├── manager_auth_proxy_patch.yaml
25│ │ └── manager_config_patch.yaml
26│ ├── manager
27│ │ ├── controller_manager_config.yaml
28│ │ ├── kustomization.yaml
29│ │ └── manager.yaml
30│ ├── prometheus # 监控指标数据采集配置
31│ │ ├── kustomization.yaml
32│ │ └── monitor.yaml
33│ ├── rbac # 部署所需的 rbac 授权 yaml
34│ │ ├── auth_proxy_client_clusterrole.yaml
35│ │ ├── auth_proxy_role.yaml
36│ │ ├── auth_proxy_role_binding.yaml
37│ │ ├── auth_proxy_service.yaml
38│ │ ├── cluster_editor_role.yaml
39│ │ ├── cluster_viewer_role.yaml
40│ │ ├── kustomization.yaml
41│ │ ├── leader_election_role.yaml
42│ │ ├── leader_election_role_binding.yaml
43│ │ ├── role_binding.yaml
44│ │ └── service_account.yaml
45│ └── samples # 这里是 crd 示例文件,可以用来部署到集群当中
46│ └── cluster_v1_cluster.yaml
47├── controllers
48│ ├── cluster_controller.go
49│ └── suite_test.go
50├── go.mod
51├── go.sum
52├── hack
53│ └── boilerplate.go.txt
54└── main.go
定义CRD
修改 cluster_type.go 文件添加地域信息:
1// ClusterSpec defines the desired state of Cluster
2type ClusterSpec struct {
3 // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
4 // Important: Run "make" to regenerate code after modifying this file
5
6 // Foo is an example field of Cluster. Edit cluster_types.go to remove/update
7 Foo string `json:"foo,omitempty"`
8
9 // Region represents the region of the member cluster locate in.
10 // +optional
11 Region string `json:"region,omitempty"`
12}
修改完之后执行 make manifests generate ,可以生成对应的config/bases/cluster.ipes.io_clusters.yaml文件。可以看到spec信息如下:
1 spec:
2 description: ClusterSpec defines the desired state of Cluster
3 properties:
4 foo:
5 description: Foo is an example field of Cluster. Edit cluster_types.go
6 to remove/update
7 type: string
8 region:
9 description: Region represents the region of the member cluster locate
10 in.
11 type: string
12 type: object
实现controller
controller的逻辑框架kubebuilder已经帮我们完成,我们只需要完成最核心的函数 Reconcile即可;
1#controllers/cluser_controller.go
2func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
3 _ = r.Log.WithValues("cluster", req.NamespacedName)
4
5 r.
6
7 return ctrl.Result{}, nil
8}
在这里我们获取cluster信息并打印
1func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
2 _ = r.Log.WithValues("cluster", req.NamespacedName)
3
4 cluster := &clusterv1.Cluster{}
5 if err := r.Client.Get(context.TODO(), req.NamespacedName, cluster); err != nil {
6 // The resource may no longer exist, in which case we stop processing.
7 if apierrors.IsNotFound(err) {
8 return ctrl.Result{}, nil
9 }
10 return ctrl.Result{Requeue: true}, err
11 }
12 // your logic here
13 r.Log.Info("ipes cluster status change", "name", cluster.Name, "region", cluster.Spec.Region)
14 return ctrl.Result{}, nil
15}
测试
部署CRD资源
我们在实现了controller 的核心逻辑之后, 需要先将CRD注册到集群中, 具体命令:
1make install
这里make install ; 是执行了以下两步:
- make manifests # 生成CRD资源
- bin/kustomize build config/crd | kubectl apply -f - #生成部署CRD, 并部署到集群中 如果集群不在本地, 可以分开执行这两步。
运行 controller
本地直接执行 make run 即可,我这里需要编译后,放到服务器上执行:
1➜ ~ ./ipes-cmp
22021-06-08T19:22:38.187+0800 INFO controller-runtime.metrics metrics server is starting to listen {"addr": ":8080"}
32021-06-08T19:22:38.188+0800 INFO setup starting manager
42021-06-08T19:22:38.188+0800 INFO controller-runtime.manager starting metrics server {"path": "/metrics"}
52021-06-08T19:22:38.188+0800 INFO controller-runtime.manager.controller.cluster Starting EventSource {"reconciler group": "cluster.ipes.io", "reconciler kind": "Cluster", "source": "kind source: /, Kind="}
62021-06-08T19:22:38.289+0800 INFO controller-runtime.manager.controller.cluster Starting Controller {"reconciler group": "cluster.ipes.io", "reconciler kind": "Cluster"}
72021-06-08T19:22:38.289+0800 INFO controller-runtime.manager.controller.cluster Starting workers {"reconciler group": "cluster.ipes.io", "reconciler kind": "Cluster", "worker count": 1}
添加一个测试例子
创建一个测试的集群
1apiVersion: cluster.ipes.io/v1
2kind: Cluster
3metadata:
4 name: test-cluster
5spec:
6 # Add fields here
7 region: beijing
1kubectl apply -f bj_cluster.yml # 部署测试集群
可以看到controller 输入日志,controller已经获取到关于cluster的信息。
12021-06-08T19:35:49.562+0800 INFO controllers.Cluster ipes cluster status change {"name": "test-cluster", "region": "beijing"}
总结
目前扩展 Kubernetes 的 API 的方式有创建 CRD、使用 Operator SDK 等方式,都需要写很多的样本文件(boilerplate),使用起来十分麻烦。为了能够更方便构建 Kubernetes API 和工具,就需要一款能够事半功倍的工具,与其他 Kubernetes API 扩展方案相比,kubebuilder 更加简单易用,并获得了社区的广泛支持。
参考
深入解析 Kubebuilder:让编写 CRD 变得更简单
Kubebuilder
Kubernetes中文指南/云原生应用架构实践手册(201910)