Kubebuilder 使用教程

Kubebuilder 是什么

kubebuilder 是使用自定义资源(CRD)构建 Kubernetes API 的框架。Kubebuilder提高了开发人员在Go中快速构建和发布Kubernetes api的速度,降低了开发管理的复杂性。

Kubebuilder 如何使用

我们通过向 Kubernetes 集群添加一个自定义 Cluster 来了解 Kubebuilder 如何使用。 其主要步骤如下:

  1. 创建一个项目
  2. 创建一个API
  3. 定义CRD
  4. 实现controller
  5. 测试

创建项目

  1. 创建目录ipes-cmp 并进入执行 go mod init ipes-cmp 来告诉 kubebuilder 和 Go module 的基本导入路径。

  2. 执行 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 ; 是执行了以下两步:

  1. make manifests # 生成CRD资源
  2. 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)

Posts in this Series