Kubernetes CRD


CRD

GitHub地址:https://github.com/kubernetes-sigs/kubebuilder


Kubernetes 裡資源類型有如下所示:

Kubernetes CRD

上述資源類型可以滿足大多數分佈式系統部署的需求


但是在不同應用業務環境下,對於平臺可能有一些特殊的需求,這些需求可以抽象為 Kubernetes 的擴展資源,而 Kubernetes 的 CRD (CustomResourceDefinition)為這樣的需求提供了輕量級的機制,保證新的資源的快速註冊和使用。


舉個栗子

我希望在 kubernetes 中有 KafkaSource 這個資源, 資源示例 kafka-source.yaml如下:

Kubernetes CRD


我們希望在執行 kubectl create -f kafka-source.yaml 之後,在 kubernetes 裡會啟動一個 pod,這個 pod 會做下面的事情:

  • 它會從地址是 my-cluster-kafka-bootstrap.kafka:9092,topic 是 knative- demo-topic 的 kafka 機群裡讀取消
  • 將讀到的消息,發送到 kubernetes 的一個 Service 去執行

Kuberentes 裡並沒有 KafkaSource 這個資源可以使用,所以直接執行 kubectl create -f kafka-source.yaml 的時候,會出錯。但是 kubernetes 提供的 CRD 機制可以讓我們輕鬆的把上述功能添加到 kubernetes 裡。


CRD 機制以上述 Kafkasource 為例,如下:

  1. 需要把 KafkaSource 這個資源註冊到 kubernetes 中,這樣 kubernetes 才會知道這個資源
  2. 註冊之後,還需要開發一個 controller 組件,來監聽用戶是否創建了 KafkaSource,也就是部署、更新或者刪除如上的 yaml 文件。
  3. Controller 監聽到有用戶創建了 KafkaSource,就會創建一個 pod 來做相應的工作

歸納一下就是:

用戶向 Kubernetes API 服務註冊一個帶特定 schema 的資源,並定義相關 API

  1. 將擴展資源的數據存儲到 Kubernetes 的 etcd 集群
  2. 藉助 Kubernetes 提供的 controller 模式開發框架,實現新的 controller,並藉助 APIServer 監聽 etcd 集群關於該資源的狀態並定義狀態變化的處理邏輯

具體流程如下圖:

Kubernetes CRD

在這個流程裡,大部分是 client-go 為用戶提供的框架和邏輯,可以直接使用,灰色的 AddFunc等是用戶需要實現的關於該擴展資源的業務邏輯。informer 會藉助 APIServer 跟蹤該擴展資源定義的變化,一旦被觸發就會調用回調函數,並把變更的具體內容放到 Workqueue 中,自定義 controller 裡面的 worker會獲取Workqueue 裡面內容,並進行相應的業務處理。


註冊使用 CustomResourceDefinition,以如下 kafkasource 的一個簡化版本為例,kubectl create -f kafkasource-customresourcedefinition.yaml:

Kubernetes CRD

可能這時候,大家還是不知道如何進行開發,就算好不容易搞清楚了,感覺開發也是很複雜的事情,我們可以使用工具-kubebuilder 來做開發,我們來做一下小的 demo,來看一下 kubebuilder 是如何幫我們進行開發的。

安裝

依賴:docker/go/kubebuilder

https://github.com/kubernetes-sigs/kubebuilder/releases

到相應的網址下載相應的二進制包,解壓壓縮包,並把二進制包放到系統路徑裡。接下來我們一步一步創建一個自定的 CronJob, 這也是一個比較經典的例子:


第一步:創建項目

kubebuilder init --domain tutorial.kubebuilder.io --license apache2 --owner "Authors"

  • A license. The reference project uses Apache 2.
  • A domain name. This is the unique domain used to identify your project's resources.
  • An author name. This is the copyright owner listed in the copyright notice at the top of each source file.

讓我們看一下生成的項目的結構:

Kubernetes CRD

go.mod: 項目第三方依賴

Makefile: 用來構建和部署 controller

PROJECT: metadata

Main.go: 應用執行入口

Config目錄下目前只包含啟動在雞群裡啟動controller的文件,還不包含CustomResourceDe nitions, RBAC con guration,and WebhookCon gurations.

config/manager: launch your controllers as pods in the cluster

config/rbac: permissions required to run your controllers under their own service account

main.go 中的 schemeHui 描述 Kinds 的 go types.

到目前這個項目包含:

  1. 設置了 flag
  2. 初始化了一個 manager,它會跟蹤所有的 controller
  3. 啟動 manager

第二步:創建 API

Groups, Versions and Kinds

Kubernetes CRD

kubebuilder create api --group batch --version v1alpha1 --kind SampleSource


講解一下自動創建的三個文件

接下來我們看一下,創建好的文件內容,看代碼:

api/v1: 只需要修改CronJobSpec和CronJobStatus

+kubebuilder:object:root :表示這是一個Kind


設計 API 的規則:

(1) 變量需要是駝峰,所以需要使用 tag 來標註

(2) 變量的類型也有要求

Numbers: int32、int64和resource.Quantity(舉例:resources requests and limits )

Spec:

  • Schedule: 定時
  • Template:pod spec

第三步:創建 controller

Controller 是 kubernetes 的核心,它負責保持集群資源實際狀態和期望的狀態一致(pod 數量之類的的),這個過程叫做 reconciling.

對某個具體的 Kind 進行 reconciling 的部分,叫做 reconciler.

請看代碼:

Import 部分......

會為大家仔細講解

剩下的主要是編碼部分,和部署驗證部分

......

請點鏈接獲取


分享到:


相關文章: