在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)鏈接。 )