kubebuilder扩展k8s
kubebuilder是个专门用于开发k8s的框架
k8s有很多资源如deployment,cronjob等资源,这些资源的行为则由位于controller-manager中的各个资源控制器来实现逻辑,
安装
在https://github.com/kubernetes-sigs/kubebuilder/releases下载合适的二进制文件并放入path中
术语
- GV: Api Group和Version
- API Group 是相关API功能的集合,
- 每个 Group 拥有一或多个Versions
- GVK: Group Version Kind
- 每个GV都包含很多个api 类型,称之为Kinds,不同Version同一个Kinds可能不同
- GVR: Group Version Rsource
- Resource 是 Kind 的对象标识,一般来Kind和Resource 是1:1 的,但是有时候存在 1:n 的关系,不过对于Operator来说都是 1:1 的关系
1 | apiVersion: apps/v1 # 这个是 GV,G 是 apps,V 是 v1 |
根据GVK K8s就能找到你到底要创建什么类型的资源,根据你定义的Spec创建好资源之后就成为了Resource,也就是GVR。GVK/GVR就是K8s资源的坐标,是我们创建/删除/修改/读取资源的基础
类似这样的关系/group/version/kind
示例
项目初始化
完整代码:https://github.com/NatureLR/code-example/tree/master/operator
需求背景
我们在部署服务的时候经常需要同时部署deployment和svc这样很复杂,于是自定义一个资源叫appx,让appx来创建svc和deployment
初始化文件夹
在项目文件夹下执行
1 | kubebuilder init --repo github.com/naturelr/code-example/operator --domain naturelr.cc --skip-go-version-check |
这个时候目录下会产生一些文件
1 | ├── Dockerfile # 编译docker镜像 |
创建api模板
执行下面的命令,创建api,期间会问你是不是需要创建Resource和Controller,这里我们都选y
1 | kubebuilder create api --group appx --version v1 --kind Appx |
完成之后多了一些目录
1 | . |
实现
定义字段
在api/v1/application_types.go
中的AppxSpec写上需要的字段
1 | type AppxSpec struct { |
然后执行make manifests generate
命令生成crd文件
生成的crd文件在config/crd/bases/
中
实现控制器
有crd只能在k8s中定义cr但是k8s并不知道如何处理这些cr,所以我们要实现控制器来处理这些逻辑
我们需要实现的控制器逻辑在controllers/application_controller.go
中的Reconcile
函数中
逻辑改完之后就需要上测试了,执行make install
安装crd到集群,注意他会安装到~/.kube/config
这个配置文件中的集群
然后执行make run
运行控制器,他会打印很多日志
- 获取cd,拿到cr中定义的镜像和端口号
1 | appx := &appxv1.Appx{} |
- 拿到信息之后需要创建对应的deployment对象和service对象,需要特别注意的是要管理创建的资源,不然删除的不会删除创建的子资源
1 | svc := &apiv1.Service{} |
- 如果已经有此资源,那么可能就需要更新资源了
1 | // svc |
到此一个简单的crd的控制逻辑就完成了
status
上面创建的cr当查看的时候并不会显示status
- 在
api/v1/appx_types.go
中找到AppxStatus
,添加上合适的字段
1 | // AppxStatus defines the observed state of Appx |
- 在
controllers/application_controller.go
中更新status字段
1 | appx.Status.Workload = *deploy.Spec.Replicas |
- 上面自会显示在get xx -o yaml当中,当我们想显示在 get xxx -o wide中时需要在
api/v1/appx_types.go
中添加注释,具体参考https://book.kubebuilder.io/reference/generating-crd.html
1 | // 注意type要对应上字段!!! |
- 同样需要重新生成crd并且要安装
event事件
evnet事件,有的时候告诉我们一些重要的信息
- 在
controllers/application_controller.go
中增加字段
1 | // AppxReconciler reconciles a Appx object |
- 调用
1 | r.Recorder.Event(appx, apiv1.EventTypeNormal, "找到cr", appx.Name) |
- 在
main.go
中加上Recorder的初始化逻辑
1 | if err = (&controllers.AppxReconciler{ |
1 | kubectl get event |
常用命令
1 | 初始化 |
参考资料
https://book.kubebuilder.io/introduction.html
https://lailin.xyz/post/operator-03-kubebuilder-tutorial.html