基于operator sdk编写一个k8s自定义资源管理应用
簡介:operator 是一種 kubernetes 的擴(kuò)展形式,可以幫助用戶以 Kubernetes 的聲明式 API 風(fēng)格自定義來管理應(yīng)用及服務(wù),operator已經(jīng)成為分布式應(yīng)用在k8s集群部署的事實標(biāo)準(zhǔn)了,在云原生時代系統(tǒng)想遷移到k8s集群上編寫operator應(yīng)用是必不可少的能力,這里介紹用 CoreOS 的 operator framework 工具如何快速構(gòu)建一個 operator 應(yīng)用。
CRD
在 Kubernetes 中我們使用的 Deployment, DamenSet,StatefulSet, Service,Ingress, ConfigMap, Secret 這些都是資源,而對這些資源的創(chuàng)建、更新、刪除的動作都會被成為為事件(Event),Kubernetes 的 Controller Manager 負(fù)責(zé)事件監(jiān)聽,并觸發(fā)相應(yīng)的動作來滿足期望(Spec),這種方式也就是聲明式,即用戶只需要關(guān)心應(yīng)用程序的最終狀態(tài)。當(dāng)我們在使用中發(fā)現(xiàn)現(xiàn)有的這些資源不能滿足我們的需求的時候,Kubernetes 提供了自定義資源(Custom Resource)和 opertor 為應(yīng)用程序提供基于 kuberntes 擴(kuò)展。
CRD 則是對自定義資源的描述(Custom Resource Definition),也就是介紹這個資源有什么屬性呀,這些屬性的類型是什么,結(jié)構(gòu)是怎樣的這類。
我們看一個postgres-operator的CRD:
apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata:name: postgresqls.acid.zalan.dolabels:app.kubernetes.io/name: postgres-operatorannotations:"helm.sh/hook": crd-install spec:group: acid.zalan.donames:kind: postgresqllistKind: postgresqlListplural: postgresqlssingular: postgresqlshortNames:- pgadditionalPrinterColumns:- name: Teamtype: stringdescription: Team responsible for Postgres CLusterJSONPath: .spec.teamId- name: Versiontype: stringdescription: PostgreSQL versionJSONPath: .spec.postgresql.version- name: Podstype: integerdescription: Number of Pods per Postgres clusterJSONPath: .spec.numberOfInstances- name: Volumetype: stringdescription: Size of the bound volumeJSONPath: .spec.volume.size ...從上面的 CRD 文件可以看到 CRD 主要包括apiVersion、kind、metadata和spec四個部分。其中最關(guān)鍵的是apiVersion和kind,apiVersion表示資源所屬組織和版本,apiVersion一般由APIGourp和Version組成,這里的 APIGourp 是apiextensions.k8s.io,Version 是v1beta1,相關(guān)信息可以通過kubectl api-resoures查看。kind表示資源類型,這里是CustomResourceDefinition,表示是一個自定義的資源描述。
operator是什么
CoreOS 在 2016 年底提出了 Operator 的概念,當(dāng)時的一段官方定義如下:
An Operator represents human operational knowledge in software, to reliably manage an application.operator 是一種 kubernetes 的擴(kuò)展形式,利用自定義資源對象(Custom Resource)來管理應(yīng)用和組件,允許用戶以 Kubernetes 的聲明式 API 風(fēng)格來管理應(yīng)用及服務(wù)。operator 定義了一組在 Kubernetes 集群中打包和部署復(fù)雜業(yè)務(wù)應(yīng)用的方法,operator主要是為解決特定應(yīng)用或服務(wù)關(guān)于如何運行、部署及出現(xiàn)問題時如何處理提供的一種特定的自定義方式。比如:
- 按需部署應(yīng)用服務(wù)(總不能用一大堆configmap來管理吧,也會很混亂~w(゚Д゚)w)
- 實現(xiàn)應(yīng)用狀態(tài)的備份和還原,完成版本升級,比如
- 數(shù)據(jù)庫 schema 或額外的配置設(shè)置的改動
- 為分布式應(yīng)用進(jìn)行master選舉,例如etcd,或者master-slave架構(gòu)的mysql集群。
operator SDK
operator SDK —— operator framework,是 CoreOS 公司開發(fā)和維護(hù)的用于快速創(chuàng)建 operator 的工具,可以幫助我們快速構(gòu)建 operator 應(yīng)用,類似的工具還有:
- KUDO (Kubernetes 通用聲明式 Operator)
- kubebuilder,kubernetes SIG 在維護(hù)的一個項目
- Metacontroller,可與 Webhook 結(jié)合使用,以實現(xiàn)自己的功能。
如果希望查看 Operator 生態(tài),可以上 http://operatorhub.io ,也可以將自己創(chuàng)建的應(yīng)用發(fā)布上去。
operator 安裝
安裝 operator sdk:
export RELEASE_VERSION=v0.13.0 curl -LO https://github.com/operator-framework/operator-sdk/releases/download/${RELEASE_VERSION}/operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu chmod +x operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu && sudo mkdir -p /usr/local/bin/ && sudo cp operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu /usr/local/bin/operator-sdk && rm operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu基于模板創(chuàng)建項目
用operator sdk 創(chuàng)建項目模板,這里用官方提供的一個sample-controller的模板:
operator-sdk new <controller-name> --repo github.com/kubernetes/sample-controller項目結(jié)構(gòu)目錄創(chuàng)建完成,如下:
$ operator-sdk new test-controller --repo github.com/kubernetes/sample-controller $ tree . ├── build │ ├── bin │ │ ├── entrypoint │ │ └── user_setup │ └── Dockerfile ├── cmd │ └── manager │ └── main.go ├── deploy │ ├── operator.yaml │ ├── role_binding.yaml │ ├── role.yaml │ └── service_account.yaml ├── go.mod ├── go.sum ├── pkg │ ├── apis │ │ └── apis.go │ └── controller │ └── controller.go ├── tools.go └── version└── version.go創(chuàng)建CRD
operator-sdk add api --api-version=<api的版本> --kind=<類型名稱>創(chuàng)建CRD后,多出來了文件夾:
$ operator-sdk add api --api-version=test.k8s.realibox.com/v1 --kind=RealiboxINFO[0000] Generating api version test.k8s.realibox.com/v1 for kind Realibox. INFO[0000] Created pkg/apis/test/group.go INFO[0002] Created pkg/apis/test/v1/realibox_types.go INFO[0002] Created pkg/apis/addtoscheme_test_v1.go INFO[0002] Created pkg/apis/test/v1/register.go INFO[0002] Created pkg/apis/test/v1/doc.go INFO[0002] Created deploy/crds/test.k8s.realibox.com_v1_realibox_cr.yaml INFO[0004] Created deploy/crds/test.k8s.realibox.com_realiboxes_crd.yaml INFO[0004] Running deepcopy code-generation for Custom Resource group versions: [test:[v1], ] INFO[0014] Code-generation complete. INFO[0014] Running CRD generation for Custom Resource group versions: [test:[v1], ] INFO[0014] Created deploy/crds/test.k8s.realibox.com_realiboxes_crd.yaml INFO[0014] CRD generation complete. INFO[0014] API generation complete. $ tree ... ├── pkg │ ├── apis │ │ ├── addtoscheme_test_v1.go │ │ ├── apis.go │ │ └── test │ │ ├── group.go │ │ └── v1 │ │ ├── doc.go │ │ ├── realibox_types.go │ │ ├── register.go │ │ └── zz_generated.deepcopy.go │ └── controller │ └── controller.go ...test 文件夾下面放得就是 CRD,我們通過pkg/apis/test/v1/*_types.go文件定義我們的CRD結(jié)構(gòu),主要是Spec和Status:
vim pkg/apis/test/v1/realibox_types.go ... // RealiboxSpec defines the desired state of Realibox type RealiboxSpec struct {// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster// Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file// Add custom validation using kubebuilder tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html }type RealiboxStatus struct {// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster// Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file// Add custom validation using kubebuilder tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html } ...這里我們只改Spec字段,將RealiboxSpec結(jié)構(gòu)體改為:
type RealiboxSpec struct {Domain string `json:"domain,omitempty"`OSS string `json:"oss,omitempty"`Size string `json:"size,omitempty"` }更新CRD文件:
operator-sdk generate k8s operator-sdk generate crdsCRD本質(zhì)是一種k8s的資源,因此要使用crd,需要在K8s集群上創(chuàng)建CRD:
kubectl apply -f deploy/crds/test.k8s.realibox.com_realiboxes_crd.yaml$ kubectl get crd
NAME CREATED AT
http://clusterauthtokens.cluster.cattle.io 2020-08-29T06:41:42Z
http://clusteruserattributes.cluster.cattle.io 2020-08-29T06:41:42Z
http://realiboxes.test.k8s.realibox.com 2020-08-29T07:57:44Z
編寫controller
創(chuàng)建好 CRD 后,我們可以編寫 controller 了,先創(chuàng)建一個 controller 監(jiān)聽和核對新創(chuàng)建的realibox資源類型:
命令行說明:
operator-sdk add controller --api-version=<api的版本> --kind=<類型名稱>運行結(jié)果:
$ operator-sdk add controller --api-version=test.k8s.realibox.com/v1 --kind=Realibox$ tree ... ├── pkg │ ├── apis │ │ ├── addtoscheme_test_v1.go │ │ ├── apis.go │ │ └── test │ │ ├── group.go │ │ └── v1 │ │ ├── doc.go │ │ ├── realibox_types.go │ │ ├── register.go │ │ └── zz_generated.deepcopy.go │ └── controller │ ├── add_realibox.go │ ├── controller.go │ └── realibox │ └── realibox_controller.go ...參考鏈接:
https://zhuanlan.zhihu.com/p/243132067
總結(jié)
以上是生活随笔為你收集整理的基于operator sdk编写一个k8s自定义资源管理应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kubesphere服务网格servic
- 下一篇: k8s API编程:kubebuilde