存儲基礎(chǔ)知識
阿里云容器服務(wù)ACK使用Kubernetes編排系統(tǒng)作為集群、應(yīng)用、存儲、網(wǎng)絡(luò)等模塊的管理平臺。本文為您介紹ACK容器存儲相關(guān)的基礎(chǔ)知識,以便在使用容器服務(wù)的存儲能力時,了解相應(yīng)模塊的基礎(chǔ)知識和使用原則。
數(shù)據(jù)卷(Volume)
因為容器中的文件在磁盤上是臨時存放的,所以Kubernetes定義了數(shù)據(jù)卷(Volume)以解決容器中的文件因容器重啟而丟失的問題。數(shù)據(jù)卷(Volume)是Pod與外部存儲設(shè)備進行數(shù)據(jù)傳遞的通道,也是Pod內(nèi)部容器間、Pod與Pod間、Pod與外部環(huán)境進行數(shù)據(jù)共享的方式。
數(shù)據(jù)卷(Volume)定義了外置存儲的細節(jié),并內(nèi)嵌到Pod中作為Pod的一部分。其實質(zhì)是外置存儲在Kubernetes系統(tǒng)的一個資源映射,當(dāng)負載需要使用外置存儲的時候,可以從數(shù)據(jù)卷(Volume)中查到相關(guān)信息并進行存儲掛載操作。
數(shù)據(jù)卷(Volume)生命周期和Pod一致,即Pod被刪除的時候,數(shù)據(jù)卷(Volume)也一起被刪除(Volume中的數(shù)據(jù)是否丟失取決于Volume的具體類型)。
Kubernetes提供了非常豐富的Volume類型,您在ACK可以使用的常用的Volume類型如下:
數(shù)據(jù)卷(Volume)分類 | 描述 |
本地存儲 | 適用于本地存儲的數(shù)據(jù)卷,例如HostPath、emptyDir等。本地存儲卷的特點是數(shù)據(jù)保存在集群的特定節(jié)點上,并且不能隨著應(yīng)用遷移,節(jié)點停機時數(shù)據(jù)即不再可用。 |
網(wǎng)絡(luò)存儲 | 適用于網(wǎng)絡(luò)存儲的數(shù)據(jù)卷,例如Ceph、GlusterFS、NFS、iSCSI等。網(wǎng)絡(luò)存儲卷的特點是數(shù)據(jù)不在集群的某個節(jié)點上,而是在遠端的存儲服務(wù)上,使用存儲卷時需要將存儲服務(wù)掛載到本地使用。 |
Secret和ConfigMap | Secret和ConfigMap是特殊的數(shù)據(jù)卷,其數(shù)據(jù)是集群的一些對象信息,該對象數(shù)據(jù)以卷的形式被掛載到節(jié)點上供應(yīng)用使用。 |
PVC | 一種數(shù)據(jù)卷定義方式,將數(shù)據(jù)卷抽象成一個獨立于Pod的對象,這個對象定義(關(guān)聯(lián))的存儲信息即存儲卷對應(yīng)的真正存儲信息,供Kubernetes負載掛載使用。 |
CSI和Flexvolume是數(shù)據(jù)卷的兩種擴展方式。每種擴展方式都可再細化成不同的存儲類型。關(guān)于存儲CSI的更多信息,請參見存儲CSI概述。
數(shù)據(jù)卷(Volume)使用原則
一個Pod可以掛載多個數(shù)據(jù)卷(Volume)。
一個Pod可以掛載多種類型的數(shù)據(jù)卷(Volume)。
每個被Pod掛載的Volume卷,可以在不同的容器間共享。
Kubernetes環(huán)境推薦使用PVC和PV方式掛載數(shù)據(jù)卷(Volume)。
雖然單Pod可以掛載多個數(shù)據(jù)卷(Volume),但是并不建議給一個Pod掛載過多數(shù)據(jù)卷。
PV和PVC
并非所有的Kubernetes數(shù)據(jù)卷(Volume)具有持久化特性,為了實現(xiàn)持久化的存儲,容器存儲需依賴于一個遠程存儲服務(wù)。為此Kubernetes引入了PV和PVC兩個資源對象,將存儲實現(xiàn)的細節(jié)從其如何被使用中抽象出來,并解耦存儲使用者和系統(tǒng)管理員的職責(zé)。PV和PVC的概念如下:
PV
PV是PersistentVolume的縮寫,譯為持久化存儲卷。PV在Kubernetes中代表一個具體存儲類型的卷,其對象中定義了具體存儲類型和卷參數(shù)。即目標存儲服務(wù)所有相關(guān)的信息都保存在PV中,Kubernetes引用PV中的存儲信息執(zhí)行掛載操作。
PV是一個集群級別的概念,其對象作用范圍是整個Kubernetes集群,而不是一個節(jié)點。PV可以有自己的獨立生命周期,不依附于Pod。
PVC
PVC是PersistentVolumeClaim的縮寫,譯為存儲聲明。PVC是在Kubernetes中一種抽象的存儲卷類型,代表了某個具體類型存儲的數(shù)據(jù)卷表達。其設(shè)計意圖是分離存儲與應(yīng)用編排,將存儲細節(jié)抽象出來并實現(xiàn)存儲的編排。這樣Kubernetes中存儲卷對象獨立于應(yīng)用編排而單獨存在,在編排層面使應(yīng)用和存儲解耦。
PV和PVC使用說明
PVC和PV的綁定
PVC與PV是一一對應(yīng)關(guān)系,不能一個PVC掛載多個PV,也不能一個PV掛載多個PVC。為應(yīng)用配置存儲時,需要聲明一個存儲需求聲明(PVC),而Kubernetes會通過最佳匹配的方式選擇一個滿足PVC需求的PV,并與之綁定。所以從職責(zé)上PVC是應(yīng)用所需要的存儲對象,屬于應(yīng)用作用域。PV是存儲平面的存儲對象,屬于整個存儲域。
PVC只有綁定了PV之后才能被Pod使用,而PVC綁定PV的過程即是消費PV的過程,這個過程是有一定規(guī)則的,以下規(guī)則都滿足的PV才能被PVC綁定:
VolumeMode:被消費PV的VolumeMode需要和PVC一致。
AccessMode:被消費PV的AccessMode需要和PVC一致。
StorageClassName:如果PVC定義了此參數(shù),PV必須有相關(guān)的參數(shù)定義才能進行綁定。
LabelSelector:通過標簽(labels)匹配的方式從PV列表中選擇合適的PV綁定。
Size:被消費PV的capacity必須大于或者等于PVC的存儲容量需求才能被綁定。
PV和PVC定義中的size字段
PVC和PV里面的size字段作用如下:
PVC、PV綁定時,會根據(jù)各自的size進行篩選。
通過PVC、StorageClass動態(tài)創(chuàng)建PV時,有些存儲類型會參考PVC的size創(chuàng)建相應(yīng)大小的PV和后端存儲。
對于支持Resize操作的存儲類型,PVC的size作為擴容后PV、后端存儲的容量值。
一個PVC、PV的size值只是在執(zhí)行一些PVC和PV管控操作的時候,作為配置參數(shù)來使用。
真正的存儲卷數(shù)據(jù)流寫數(shù)據(jù)的時候,不會參考PVC和PV的size字段,而是依賴底層存儲介質(zhì)的實際容量。
數(shù)據(jù)卷(Volume)使用方式
常見的容器存儲數(shù)據(jù)卷使用方式如下:
靜態(tài)存儲卷
靜態(tài)存儲卷一般是指由管理員創(chuàng)建的PV。所有的數(shù)據(jù)卷(Volume)都支持創(chuàng)建靜態(tài)存儲卷。
靜態(tài)存儲卷先由集群管理員分析集群中存儲需求,并預(yù)先分配一些存儲介質(zhì)(例如云盤、NAS盤等),同時創(chuàng)建對應(yīng)的PV對象。創(chuàng)建好的PV對象等待PVC來消費。如果負載中定義了PVC需求,Kubernetes會通過相關(guān)規(guī)則實現(xiàn)PVC和匹配的PV進行綁定,這樣就實現(xiàn)了應(yīng)用對存儲服務(wù)的訪問能力。
動態(tài)存儲卷
動態(tài)存儲卷一般是指通過存儲插件自動創(chuàng)建的PV。
動態(tài)卷一般由集群管理員配置好后端的存儲池,并創(chuàng)建相應(yīng)的模板(StorageClass),當(dāng)有PVC需要消費PV的時候,根據(jù)PVC定義的需求,并參考StorageClass的存儲細節(jié),由存儲插件動態(tài)創(chuàng)建一個PV。StorageClass的定義如下:
StorageClass
當(dāng)您聲明一個PVC時,如果在PVC中添加了StorageClassName字段,意味著當(dāng)PVC在集群中找不到匹配的PV時,會根據(jù)StorageClassName的定義觸發(fā)相應(yīng)的Provisioner插件創(chuàng)建合適的PV供綁定,即創(chuàng)建動態(tài)數(shù)據(jù)卷。
動態(tài)數(shù)據(jù)卷由Provisioner插件創(chuàng)建,并通過StorageClassName與PVC進行關(guān)聯(lián)。
StorageClass可譯為存儲類,表示為一個創(chuàng)建PV存儲卷的模板。在PVC觸發(fā)自動創(chuàng)建PV的過程中,即使用StorageClass對象中的內(nèi)容進行創(chuàng)建。其內(nèi)容如下:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: alicloud-disk-topology parameters: type: cloud_ssd provisioner: diskplugin.csi.alibabacloud.com reclaimPolicy: Delete allowVolumeExpansion: true volumeBindingMode: WaitForFirstConsumer
參數(shù)
描述
reclaimPolicy
用來指定創(chuàng)建PV的persistentVolumeReclaimPolicy字段值,支持Delete和Retain。
Delete表示動態(tài)創(chuàng)建的PV,在銷毀的時候也會自動銷毀。
Retain表示動態(tài)創(chuàng)建的PV,不會自動銷毀,而是由管理員處理。
allowVolumeExpansion
定義由此存儲類創(chuàng)建的PV是否運行動態(tài)擴容,默認為
false
。是否能動態(tài)擴容是由底層存儲插件來實現(xiàn)的,這里只是一個開關(guān)。volumeBindingMode
表示動態(tài)創(chuàng)建PV的時間,支持Immediate和WaitForFirstConsumer,分別表示立即創(chuàng)建和延遲創(chuàng)建。
延遲綁定
針對某類存儲(例如阿里云云盤)在掛載屬性上有所限制,只能掛載相同可用區(qū)的數(shù)據(jù)卷和節(jié)點,不在同一個可用區(qū)不可以掛載。這種類型的存儲卷通常遇到如下問題:
創(chuàng)建了A可用區(qū)的數(shù)據(jù)卷,但是A可用區(qū)的節(jié)點資源已經(jīng)耗光,導(dǎo)致Pod啟動無法完成掛載。
集群管理員在規(guī)劃PVC、PV的時候不能確定在哪些可用區(qū)創(chuàng)建多個PV來備用。
StorageClass中的volumeBindingMode字段正是用來解決此問題,如果將volumeBindingMode配置為WaitForFirstConsumer值,則表示存儲插件在收到PVC Pending的時候不會立即進行數(shù)據(jù)卷創(chuàng)建,而是等待這個PVC被Pod消費的時候才執(zhí)行創(chuàng)建流程。
說明延遲綁定實現(xiàn)原理如下:
Provisioner在收到PVC Pending狀態(tài)的時候不會立即進行數(shù)據(jù)卷創(chuàng)建,而是等待這個PVC被Pod消費。如果有Pod消費此PVC,調(diào)度器發(fā)現(xiàn)PVC是延遲綁定模式,則繼續(xù)完成調(diào)度功能,且調(diào)度器會將調(diào)度結(jié)果通過patch命令寫入PVC的metadata中。當(dāng)Provisioner發(fā)現(xiàn)PVC中寫入了調(diào)度信息時,會根據(jù)調(diào)度信息獲取創(chuàng)建目標數(shù)據(jù)卷的位置信息(區(qū)域和節(jié)點信息),并觸發(fā)PV的創(chuàng)建流程。
在多可用區(qū)集群環(huán)境中,更推薦使用延遲綁定的動態(tài)卷方案,目前阿里云ACK集群已經(jīng)支持上述配置方案。
動態(tài)存儲卷的優(yōu)勢
動態(tài)存儲卷讓Kubernetes實現(xiàn)了PV的自動化生命周期管理,PV的創(chuàng)建、刪除都通過Provisioner完成。
自動化創(chuàng)建PV對象,減少了配置復(fù)雜度和系統(tǒng)管理員的工作量。
動態(tài)卷可以實現(xiàn)PVC對存儲的需求容量和Provisioner輸出的PV容量一致,實現(xiàn)存儲容量規(guī)劃最優(yōu)。
掛載SubPath卷
Kubernetes提供了
volumeMounts.subPath
屬性配置,可用于指定所引用的卷內(nèi)的子路徑,而不是其根路徑。說明SubPath在Kubernetes的一些版本中存在掛載、卸載不充分的問題,故不建議使用。如果您想要掛載卷的子目錄(如NAS、OSS子目錄),可以通過阿里云存儲CSI原生支持的能力進行掛載。
存儲卷配額說明
部分存儲類型在每個節(jié)點的掛載數(shù)量是有限制的,例如:阿里云云盤類型在一個節(jié)點上最多掛載16塊數(shù)據(jù)盤。對于這樣的配額限制,ACK提供了相應(yīng)的調(diào)度功能,當(dāng)某個節(jié)點上掛載了某種存儲滿額的卷后,調(diào)度器就不會再把這個類型的卷調(diào)度到這個節(jié)點。
ACK CSI存儲插件中可以通過MAX_VOLUMES_PERNODE字段配置每個節(jié)點的數(shù)據(jù)卷掛載數(shù)量。關(guān)于存儲CSI的更多信息,請參見存儲CSI概述。