kubebuilder是個專門用于開發(fā)k8s的框架
k8s有很多資源如deployment,cronjob等資源,這些資源的行為則由位于controller-manager中的各個資源控制器來實現(xiàn)邏輯,
在https://github.com/kubernetes-sigs/kubebuilder/releases下載合適的二進(jìn)制文件并放入path中
GV: Api Group和Version
API Group 是相關(guān)API功能的集合,
每個 Group 擁有一或多個Versions
GVK: Group Version Kind
每個GV都包含很多個api 類型,稱之為Kinds,不同Version同一個Kinds可能不同
GVR: Group Version Rsource
Resource 是 Kind 的對象標(biāo)識,一般來Kind和Resource 是1:1 的,但是有時候存在 1:n 的關(guān)系,不過對于Operator來說都是 1:1 的關(guān)系
apiVersion: apps/v1 # 這個是 GV,G 是 apps,V 是 v1kind: Deployment # 這個就是 Kindsepc: # 加上下放的 spec 就是 Resource了
根據(jù)GVK K8s就能找到你到底要創(chuàng)建什么類型的資源,根據(jù)你定義的Spec創(chuàng)建好資源之后就成為了Resource,也就是GVR。GVK/GVR就是K8s資源的坐標(biāo),是我們創(chuàng)建/刪除/修改/讀取資源的基礎(chǔ)
類似這樣的關(guān)系/group/version/kind
完整代碼:https://github.com/NatureLR/code-example/tree/master/operator
我們在部署服務(wù)的時候經(jīng)常需要同時部署deployment和svc這樣很復(fù)雜,于是自定義一個資源叫appx,讓appx來創(chuàng)建svc和deployment
在項目文件夾下執(zhí)行
kubebuilder init --repo github.com/naturelr/code-example/operator --domain naturelr.cc --skip-go-version-check
這個時候目錄下會產(chǎn)生一些文件
├── Dockerfile # 編譯docker鏡像 ├── Makefile # 編譯部署相關(guān)的腳本,常用功能都在里面 ├── PROJECT # 項目說明 ├── config # 這個目錄都是一些需要安裝到集群的文件 │ ├── default # 默認(rèn)配置 │ ├── manager # crd文件 │ ├── prometheus # 監(jiān)控相關(guān)的如ServiceMonitor │ └── rbac # rbac文件 ├── go.mod ├── go.sum ├── hack │ └── boilerplate.go.txt └── main.go 6 directories, 24 files
執(zhí)行下面的命令,創(chuàng)建api,期間會問你是不是需要創(chuàng)建Resource和Controller,這里我們都選y
kubebuilder create api --group appx --version v1 --kind Appx
完成之后多了一些目錄
. ├── Dockerfile ├── Makefile ├── PROJECT ├── api │ └── v1 # 我們自定義的api ├── bin │ └── controller-gen # 生成文件的程序 ├── config ├── controllers │ ├── appx_controller.go # 控制邏輯寫在這 │ └── suite_test.go # 測試用例 ├── go.mod ├── go.sum ├── hack │ └── boilerplate.go.txt └── main.go 12 directories, 10 files
在api/v1/application_types.go
中的AppxSpec寫上需要的字段
type AppxSpec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // Important: Run "make" to regenerate code after modifying this file // Foo is an example field of Appx. Edit appx_types.go to remove/update Image string `json:"image,omitempty"` Port int `json:"port,omitempty"`}
然后執(zhí)行make manifests generate
命令生成crd文件
生成的crd文件在config/crd/bases/
中
有crd只能在k8s中定義cr但是k8s并不知道如何處理這些cr,所以我們要實現(xiàn)控制器來處理這些邏輯
我們需要實現(xiàn)的控制器邏輯在controllers/application_controller.go
中的Reconcile
函數(shù)中
邏輯改完之后就需要上測試了,執(zhí)行make install
安裝crd到集群,注意他會安裝到~/.kube/config
這個配置文件中的集群
然后執(zhí)行make run
運(yùn)行控制器,他會打印很多日志
獲取cd,拿到cr中定義的鏡像和端口號
appx := &appxv1.Appx{}if err := r.Get(ctx, req.NamespacedName, appx); err != nil { return ctrl.Result{}, err}
拿到信息之后需要創(chuàng)建對應(yīng)的deployment對象和service對象,需要特別注意的是要管理創(chuàng)建的資源,不然刪除的不會刪除創(chuàng)建的子資源
svc := &apiv1.Service{}if err := r.Get(ctx, req.NamespacedName, svc); err != nil { if client.IgnoreNotFound(err) != nil { return ctrl.Result{}, err// 如果有錯誤且不是沒找到的話就直接返回錯誤 } // 沒找到就創(chuàng)建資源 if svc.Name == "" { l.Info("創(chuàng)建service:", "名字", appx.Name) svc = &apiv1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: req.Name, Namespace: req.Namespace, }, Spec: apiv1.ServiceSpec{ Selector: map[string]string{"app": req.Name}, Ports: []apiv1.ServicePort{{ Port: int32(appx.Spec.Port), TargetPort: intstr.FromInt(appx.Spec.Port), }, }, }, } // 關(guān)聯(lián) appx和deployment if err := controllerutil.SetOwnerReference(appx, svc, r.Scheme); err != nil { return ctrl.Result{}, err } if err := r.Create(ctx, svc); err != nil { return ctrl.Result{}, err } l.Info("創(chuàng)建service成功") }}
如果已經(jīng)有此資源,那么可能就需要更新資源了
// svcsvc.Spec.Ports = []apiv1.ServicePort{{Port: int32(appx.Spec.Port)}}l.Info("更新service", "port", appx.Spec.Image)if err := r.Update(ctx, svc); err != nil { return ctrl.Result{}, err}l.Info("service更新完成")
到此一個簡單的crd的控制邏輯就完成了
上面創(chuàng)建的cr當(dāng)查看的時候并不會顯示status
在api/v1/appx_types.go
中找到AppxStatus
,添加上合適的字段
// AppxStatus defines the observed state of Appxtype AppxStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster // Important: Run "make" to regenerate code after modifying this file // 必須要有json tag Workload int32 `json:"workload"` Svc string `json:"svc"`}
在controllers/application_controller.go
中更新status字段
appx.Status.Workload = *deploy.Spec.Replicas appx.Status.Svc = fmt.Sprintf("%d", svc.Spec.Ports[0].Port)r.Status().Update(ctx, appx)
上面自會顯示在get xx -o yaml當(dāng)中,當(dāng)我們想顯示在 get xxx -o wide中時需要在api/v1/appx_types.go
中添加注釋,具體參考https://book.kubebuilder.io/reference/generating-crd.html
// 注意type要對應(yīng)上字段!!! //+kubebuilder:printcolumn:JSONPath=".status.workload",name=Workload,type=integer //+kubebuilder:printcolumn:JSONPath=".status.svc",name=Svc,type=string
同樣需要重新生成crd并且要安裝
evnet事件,有的時候告訴我們一些重要的信息
在controllers/application_controller.go
中增加字段
// AppxReconciler reconciles a Appx objecttype AppxReconciler struct { client.Client Scheme *runtime.Scheme Recorder record.EventRecorder//增加事件結(jié)構(gòu)體}
調(diào)用
r.Recorder.Event(appx, apiv1.EventTypeNormal, "找到cr", appx.Name)
在main.go
中加上Recorder的初始化邏輯
if err = (&controllers.AppxReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), Recorder: mgr.GetEventRecorderFor("Appx"), //+}).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Appx") os.Exit(1)}
$ kubectl get event LAST SEEN TYPE REASON OBJECT MESSAGE 2m55s Normal 找到cr appx 4s Normal 找到cr appx/foo foo
# 初始化kubebuilder init --repo github.com/naturelr/code-example/operator --domain naturelr.cc --skip-go-version-check# 創(chuàng)建 apikubebuilder create api --group appx --version v1 --kind Appx# 創(chuàng)建webhookkubebuilder create webhook --group nodes --version v1 --kind Appx --defaulting --programmatic-validation# 生成文件make manifests generate# 安裝crd等文件make install# 本地調(diào)試運(yùn)行make run
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/127897.html
摘要:與通過來自定義監(jiān)控指標(biāo)自動擴(kuò)展是一種根據(jù)資源使用情況自動擴(kuò)展或縮小工作負(fù)載的方法。適配器刪除后綴并將度量標(biāo)記為計數(shù)器度量標(biāo)準(zhǔn)。負(fù)載測試完成后,會將部署縮到其初始副本您可能已經(jīng)注意到自動縮放器不會立即對使用峰值做出反應(yīng)。 k8s與HPA--通過 Prometheus adaptor 來自定義監(jiān)控指標(biāo) 自動擴(kuò)展是一種根據(jù)資源使用情況自動擴(kuò)展或縮小工作負(fù)載的方法。 Kubernetes中的自...
摘要:與通過來自定義監(jiān)控指標(biāo)自動擴(kuò)展是一種根據(jù)資源使用情況自動擴(kuò)展或縮小工作負(fù)載的方法。適配器刪除后綴并將度量標(biāo)記為計數(shù)器度量標(biāo)準(zhǔn)。負(fù)載測試完成后,會將部署縮到其初始副本您可能已經(jīng)注意到自動縮放器不會立即對使用峰值做出反應(yīng)。 k8s與HPA--通過 Prometheus adaptor 來自定義監(jiān)控指標(biāo) 自動擴(kuò)展是一種根據(jù)資源使用情況自動擴(kuò)展或縮小工作負(fù)載的方法。 Kubernetes中的自...
摘要:與通過來自定義監(jiān)控指標(biāo)自動擴(kuò)展是一種根據(jù)資源使用情況自動擴(kuò)展或縮小工作負(fù)載的方法。適配器刪除后綴并將度量標(biāo)記為計數(shù)器度量標(biāo)準(zhǔn)。負(fù)載測試完成后,會將部署縮到其初始副本您可能已經(jīng)注意到自動縮放器不會立即對使用峰值做出反應(yīng)。 k8s與HPA--通過 Prometheus adaptor 來自定義監(jiān)控指標(biāo) 自動擴(kuò)展是一種根據(jù)資源使用情況自動擴(kuò)展或縮小工作負(fù)載的方法。 Kubernetes中的自...
摘要:幫你揭開擋在你與容器云之間的那層神秘面紗,看看你的企業(yè)究竟適不適合選用基于的容器云管理平臺。那么,選擇什么樣的容器云平臺就已經(jīng)是箭在弦上的大事了。 本文簡單粗暴,直戳淚點(diǎn),ho,不,是直戳痛點(diǎn)。幫你揭開擋在你與容器云之間的那層神秘面紗,看看你的企業(yè)究竟適不適合選用基于K8S的容器云管理平臺。 企業(yè)對容器云平臺的需求現(xiàn)狀是什么? 眾所周知,Docker很火,一大批互聯(lián)網(wǎng)公司早已領(lǐng)先一步,...
摘要:如果上的資源耗盡,這類將無法成功調(diào)度。將這個資源及其對應(yīng)的設(shè)備個數(shù)記錄到更新到。 extended-resources extended-resources在k8s1.9中是一個stable的特性。可以用一句話來概括這個特性: 通過向apiserver發(fā)送一個patch node 的請求,為這個node增加一個自定義的資源類型,用于以該資源的配額統(tǒng)計和相應(yīng)的QoS的配置。 patch ...
閱讀 351·2024-11-07 18:25
閱讀 130598·2024-02-01 10:43
閱讀 914·2024-01-31 14:58
閱讀 879·2024-01-31 14:54
閱讀 82884·2024-01-29 17:11
閱讀 3176·2024-01-25 14:55
閱讀 2028·2023-06-02 13:36
閱讀 3108·2023-05-23 10:26