Kubernetes中自定義資源多版本管理

在kubernetes生態(tài)中,通過自定義CRD(CustomResourceDefinition)來擴(kuò)展自定義資源,擴(kuò)展集群的功能。通過執(zhí)行kubectl get crd來獲取kubernetes集群中安裝的CRD資源,CRD擴(kuò)展方式有效的擴(kuò)展kubernetes生態(tài)。

在對資源定義的時(shí)候,通過GVK(Group-Version-Kind)來唯一的表示一種資源類型,可以看到如下的yaml中Deployment這個(gè)類型對應(yīng)的Group為apps, 版本是v1

apiVersion: apps/v1

kind: Deployment

metadata:

annotations:

deployment.kubernetes.io/revision: "1"

labels:

app.kubernetes.io/component: manager

name: project-controller-manager

namespace: default

在創(chuàng)建CRD的時(shí)候,需要定義一個(gè)版本,例如v1beta1,所有自定義資源對象最初都將存儲在這個(gè)版本中,所有的client將會使用v1beta1 版本的API。隨著資源對象的演進(jìn),會引入其他新的版本,例如v1beta2、v1、v2beta1、v2beta2等等,等某些api對象版本成熟,將會將歷史版本的api對象設(shè)置成廢棄的狀態(tài),最終移除對于廢棄api對象的支持。對應(yīng)的client去訪問和操作api對象的時(shí)候需要根據(jù)不同版本的api去做調(diào)整,下面的內(nèi)容是kubernetes中針對自定義CRD資源如何去做多版本的管理以及kubebuilder框架為我們提供了那些機(jī)制完成多版本資源的管理。

CRD資源支持對象支持多個(gè)版本

CustomResourceDefinition定義的時(shí)候,可以在spec.versions中定義多個(gè)版本的對象,例如可以自定義CronJob資源存在三個(gè)版本v1beta1、v1、v2beta1。

資源對象的版本可以三個(gè)狀態(tài)

使用中:該版本的資源定義可以被使用

廢棄狀態(tài):該版本的資源定義仍然可以被使用,但是已經(jīng)處于不推薦使用狀態(tài),在未來將會被移除,處于該狀態(tài)的資源對象,需要將其升級到新版本的對象

移除狀態(tài):該版本的資源對象已經(jīng)無法被訪問和使用

資源對象版本的管理可以參考kubernetes api管理規(guī)范去規(guī)劃CRD資源對象的管理。Kubernetes 是一個(gè) API 驅(qū)動(dòng)的系統(tǒng),API的版本號通常用于描述API的成熟階段。

v1

正式發(fā)布(Generally available,GA,穩(wěn)定版本)

v1beta1

Beta (預(yù)發(fā)布)

v1alpha1

Alpha (試驗(yàn)性)

不同版本對應(yīng)的廢棄和移除策略也是不一樣的, 當(dāng)某個(gè)API的實(shí)現(xiàn)達(dá)到一個(gè)新的GA穩(wěn)定版本時(shí)(如v2),舊的GA版本(如v1)和Beta版本(例如v2beta1)將逐漸被廢棄,Kubernetes建議廢棄的時(shí)間如下。

對于舊的GA版本(如v1),Kubernetes建議廢棄的時(shí)間應(yīng)不少于12個(gè)月或3個(gè)大版本Release的時(shí)間,選擇最長的時(shí)間。

對舊的Beta版本(如v2beta1),Kubernetes建議廢棄的時(shí)間應(yīng)不少于9個(gè)月或3個(gè)大版本Release的時(shí)間,選擇最長的時(shí)間。

對舊的Alpha版本,則無須等待,可以直接廢棄。

通過在自定義資源的時(shí)候指定字段標(biāo)注出來那個(gè)版本的資源對象處于廢棄狀態(tài),

當(dāng)對該資源的已棄用版本發(fā)出API請求時(shí),將在API響應(yīng)中作為頭返回一條警告消息。通過這個(gè)告警信息可以方便的對api版本進(jìn)行治理。

另外可以在定義資源對象的時(shí)候,設(shè)置是否移除該版本的資源對象,如下圖所示。可以通過調(diào)整這個(gè)字段來關(guān)閉該版本的資源對象,測試對該資源對象訪問的組件是否工作正常,常常會在組件升級的過程中會去使用。

對象的版本與存儲

Client端去訪問資源對象的時(shí)候,需要指定對應(yīng)的版本,廢棄狀態(tài)的版本以及正常使用的版本可以正常的訪問,移除狀態(tài)的版本無法訪問。Client可以訪問不同版本的api版本,通過版本之間的轉(zhuǎn)換來支持多個(gè)版本的資源對象,不同版本的資源對象需要可以相互轉(zhuǎn)換,并且轉(zhuǎn)換的時(shí)候不能發(fā)生字段屬性的丟失。 Kubebuilder中采用“hub and spoke”模型來管理不同版本的api轉(zhuǎn)換

實(shí)心點(diǎn)表示某個(gè)版本的對象,需要實(shí)現(xiàn)不同版本資源的轉(zhuǎn)換,kubebuilder中定義了某個(gè)版本是hub,如右邊圖中心的實(shí)心點(diǎn),對象之間的轉(zhuǎn)換需要通過hub version。Hub version也可以被稱為storage version. Hub version在CRD可以通過設(shè)置版本對象中的storage: true來標(biāo)志為hub。

對于CRD對象的版本之間的轉(zhuǎn)換需要提供webhook來支持,在CRD對象定義中通過spec.conversion來定義webhook, webhook是外部一個(gè)服務(wù)。之后由kube-apiserver調(diào)用過程中對對象版本進(jìn)行轉(zhuǎn)換。Webhook支持URL或者Service Reference兩種格式,下圖為service reference為kubernetes集群中某個(gè)service.

當(dāng)對象存在v1beta1、 v1、 v2beta1三個(gè)版本,v1為storage/hub version, client創(chuàng)建v1beta1的對象,kube-apiserver將會調(diào)用webhook完成v1beta1轉(zhuǎn)換成v1格式的對象。之后存儲的對象版本為v1版本。當(dāng)client獲取該對象的v2beta1版本的時(shí)候,kube-apiserver獲取到存儲的v1版本的時(shí)候,會調(diào)用webhook完成v1版本的格式轉(zhuǎn)換成v2beta1版本,返回給client。

Kubebuilder支持多版本對象

通過kubebuilder初始化一個(gè)demo項(xiàng)目,演示如何在kubebuilder的框架下支持多個(gè)版本對象,以Changing things up - The Kubebuilder Book為例子。

# 創(chuàng)建project項(xiàng)目空間

mkdir project

cd project

# 初始化

kubebuilder init --domain tutorial.kubebuilder.io --repo tutorial.kubebuilder.io/project

##創(chuàng)建三個(gè)版本的api對象

# kubebuilder create api --group batch --version v1 --kind CronJob --force

# kubebuilder create api --group batch --version v2 --kind CronJob --force

# kubebuilder create api --group batch --version v3 --kind CronJob --force

##在v1對應(yīng)的project/api/v1/cronjob_types.go中設(shè)置+kubebuilder:storageversion該v1版本為storage

##添加project/api/v1/cronjob_conversion.go

// Hub marks this type as a conversion hub.

func (*CronJob) Hub() {}

##添加project/api/v2/cronjob_conversion.go

// ConvertTo converts this CronJob to the Hub version (v1).

func (src *CronJob) ConvertTo(dstRaw conversion.Hub) error {

….

}

// ConvertFrom converts from the Hub version (v1) to this version.

func (dst *CronJob) ConvertFrom(srcRaw conversion.Hub) error {

…….

}

##添加project/api/v3/cronjob_conversion.go

// ConvertTo converts this CronJob to the Hub version (v1).

func (src *CronJob) ConvertTo(dstRaw conversion.Hub) error {

….

}

// ConvertFrom converts from the Hub version (v1) to this version.

func (dst *CronJob) ConvertFrom(srcRaw conversion.Hub) error {

…….

}

###添加一個(gè)webhook,來實(shí)現(xiàn)/convert

kubebuilder create webhook --group batch --version v1 --kind CronJob --conversion

Kubebuilder基于“hub and spoke”模型來實(shí)現(xiàn)對象之間的轉(zhuǎn)換,如上個(gè)例子所示,我們需要實(shí)現(xiàn)v2<->v1, v1<->v3之間的ConvertTo、ConvertFrom函數(shù)

總結(jié)

Kubernetes 資源對象的版本定義對于kubernetes的成功起到了至關(guān)重要的作用,其中資源對象的多版本管理包括了kubernetes社區(qū)的思考和探索,對于其他系統(tǒng)的api對象的設(shè)計(jì)有很好的參考價(jià)值。

參考資料

Kubernetes 棄用策略 | Kubernetes

and setting up the webhooks - The Kubebuilder Book

(免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請進(jìn)一步核實(shí),并對任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對有關(guān)資料所引致的錯(cuò)誤、不確或遺漏,概不負(fù)任何法律責(zé)任。
任何單位或個(gè)人認(rèn)為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權(quán)或存在不實(shí)內(nèi)容時(shí),應(yīng)及時(shí)向本網(wǎng)站提出書面權(quán)利通知或不實(shí)情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實(shí)情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關(guān)文章源頭核實(shí),溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。 )