Kubernetes CRD 控制器开发系列 Part 1: 初识 CRD 和 Operator 框架
文章介绍了关于 CRD controller 开发的目的、框架以及开源 kubebuilder
脚手架的简单使用。
1.Custom Resource Define
Custom Resource Define
简称 CRD,是 Kubernetes(v1.7+)为提高可扩展性,让开发者去自定义资源的一种方式。CRD 资源可以动态注册到集群中,注册完毕后,用户可以通过 kubectl 来创建访问这个自定义的资源对象,类似于操作 Pod 一样。不过需要注意的是 CRD 仅仅是资源的定义而已,需要一个对应的控制器去监听 CRD 的各种事件来添加自定义的业务逻辑。
2.YAML 文件格式
我们可以定义一个如下所示的 CRD 资源清单文件:
1# crd-demo.yaml
2apiVersion: apiextensions.k8s.io/v1
3kind: CustomResourceDefinition
4metadata:
5 # name 必须匹配下面的spec字段:<plural>.<group>
6 name: crontabs.stable.example.com
7spec:
8 # group 名用于 REST API 中的定义:/apis/<group>/<version>
9 group: stable.example.com
10 # 列出自定义资源的所有 API 版本
11 versions:
12 - name: v1beta1 # 版本名称,比如 v1、v2beta1 等等
13 served: true # 是否开启通过 REST APIs 访问 `/apis/<group>/<version>/...`
14 storage: true # 必须将一个且只有一个版本标记为存储版本
15 schema: # 定义自定义对象的声明规范
16 openAPIV3Schema:
17 description: Define CronTab YAML Spec
18 type: object
19 properties:
20 spec:
21 type: object
22 properties:
23 cronSpec:
24 type: string
25 image:
26 type: string
27 replicas:
28 type: integer
29 # 定义作用范围:Namespaced(命名空间级别)或者 Cluster(整个集群)
30 scope: Namespaced
31 names:
32 # kind 是 singular 的一个驼峰形式定义,在资源清单中会使用
33 kind: CronTab
34 # plural 名字用于 REST API 中的定义:/apis/<group>/<version>/<plural>
35 plural: crontabs
36 # singular 名称用于 CLI 操作或显示的一个别名
37 singular: crontab
38 # shortNames 相当于缩写形式
39 shortNames:
40 - ct
我们在创建资源的时候,肯定不是任由我们随意去编写 YAML 文件的,当我们把上面的 CRD 文件提交给 Kubernetes 之后,Kubernetes 会对我们提交的声明文件进行校验,从定义可以看出 CRD 是基于 OpenAPI v3 schem 进行规范的。
使用 kubectl
来创建这个 CRD 资源清单:
1[root@master ~]# kubectl apply -f crd-demo.yaml
2customresourcedefinition.apiextensions.k8s.io/crontabs.stable.example.com created
然后我们就可以使用这个 API 端点来创建和管理自定义的对象,这些对象的类型就是上面创建的 CRD 对象规范中的 CronTab
。
现在在 Kubernetes 集群中我们就多了一种新的资源叫 crontabs.stable.example.com
,我们就可以使用它来定义一个 CronTab
资源对象了,这个自定义资源对象里面可以包含的字段我们在定义的时候通过 schema
进行了规范,比如现在我们来创建一个如下所示的资源清单:
1# crd-crontab-demo.yaml
2apiVersion: "stable.example.com/v1beta1"
3kind: CronTab
4metadata:
5 name: my-new-cron-object
6spec:
7 cronSpec: "* * * * */5"
8 image: my-awesome-cron-image
直接创建这个对象:
1[root@master ~]# kubectl apply -f crd-crontab-demo.yaml
2crontab.stable.example.com/my-new-cron-object created
我们就可以用 kubectl
来管理我们这里创建 CronTab
对象了,比如:
1[root@master ~]# kubectl get ct # 简写
2NAME AGE
3my-new-cron-object 42s
4[root@master ~]# kubectl get crontab
5NAME AGE
6my-new-cron-object 88s
3.kubebuilder 脚手架使用
创建一个目录,然后在里面运行 kubebuilder init
命令,初始化一个新项目。
1$ cd go/src/github.com/peterliao96
2$ mkdir builder-demo
3$ cd builder-demo
4# 开启 go modules
5$ export GO111MODULE=on
6$ export GOPROXY=https://goproxy.cn
7$ kubebuilder init --domain ydzs.io --owner peterliao96 --repo github.com/peterliao96/builder-demo
8# 创建一个新的 API(组/版本)为 “webapp/v1”,并在上面创建新的 Kind(CRD) “Guestbook”
9$ kubebuilder create api --group webapp --version v1 --kind Guestbook
上面的命令会创建文件 api/v1/guestbook_types.go
,该文件中定义相关 API ,而针对于这一类型 (CRD) 的业务逻辑生成在 controller/guestbook_controller.go
文件中。
我们可以根据自己的需求去修改资源对象的定义结构,修改 api/v1/guestbook_types.go
文件:
1// api/v1/guestbook_types.go
2package v1
3
4import (
5 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
6)
7
8// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
9// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
10
11// GuestbookSpec defines the desired state of Guestbook
12type GuestbookSpec struct {
13 // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
14 // Important: Run "make" to regenerate code after modifying this file
15
16 // Foo is an example field of Guestbook. Edit guestbook_types.go to remove/update
17 Foo string `json:"foo,omitempty"`
18}
19
20// GuestbookStatus defines the observed state of Guestbook
21type GuestbookStatus struct {
22 // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
23 // Important: Run "make" to regenerate code after modifying this file
24}
25
26//+kubebuilder:object:root=true
27//+kubebuilder:subresource:status
28
29// Guestbook is the Schema for the guestbooks API
30type Guestbook struct {
31 metav1.TypeMeta `json:",inline"`
32 metav1.ObjectMeta `json:"metadata,omitempty"`
33
34 Spec GuestbookSpec `json:"spec,omitempty"`
35 Status GuestbookStatus `json:"status,omitempty"`
36}
37
38//+kubebuilder:object:root=true
39
40// GuestbookList contains a list of Guestbook
41type GuestbookList struct {
42 metav1.TypeMeta `json:",inline"`
43 metav1.ListMeta `json:"metadata,omitempty"`
44 Items []Guestbook `json:"items"`
45}
46
47func init() {
48 SchemeBuilder.Register(&Guestbook{}, &GuestbookList{})
49}
本文摘录于 Kubernetes 开发课文档中的 CRD介绍 和 kubebuilder 介绍。