淺談Kubernetes 持久化存儲(chǔ)管理
?一、引言
Kubernetes從版本1.0以后,引入了兩個(gè)新的 API 資源:PersistentVolume 和 PersistentVolumeClaim 實(shí)現(xiàn)了對(duì)存儲(chǔ)供應(yīng)的獨(dú)立管理。持久卷(PersistentVolume,PV) 是對(duì)存儲(chǔ)資源在集群中的抽象;持久卷聲明(PersistentVolumeClaim,PVC)則是用戶對(duì)存儲(chǔ)資源的請(qǐng)求。盡管PV和PVC已經(jīng)實(shí)現(xiàn)了對(duì)用戶存儲(chǔ)資源請(qǐng)求的管理,但是管理員仍需手動(dòng)創(chuàng)建各種類型的PV 實(shí)現(xiàn)對(duì)用戶的存儲(chǔ)供應(yīng)。為了實(shí)現(xiàn)存儲(chǔ)資源的動(dòng)態(tài)供應(yīng),Kubernetes從版本1.4以后就引入了存儲(chǔ)類(StorageClass)資源。自1.9版本以后,Kubernetes又引入了容器存儲(chǔ)接口(Container Storage Interface CSI),將存儲(chǔ)驅(qū)動(dòng)代碼從Kubernetes的核心庫中剝離了出來,在Kubernetes和外部存儲(chǔ)間引入了一套標(biāo)準(zhǔn)的存儲(chǔ)管理接口,使得外部存儲(chǔ)可以通過實(shí)例化該接口動(dòng)態(tài)為容器提供存儲(chǔ)資源。本文將從上述資源對(duì)象入手,對(duì)Kubernetes的存儲(chǔ)管理進(jìn)行簡(jiǎn)要說明,并簡(jiǎn)述G行在容器存儲(chǔ)管理上的實(shí)踐。
二、PV和PVC
1、PV
PV(PersistentVolume) 是集群中存儲(chǔ)資源,一般由管理員創(chuàng)建或者由StorageClass自動(dòng)創(chuàng)建。他們不同于普通的volume,其生命周期獨(dú)立于Pod存在。PV主要包括了存儲(chǔ)能力、訪問模式、存儲(chǔ)類型、回收策略、后端存儲(chǔ)類型等關(guān)鍵信息的描述。下文我們來創(chuàng)建一個(gè)PV,YAML如下:
針對(duì)這個(gè)例子,我們來對(duì)PV的關(guān)鍵屬性進(jìn)行簡(jiǎn)要描述:
- Capacity:描述指定存儲(chǔ)設(shè)備的存儲(chǔ)能力,目前僅支持對(duì)存儲(chǔ)大小(storage)的設(shè)置,未來可能支持IOPS、吞入量等;
- VolumeMode:Kubernetes支持兩種存儲(chǔ)卷模式:Filesystem(文件系統(tǒng))和Block(塊設(shè)備),默認(rèn)值為Filesytem。當(dāng)VolumeMode指定為Filesystem時(shí),Kubernetes會(huì)在首次掛載時(shí)實(shí)現(xiàn)對(duì)文件系統(tǒng)的初始化;當(dāng)VolumeMode指定為Block時(shí),則會(huì)以原始?jí)K設(shè)備的形式掛載給Pod,Pod和Volume之間不會(huì)有任何文件系統(tǒng)層;
- AccessModes:描述用戶對(duì)存儲(chǔ)資源的訪問權(quán)限,需要注意的是一個(gè)PV在同一時(shí)刻只能以一種訪問模式被掛載,其可選的訪問模式包括:a. ReadWriteOnce(RWO):卷可以被一個(gè)節(jié)點(diǎn)以讀寫方式掛載,可以被同一節(jié)點(diǎn)上的多個(gè)Pod訪問;b. ReadOnlyMany(ROX):卷可以被多個(gè)節(jié)點(diǎn)以只讀方式掛載;c. ReadWriteMany(RWX):卷可以被多個(gè)節(jié)點(diǎn)以讀寫方式掛載;d. ReadWriteOncePod(RWOP):卷可以被單個(gè)Pod 以讀寫方式掛載。此模式必須需要CSI支持以及需要 Kubernetes 1.22 以上版本。
- StorageClassName:指定的存儲(chǔ)類別(StorageClass),只有StorageClassName相同的PV和PVC才能進(jìn)行綁定。若StorageClassName不進(jìn)行設(shè)置,則會(huì)被設(shè)置為集群默認(rèn)的 StorageClass。
2、PVC
PVC 是用戶對(duì)存儲(chǔ)資源的申請(qǐng),主要包括了存儲(chǔ)空間請(qǐng)求、訪問模式、選擇條件和存儲(chǔ)類別等信息的描述。集群根據(jù)PVC的描述為其選擇匹配的PV進(jìn)行綁定。下面我們來創(chuàng)建一個(gè)PVC,YAML如下:
針對(duì)這個(gè)例子,我們來對(duì)PVC的關(guān)鍵屬性進(jìn)行簡(jiǎn)要描述:
- Resources:描述對(duì)存儲(chǔ)資源的請(qǐng)求,例如存儲(chǔ)大?。╮equests.storage);
- VolumeMode:存儲(chǔ)卷模式,其設(shè)置跟PV的設(shè)置相同;
- AccessModes:訪問模式,其設(shè)置跟PV的設(shè)置相同;
- StorageClassName:存儲(chǔ)類別(StorageClass)名稱,當(dāng)系統(tǒng)設(shè)置了StorageClass,則系統(tǒng)會(huì)自動(dòng)為PVC創(chuàng)建相應(yīng)的PV并進(jìn)行綁定;
- Selector:選擇器,PVC會(huì)根據(jù)selector的內(nèi)容對(duì)滿足條件的PV進(jìn)行篩選,選擇KV匹配的PV進(jìn)行綁定。
PVC根據(jù)上述屬性描述選擇與之匹配的PV進(jìn)行綁定,需要注意的是,PVC只會(huì)在相同的Namespace內(nèi)選擇PV,同樣的,Pod也只能掛載相同的Namespace的PVC。只有當(dāng)PVC選擇到合適的PV時(shí),才可以被Pod進(jìn)行正常掛載,示例如下:
3、PV和PVC的生命周期
PV生命周期的各個(gè)階段:
- Available(可用):尚未與任何PVC進(jìn)行綁定;
- Bound(已綁定):已經(jīng)綁定到某個(gè)PVC;
- Released(已釋放):所綁定的PVC已被刪除,但是資源尚未被集群回收;
- Failed(失?。壕碜詣?dòng)回收操作失敗。
PV和PVC的相互關(guān)系如下圖1所示的生命周期:
圖1
Kubernetes提供了兩種存儲(chǔ)資源的供應(yīng)模式:
靜態(tài)模式:集群管理員必須聯(lián)系存儲(chǔ)管理員手動(dòng)來創(chuàng)建新的存儲(chǔ)卷, 然后在 Kubernetes 集群創(chuàng)建 PersistentVolume 對(duì)象來表示這些卷,最后用戶創(chuàng)建PVC進(jìn)行綁定。
動(dòng)態(tài)模式:集群管理員無需手動(dòng)創(chuàng)建PV卷,通過配置StorageClass來實(shí)現(xiàn)對(duì)存儲(chǔ)類的管理和資源的動(dòng)態(tài)供應(yīng)。用戶申請(qǐng)PVC時(shí),指定StorageClassName,對(duì)應(yīng)的StorageClass將會(huì)自動(dòng)完成對(duì)應(yīng)存儲(chǔ)類的存儲(chǔ)卷創(chuàng)建以及Kubernetes集群中PV的創(chuàng)建。若StorageClassName聲明為"", 則說明該P(yáng)VC禁止使用動(dòng)態(tài)模式。
三、StorageClass和CSI
1、StorageClass
動(dòng)態(tài)供應(yīng)模式主要基于StorageClass對(duì)象實(shí)現(xiàn),集群管理員可以針對(duì)不同的存儲(chǔ)類型創(chuàng)建不同的StorageClass,對(duì)用戶屏蔽了底層存儲(chǔ)的細(xì)節(jié)?;赟torageClass的動(dòng)態(tài)存儲(chǔ)供應(yīng)逐步成為了云平臺(tái)的標(biāo)準(zhǔn)存儲(chǔ)配置模式。StorageClass主要包括了存儲(chǔ)提供者以及相關(guān)存儲(chǔ)參數(shù)的配置。StorageClass一旦創(chuàng)建,則不能被修改,只能刪除重建。示例如下:
示例聲明一個(gè)名為standard,由Kubernetes.io/aws-ebs提供的存儲(chǔ)類。
2、CSI
StorageClass提供了存儲(chǔ)動(dòng)態(tài)供應(yīng)的功能,但是各種后端存儲(chǔ)插件的代碼都必須被放入Kubernetes的主干代碼中以供調(diào)用,這種緊耦合的開發(fā)模式,導(dǎo)致了巨大的維護(hù)成本和諸多問題。因此Kubernetes基于上述考慮,推出了容器存儲(chǔ)接口標(biāo)準(zhǔn)(CSI)。各存儲(chǔ)提供方自行維護(hù)自己的存儲(chǔ)插件代碼,只要滿足CSI 標(biāo)準(zhǔn),即可讓Kubernetes進(jìn)行調(diào)用,無需再耦合在Kubernetes的主干代碼中。CSI 存儲(chǔ)插件的標(biāo)準(zhǔn)實(shí)現(xiàn)主要包含兩種組件:
Controller Plugin:Controller主要實(shí)現(xiàn)存儲(chǔ)資源和存儲(chǔ)類的管理,一般為單實(shí)例部署,可以部署在任意節(jié)點(diǎn)上。
Node Plugin:主要實(shí)現(xiàn)對(duì)Node上存儲(chǔ)卷的管理和操作,包括卷的掛載、卸載等,一般部署為Daemonset,每個(gè)Node上運(yùn)行一個(gè)Pod。
四、G行的容器存儲(chǔ)管理實(shí)踐
1、背景
G行在云平臺(tái)3.0之前已經(jīng)引入了集中式NAS存儲(chǔ),在用戶需要申請(qǐng)PV卷時(shí),需要先向存儲(chǔ)管理員提出申請(qǐng),然后由存儲(chǔ)管理員在存儲(chǔ)端按用戶需求創(chuàng)建一塊存儲(chǔ)卷,再由系統(tǒng)管理員在集群中手動(dòng)創(chuàng)建PV卷完成資源交付,最后用戶在系統(tǒng)中創(chuàng)建PVC完成資源申請(qǐng),流程如下圖2所示:
圖2
從上述流程描述可以看出,整個(gè)過程中需要大量人為介入,缺乏自動(dòng)化。Kubernetes本身提供了StorageClass 用于支持資源的動(dòng)態(tài)創(chuàng)建,因此G行考慮在現(xiàn)有基礎(chǔ)上引入CSI存儲(chǔ)插件,實(shí)現(xiàn)了自動(dòng)化存儲(chǔ)交付。并在原有的基礎(chǔ)上,引入了高性能本地存儲(chǔ)和分布式SAN存儲(chǔ),擴(kuò)充了存儲(chǔ)資源類型。
2、CSI的部署與實(shí)踐
圖3
CSI的部署過程如上圖3所示,過程相對(duì)比較復(fù)雜,每次Kubernetes集群創(chuàng)建后,若都需要手動(dòng)部署CSI插件,無疑會(huì)增加系統(tǒng)運(yùn)維的成本。G行在此基礎(chǔ)上引入APP標(biāo)準(zhǔn)化交付框架,將Kubernetes的集群創(chuàng)建操作,以及CSI插件的部署進(jìn)行了集成,實(shí)現(xiàn)了Kubernetes集群的一鍵化創(chuàng)建,標(biāo)準(zhǔn)化交付。當(dāng)集群創(chuàng)建完成后,相應(yīng)的CSI插件及StorageClass就已經(jīng)自動(dòng)完成了部署,用戶即可直接使用。
集群中已經(jīng)部署好用戶所需的StorageClass,存儲(chǔ)資源申請(qǐng)只需直接創(chuàng)建PVC即可,示例如下:
剛創(chuàng)建完的PVC的狀態(tài)為Pending。
CSI的Controller會(huì)Watch kube-apiserver,檢測(cè)StorageClass的provisioner為自身的PVC的變化,當(dāng)感知到PVC的創(chuàng)建后,會(huì)自動(dòng)去存儲(chǔ)端進(jìn)行存儲(chǔ)卷的創(chuàng)建,存儲(chǔ)卷創(chuàng)建完以后,Controller會(huì)自動(dòng)在集群中創(chuàng)建PV。
圖4
整個(gè)過程結(jié)束后,可以在集群中看到PV已經(jīng)被成功創(chuàng)建,PVC的狀態(tài)已經(jīng)變?yōu)榱薆ound。
從圖4上述過程可以看出,用戶申請(qǐng)存儲(chǔ)資源的整個(gè)流程中,無需存儲(chǔ)管理員和集群管理員手動(dòng)干預(yù),即可自動(dòng)存儲(chǔ)資源交付。
3、使用CSI支持動(dòng)態(tài)擴(kuò)容
在云平臺(tái)3.0中,G行在云平臺(tái)3.0中的引入了高性能本地存儲(chǔ)和分布式SAN存儲(chǔ),這兩類存儲(chǔ)在存儲(chǔ)層基于KVM動(dòng)態(tài)擴(kuò)容技術(shù)可實(shí)現(xiàn)對(duì)后端存儲(chǔ)卷的動(dòng)態(tài)擴(kuò)容。在容器平臺(tái)中,G行對(duì)相應(yīng)的CSI Controller進(jìn)行了升級(jí)優(yōu)化,實(shí)現(xiàn)了EXPAND_VOLUME的功能,響應(yīng)用戶的擴(kuò)容需求。當(dāng)CSI Controller在Watch到相應(yīng)的修改后,會(huì)調(diào)用存儲(chǔ)后端接口對(duì)相應(yīng)的存儲(chǔ)卷和PV卷進(jìn)行擴(kuò)容,并對(duì)文件系統(tǒng)根據(jù)相應(yīng)設(shè)置進(jìn)行調(diào)整。
首先在存儲(chǔ)插件部署時(shí),需要將StorageClass的allowVolumeExpansion字段設(shè)置為True,開啟動(dòng)態(tài)擴(kuò)容,StorageClaas配置示例如下:
對(duì)于正在運(yùn)行中的業(yè)務(wù),若用戶有擴(kuò)容需求,無需卸載其使用的PV卷,直接修改PVC的requests大小,CSI Controller則立即嘗試調(diào)用存儲(chǔ)后端接口對(duì)相應(yīng)的存儲(chǔ)卷和PV卷進(jìn)行擴(kuò)容,后端存儲(chǔ)在接收到擴(kuò)容需求后,調(diào)用virsh blockresize命令調(diào)整存儲(chǔ)卷大小,并將處理結(jié)果返回給CSI Controller。CSI Controller確認(rèn)存儲(chǔ)卷已經(jīng)擴(kuò)容后,找到當(dāng)前存儲(chǔ)卷所掛載的node節(jié)點(diǎn),請(qǐng)求相應(yīng)的node節(jié)點(diǎn)上的CSI Daemonset對(duì)擴(kuò)容卷進(jìn)行resize,將擴(kuò)容的容量擴(kuò)充進(jìn)文件系統(tǒng)中。至此,用戶的動(dòng)態(tài)擴(kuò)容需求就完成了。整個(gè)擴(kuò)容流程,用戶無需暫停業(yè)務(wù),業(yè)務(wù)連續(xù)性和穩(wěn)定性得到了保障。
4、多種CSI并行
G行在云平臺(tái)3.0中支持了集中式NAS存儲(chǔ)、高性能本地存儲(chǔ)和分布式SAN存儲(chǔ),并針對(duì)這三類存儲(chǔ)類進(jìn)行了性能測(cè)試,針對(duì)測(cè)試結(jié)果梳理了相應(yīng)的用戶使用場(chǎng)景,部分測(cè)試數(shù)據(jù)如下(測(cè)試數(shù)據(jù)僅供參考):
集中式NAS存儲(chǔ):作為文件存儲(chǔ),讀寫性能弱于塊存儲(chǔ),原生支持文件系統(tǒng)的多節(jié)點(diǎn)讀寫,適用于有文件共享需求的用戶使用。
分布式SAN存儲(chǔ):分布式塊存儲(chǔ),讀寫性能好。在存儲(chǔ)模式為Filesystem時(shí)不支持多節(jié)點(diǎn)讀寫,適用于對(duì)存儲(chǔ)性能要求較高,無共享存儲(chǔ)需求的用戶使用。
高性能本地存儲(chǔ):本地塊存儲(chǔ),讀寫性能好。同樣不支持Filesystem存儲(chǔ)模式下的多節(jié)點(diǎn)讀寫,適用于單存儲(chǔ)卷容量300G以下,無共享存儲(chǔ)需求,對(duì)存儲(chǔ)性能要求高的用戶使用。
五、總結(jié)
Kubernetes通過PV、PVC、StorageClass、CSI標(biāo)準(zhǔn)構(gòu)建了一套完善的存儲(chǔ)管理機(jī)制,G行充分利用Kubernetes資源對(duì)象,并針對(duì)行內(nèi)現(xiàn)狀,引入多種存儲(chǔ)類型和對(duì)應(yīng)的CSI存儲(chǔ)插件,實(shí)現(xiàn)了多種CSI并行及自動(dòng)化容器存儲(chǔ)管理。存儲(chǔ)管理員和系統(tǒng)管理員無需再手動(dòng)創(chuàng)建存儲(chǔ)卷和PV卷,只需在項(xiàng)目創(chuàng)建之初,針對(duì)不同的存儲(chǔ)類(StorageClass)給項(xiàng)目分配存儲(chǔ)配額。用戶需要時(shí),可直接創(chuàng)建PVC,CSI 控制器會(huì)根據(jù)用戶的PVC參數(shù),調(diào)用存儲(chǔ)端接口,自動(dòng)創(chuàng)建存儲(chǔ)卷以及PV卷,實(shí)現(xiàn)了用戶的即時(shí)申請(qǐng),即時(shí)可用,當(dāng)用戶有擴(kuò)容需求時(shí),現(xiàn)有CSI控制器也可支持PV卷的動(dòng)態(tài)擴(kuò)容,無需管理員手動(dòng)調(diào)整。相比靜態(tài)交付管理的模式,集群管理員無需預(yù)先配置存儲(chǔ),既降低了人力成本,又提升了交付效率和業(yè)務(wù)的連續(xù)性。同時(shí),多種存儲(chǔ)類的引入也滿足了不同使用場(chǎng)景下的用戶需求。