kubebuilder是专门用于k8s开发的框架。
k8s 有很多资源,例如部署、cronjobs 和其他资源。 这些资源行为由controller-manager中的每个资源控制器实现。
安装
https://github.com/kubernetes-sigs/kubebuilder /发布创建一个文件并将其放置在您的路径中。
术语
GV:API 组和版本
API 组是相关 API 函数的集合。
每个组都有一个或多个版本
GVK:组版本类型
每个 GV 都有许多称为“包含”的 API 类型。 同一类型的不同版本可能会有所不同。
GVR:组版本资源
资源是一种类型的对象标识符。 一般来说,Kind 和 Resource 是 1:1,有时存在 1:n 关系,但 Operator 始终是 1:1 关系。
apiVersion: apps/v1 # 这是 GV,G 是 app,V 是 v1kind: Deployment # 这是 Kindsepc: # 另外它是一个分布式规范。 Resource
根据GVK K8s,可以勾选自己想要创建的资源类型,按照自己定义的规范进行创建如果是,这就是 GVK/GVR。 资源的坐标以及创建/删除/修改/读取资源的依据。
类似这样的关系/组/版本/类型
初始化项目
完整代码:https://github.comcom/NatureLR/code-example/tree/master/operator
需求背景
在很多地方部署服务时有些情况,需要同时部署deployment和svc,比较复杂,所以可以自定义一个叫appx的资源,在appx中添加svc。 并创建部署
初始化文件夹
在项目文件夹中运行
kubebuilder init --repo github.com/naturelr/code-示例/运算符 --域 Naturelr .cc - -skip-go-version-check
此时目录下会生成一些文件。
§── Dockerfile # 编译Docker镜像。 §── Makefile # 编译部署相关脚本。 所有常用功能都是Surface §── PROJECT # 项目描述 §── config # 该目录包含集群上需要安装的一些文件 │ §──default # 默认配置 │ §── manag er # crd 文件 │ §─ ─ prometheus # ServiceMonitor等监控相关 │ └── rbac # rbac文件§── go.mod§── ─ go.sum∴── hack │ └──样板.go.txt └── main.go6目录,24个文件 创建API模板
运行以下命令访问API 在此过程中,会询问您是否需要创建资源和控制器,此处选择 y kubebuilder create api --group appx - -version v1 --kind Appx。
一旦完成,就会多出几个目录
。 §── Dockerfile ∴── Makefile §── 项目 §── api│ └── v1 # 自定义 API -------------- bin│ └─ ─controller-gen # 生成文件的程序 §── configutils──controllers│ §── appx_controller.go # 在此编写控制逻辑 │ └── suite_test .go # 测试用例 §── go.mod ├── ─ go.sum│hack│ └─boilerplate.go.txt └─main.go12目录,10 文件实现定义字段
在 api/v1/application_types.go 中写入 AppxSpec 必填字段
type AppxSpec struct { // 插入附加规格字段 -desired Cluster state //重要:修改此文件后,运行“make”重新生成代码。 //Foo 是 Appx 中的示例字段。 编辑 appx_types.go 并输入图像字符串 `json:"image,omitempty"` port int `json:"port,omitempty"`}<p style="margin-top: 0px; margin-bottom: 20px ; 颜色: rgb(85, 85, 85); 字体-系列: Lato, "PingFang SC", "Microsoft 使用 makemanifestsgenerate 命令生成 crd 文件。
生成的crd文件位于config/crd/bases/
实现控制器
是的,crd只能在k8s中定义cr,但是k8s可以定义这些cr
你需要实现的控制器逻辑在controllers/application_controller.go中在协调函数中:
更改逻辑后需要测试一下。make install 通过运行以下命令在集群上安装 crd: 请注意,crd 安装在集群上的配置文件 ~/.kube/config
然后运行make run,这会运行控制器并打印出大量日志。
CD。 cr
appx := &appxv1.Appx{}if err := r.Get( ctx, req.NamespacedName, appx); err != nil { return ctrl.Result{}, 呃r}
获得信息后,您需要创建相应的部署和服务对象。 管理所创建的资源时必须特别小心。 否则,删除资源不会删除创建的任何子资源。
svc := &apiv1.Service {}if e rr := r.Get(ctx, req.NamespacedName, svc ); err != nil { if client.IgnoreNotFound(err) != nil { return ctrl.Result {}, err// 如果出现错误,没有找到,则直接返回错误 } // 如果没有找到,则创建资源 if svc.Name == "" { l.Info("创建服务:" , "Name", appx.Name) svc = &apiv1.Service{ 对象meta:metav1.ObjectMeta{ 名称: req.Name,命名空间:req.Namespace,},规范:apiv1.ServiceSpec{ 选择器:map[string]string{"app": req.Name},端口:[]apiv1 .ServicePort{{ 端口:int32(appx.Spec .端口),目标端口:intstr.FromInt(appx.Spec.Port), }, }, }, } //将appx与部署关联起来 if err :=controllerutil.SetOwnerReference(appx, svc, r.Scheme); err != nil { Return ctrl.Result{}, err } if err := r.Create(ctx, svc) ; 错误 != nil { 返回 ctrl.Result{}, 错误 } l.Info("服务已完全创建") }}
如果此资源已存在,您可能需要更新该资源
// svcsvc .Spec.Ports = []apiv1 . ServicePort{{端口: int32(appx.Spec.Port)}}l.Info("更新服务", "端口", appx.Spec.Image)if err := r.Update(ctx, svc); err != nil { return ctrl.Result{}, err}l.Info("服务更新完成")
现在简单的crd控制逻辑就完成了。 /p>状态
上面创建的cr不会显示状态如果:已看到
在api/v1/appx_types.go中找到AppxStatus并添加适当的字段
// AppxStatus定义了观察到的状态Appxtype AppxStatus struct { // 插入附加状态字段 - 定义 观察到的( );集群状态 //重要:修改此文件后,运行“make”重新生成代码。 //需要json标签。 Workload int32 `json:"workload"` Svc string `json:"svc"`}
控制器内更新 s/application_controller.go 状态字段
appx.Status.Workload = *deploy.Spec.Replicasappx. Status.Svc = fmt.Sprintf("%d", svc.Spec.Ports[0].Port) r.Status().Update(ctx, appx)
上面会出现在 get xx -o yaml 中。 如果想以 get xxx -o width 显示,需要在 api/v1/appx_types.go 中添加注释。 有关更多信息,请参阅 https://book.kubebuilder.io/reference/ generated -crd.html
//。 请注意,类型必须与顶部字段相对应。 ! ! //+kubebuilder:printcolumn:JSONPath=".status.workload",name=Workload,type=integer//+kubebuilder:printcolumn:JSONPath=".status.svc",name=Svc,type=string
crd 也必须重新生成。 已安装
事件事件
evnet 事件,有时会告诉我们重要信息
p>
添加字段to controllers/application_controller.go
// AppxReconciler 协调 Appx objecttype AppxReconciler struct { client.Client Scheme *runtime.Scheme Recorder record.EventRecorder//添加事件结构}
调用
r.Recorder.Event(appx, apiv1.EventTypeNormal, "find cr", appx.Name)
Recorder初始化添加转换逻辑到main.go
if err = (&controllers.AppxReconciler{ Client: mgr.GetClient(), Scheme:mgr.GetScheme(), 记录器: mgr.GetEventRecorderFor("Appx"), //+}).SetupWithManager(mgr); err != nil { setupLog.Error(err, "无法创建控制器", "控制器", "Appx") os.Exit(1)}$ kubectl get eventLAST SEEN TYPE REASON OBJECT MESSAG E2m55s 正常查找 cr Appx 4s 正常查找 cr Appx/foo foo 常用命令# 初始化 kubebuilder init --repo github.com/naturelr/code-example/operator --domain Naturelr.cc [ k4]-skip- go[ k4]version-check# 创建 apikubebuilder api --group appx 创建 --版本 v1 --type Appx# create webhookkubebuilder webhook 创建 --组节点 --版本 v1 --type Appx [ k4][ k4]default ting --programmatic-validation# 生成文件 make 生成清单 # crd 等文件 make install# 本地调试与执行 make run 参考资料
评论前必须登录!
注册