掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
存儲的管理是一個與計算實例的管理完全不同的問題。PersistentVolume 子系統(tǒng)為用戶 和管理員提供了一組 API,將存儲如何供應(yīng)的細(xì)節(jié)從其如何被使用中抽象出來。 為了實現(xiàn)這點,我們引入了兩個新的 API 資源:PersistentVolume 和 PersistentVolumeClaim。

“只有客戶發(fā)展了,才有我們的生存與發(fā)展!”這是創(chuàng)新互聯(lián)建站的服務(wù)宗旨!把網(wǎng)站當(dāng)作互聯(lián)網(wǎng)產(chǎn)品,產(chǎn)品思維更注重全局思維、需求分析和迭代思維,在網(wǎng)站建設(shè)中就是為了建設(shè)一個不僅審美在線,而且實用性極高的網(wǎng)站。創(chuàng)新互聯(lián)對做網(wǎng)站、成都網(wǎng)站制作、網(wǎng)站制作、網(wǎng)站開發(fā)、網(wǎng)頁設(shè)計、網(wǎng)站優(yōu)化、網(wǎng)絡(luò)推廣、探索永無止境。
持久卷(PersistentVolume,PV)是集群中的一塊存儲,可以由管理員事先供應(yīng),或者 使用存儲類(Storage Class)來動態(tài)供應(yīng)。 持久卷是集群資源,就像節(jié)點也是集群資源一樣。PV 持久卷和普通的 Volume 一樣,也是使用 卷插件來實現(xiàn)的,只是它們擁有獨立于任何使用 PV 的 Pod 的生命周期。 此 API 對象中記述了存儲的實現(xiàn)細(xì)節(jié),無論其背后是 NFS、iSCSI 還是特定于云平臺的存儲系統(tǒng)。
持久卷申領(lǐng)(PersistentVolumeClaim,PVC)表達的是用戶對存儲的請求。概念上與 Pod 類似。 Pod 會耗用節(jié)點資源,而 PVC 申領(lǐng)會耗用 PV 資源。Pod 可以請求特定數(shù)量的資源(CPU 和內(nèi)存);同樣 PVC 申領(lǐng)也可以請求特定的大小和訪問模式 (例如,可以要求 PV 卷能夠以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一來掛載,參見訪問模式)。
盡管 PersistentVolumeClaim 允許用戶消耗抽象的存儲資源,常見的情況是針對不同的 問題用戶需要的是具有不同屬性(如,性能)的 PersistentVolume 卷。 集群管理員需要能夠提供不同性質(zhì)的 PersistentVolume,并且這些 PV 卷之間的差別不 僅限于卷大小和訪問模式,同時又不能將卷是如何實現(xiàn)的這些細(xì)節(jié)暴露給用戶。 為了滿足這類需求,就有了 存儲類(StorageClass) 資源。
PV 卷是集群中的資源。PVC 申領(lǐng)是對這些資源的請求,也被用來執(zhí)行對資源的申領(lǐng)檢查。 PV 卷和 PVC 申領(lǐng)之間的互動遵循如下生命周期:
PV 卷的供應(yīng)有兩種方式:靜態(tài)供應(yīng)或動態(tài)供應(yīng)。
集群管理員創(chuàng)建若干 PV 卷。這些卷對象帶有真實存儲的細(xì)節(jié)信息,并且對集群 用戶可用(可見)。PV 卷對象存在于 Kubernetes API 中,可供用戶消費(使用)。
如果管理員所創(chuàng)建的所有靜態(tài) PV 卷都無法與用戶的 PersistentVolumeClaim 匹配, 集群可以嘗試為該 PVC 申領(lǐng)動態(tài)供應(yīng)一個存儲卷。 這一供應(yīng)操作是基于 StorageClass 來實現(xiàn)的:PVC 申領(lǐng)必須請求某個 存儲類,同時集群管理員必須 已經(jīng)創(chuàng)建并配置了該類,這樣動態(tài)供應(yīng)卷的動作才會發(fā)生。 如果 PVC 申領(lǐng)指定存儲類為 ?""?,則相當(dāng)于為自身禁止使用動態(tài)供應(yīng)的卷。
為了基于存儲類完成動態(tài)的存儲供應(yīng),集群管理員需要在 API 服務(wù)器上啟用 ?DefaultStorageClass ?準(zhǔn)入控制器。 舉例而言,可以通過保證 ?DefaultStorageClass ?出現(xiàn)在 API 服務(wù)器組件的 ?--enable-admission-plugins? 標(biāo)志值中實現(xiàn)這點;該標(biāo)志的值可以是逗號 分隔的有序列表。
用戶創(chuàng)建一個帶有特定存儲容量和特定訪問模式需求的 PersistentVolumeClaim 對象; 在動態(tài)供應(yīng)場景下,這個 PVC 對象可能已經(jīng)創(chuàng)建完畢。 主控節(jié)點中的控制回路監(jiān)測新的 PVC 對象,尋找與之匹配的 PV 卷(如果可能的話), 并將二者綁定到一起。 如果為了新的 PVC 申領(lǐng)動態(tài)供應(yīng)了 PV 卷,則控制回路總是將該 PV 卷綁定到這一 PVC 申領(lǐng)。 否則,用戶總是能夠獲得他們所請求的資源,只是所獲得的 PV 卷可能會超出所請求的配置。 一旦綁定關(guān)系建立,則 PersistentVolumeClaim 綁定就是排他性的,無論該 PVC 申領(lǐng)是 如何與 PV 卷建立的綁定關(guān)系。 PVC 申領(lǐng)與 PV 卷之間的綁定是一種一對一的映射,實現(xiàn)上使用 ClaimRef 來記述 PV 卷 與 PVC 申領(lǐng)間的雙向綁定關(guān)系。
如果找不到匹配的 PV 卷,PVC 申領(lǐng)會無限期地處于未綁定狀態(tài)。 當(dāng)與之匹配的 PV 卷可用時,PVC 申領(lǐng)會被綁定。 例如,即使某集群上供應(yīng)了很多 50 Gi 大小的 PV 卷,也無法與請求 100 Gi 大小的存儲的 PVC 匹配。當(dāng)新的 100 Gi PV 卷被加入到集群時,該 PVC 才有可能被綁定。
Pod 將 PVC 申領(lǐng)當(dāng)做存儲卷來使用。集群會檢視 PVC 申領(lǐng),找到所綁定的卷,并 為 Pod 掛載該卷。對于支持多種訪問模式的卷,用戶要在 Pod 中以卷的形式使用申領(lǐng) 時指定期望的訪問模式。
一旦用戶有了申領(lǐng)對象并且該申領(lǐng)已經(jīng)被綁定,則所綁定的 PV 卷在用戶仍然需要它期間 一直屬于該用戶。用戶通過在 Pod 的 ?volumes ?塊中包含 ?persistentVolumeClaim ?節(jié)區(qū)來調(diào)度 Pod,訪問所申領(lǐng)的 PV 卷。
保護使用中的存儲對象(Storage Object in Use Protection)這一功能特性的目的 是確保仍被 Pod 使用的 PersistentVolumeClaim(PVC)對象及其所綁定的 PersistentVolume(PV)對象在系統(tǒng)中不會被刪除,因為這樣做可能會引起數(shù)據(jù)丟失。
當(dāng)使用某 PVC 的 Pod 對象仍然存在時,認(rèn)為該 PVC 仍被此 Pod 使用。
如果用戶刪除被某 Pod 使用的 PVC 對象,該 PVC 申領(lǐng)不會被立即移除。 PVC 對象的移除會被推遲,直至其不再被任何 Pod 使用。 此外,如果管理員刪除已綁定到某 PVC 申領(lǐng)的 PV 卷,該 PV 卷也不會被立即移除。 PV 對象的移除也要推遲到該 PV 不再綁定到 PVC。
你可以看到當(dāng) PVC 的狀態(tài)為 ?Terminating ?且其 ?Finalizers ?列表中包含 ?kubernetes.io/pvc-protection? 時,PVC 對象是處于被保護狀態(tài)的。
kubectl describe pvc hostpath
Name: hostpath
Namespace: default
StorageClass: example-hostpath
Status: Terminating
Volume:
Labels:
Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath
volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [kubernetes.io/pvc-protection]
你也可以看到當(dāng) PV 對象的狀態(tài)為 ?Terminating ?且其 ?Finalizers ?列表中包含 ?kubernetes.io/pv-protection? 時,PV 對象是處于被保護狀態(tài)的。
kubectl describe pv task-pv-volume
Name: task-pv-volume
Labels: type=local
Annotations:
Finalizers: [kubernetes.io/pv-protection]
StorageClass: standard
Status: Terminating
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /tmp/data
HostPathType:
Events:
當(dāng)用戶不再使用其存儲卷時,他們可以從 API 中將 PVC 對象刪除,從而允許 該資源被回收再利用。PersistentVolume 對象的回收策略告訴集群,當(dāng)其被 從申領(lǐng)中釋放時如何處理該數(shù)據(jù)卷。 目前,數(shù)據(jù)卷可以被 Retained(保留)、Recycled(回收)或 Deleted(刪除)。
回收策略 ?Retain ?使得用戶可以手動回收資源。當(dāng) PersistentVolumeClaim 對象 被刪除時,PersistentVolume 卷仍然存在,對應(yīng)的數(shù)據(jù)卷被視為"已釋放(released)"。 由于卷上仍然存在這前一申領(lǐng)人的數(shù)據(jù),該卷還不能用于其他申領(lǐng)。 管理員可以通過下面的步驟來手動回收該卷:
如果你希望重用該存儲資產(chǎn),可以基于存儲資產(chǎn)的定義創(chuàng)建新的 PersistentVolume 卷對象。
對于支持 ?Delete ?回收策略的卷插件,刪除動作會將 PersistentVolume 對象從 Kubernetes 中移除,同時也會從外部基礎(chǔ)設(shè)施(如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)中移除所關(guān)聯(lián)的存儲資產(chǎn)。 動態(tài)供應(yīng)的卷會繼承其 StorageClass 中設(shè)置的回收策略,該策略默認(rèn) 為 ?Delete?。 管理員需要根據(jù)用戶的期望來配置 StorageClass;否則 PV 卷被創(chuàng)建之后必須要被 編輯或者修補。
回收策略 ?
Recycle?已被廢棄。取而代之的建議方案是使用動態(tài)供應(yīng)。
如果下層的卷插件支持,回收策略 ?Recycle ?會在卷上執(zhí)行一些基本的 擦除(?rm -rf /thevolume/*?)操作,之后允許該卷用于新的 PVC 申領(lǐng)。
不過,管理員可以按 參考資料 中所述,使用 Kubernetes 控制器管理器命令行參數(shù)來配置一個定制的回收器(Recycler) Pod 模板。此定制的回收器 Pod 模板必須包含一個 ?volumes ?規(guī)約,如下例所示:
apiVersion: v1
kind: Pod
metadata:
name: pv-recycler
namespace: default
spec:
restartPolicy: Never
volumes:
- name: vol
hostPath:
path: /any/path/it/will/be/replaced
containers:
- name: pv-recycler
image: "K8S.gcr.io/busybox"
command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"]
volumeMounts:
- name: vol
mountPath: /scrub
定制回收器 Pod 模板中在 ?volumes ?部分所指定的特定路徑要替換為 正被回收的卷的路徑。
通過在 PersistentVolumeClaim 中指定 PersistentVolume,你可以聲明該特定 PV 與 PVC 之間的綁定關(guān)系。如果該 PersistentVolume 存在且未被通過其 ?claimRef ?字段預(yù)留給 PersistentVolumeClaim,則該 PersistentVolume 會和該 PersistentVolumeClaim 綁定到一起。
綁定操作不會考慮某些卷匹配條件是否滿足,包括節(jié)點親和性等等。 控制面仍然會檢查 存儲類、訪問模式和所請求的 存儲尺寸都是合法的。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-pvc
namespace: foo
spec:
storageClassName: "" # 此處須顯式設(shè)置空字符串,否則會被設(shè)置為默認(rèn)的 StorageClass
volumeName: foo-pv
...
此方法無法對 PersistentVolume 的綁定特權(quán)做出任何形式的保證。 如果有其他 PersistentVolumeClaim 可以使用你所指定的 PV,則你應(yīng)該首先預(yù)留 該存儲卷。你可以將 PV 的 ?claimRef ?字段設(shè)置為相關(guān)的 PersistentVolumeClaim 以確保其他 PVC 不會綁定到該 PV 卷。
apiVersion: v1
kind: PersistentVolume
metadata:
name: foo-pv
spec:
storageClassName: ""
claimRef:
name: foo-pvc
namespace: foo
...
如果你想要使用 ?claimPolicy ?屬性設(shè)置為 ?Retain ?的 PersistentVolume 卷 時,包括你希望復(fù)用現(xiàn)有的 PV 卷時,這點是很有用的
FEATURE STATE: Kubernetes v1.11 [beta]
現(xiàn)在,對擴充 PVC 申領(lǐng)的支持默認(rèn)處于被啟用狀態(tài)。你可以擴充以下類型的卷:
只有當(dāng) PVC 的存儲類中將 ?allowVolumeExpansion ?設(shè)置為 true 時,你才可以擴充該 PVC 申領(lǐng)。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://192.168.10.100:8080"
restuser: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
如果要為某 PVC 請求較大的存儲卷,可以編輯 PVC 對象,設(shè)置一個更大的尺寸值。 這一編輯操作會觸發(fā)為下層 PersistentVolume 提供存儲的卷的擴充。 Kubernetes 不會創(chuàng)建新的 PV 卷來滿足此申領(lǐng)的請求。 與之相反,現(xiàn)有的卷會被調(diào)整大小。
直接編輯 PersistentVolume 的大小可以阻止該卷自動調(diào)整大小。 如果對 PersistentVolume 的容量進行編輯,然后又將其所對應(yīng)的 PersistentVolumeClaim 的 ?
.spec? 進行編輯,使該 PersistentVolumeClaim 的大小匹配 PersistentVolume 的話,則不會發(fā)生存儲大小的調(diào)整。 Kubernetes 控制平面將看到兩個資源的所需狀態(tài)匹配,并認(rèn)為其后備卷的大小 已被手動增加,無需調(diào)整。
FEATURE STATE: Kubernetes v1.16 [beta]
對 CSI 卷的擴充能力默認(rèn)是被啟用的,不過擴充 CSI 卷要求 CSI 驅(qū)動支持 卷擴充操作。
只有卷中包含的文件系統(tǒng)是 XFS、Ext3 或者 Ext4 時,你才可以重設(shè)卷的大小。
當(dāng)卷中包含文件系統(tǒng)時,只有在 Pod 使用 ?ReadWrite ?模式來使用 PVC 申領(lǐng)的 情況下才能重設(shè)其文件系統(tǒng)的大小。 文件系統(tǒng)擴充的操作或者是在 Pod 啟動期間完成,或者在下層文件系統(tǒng)支持在線 擴充的前提下在 Pod 運行期間完成。
如果 FlexVolumes 的驅(qū)動將 ?RequiresFSResize ?能力設(shè)置為 true,則該 FlexVolume 卷(于 Kubernetes v1.23 棄用)可以在 Pod 重啟期間調(diào)整大小。
FEATURE STATE: Kubernetes v1.15 [beta]
Kubernetes 從 1.15 版本開始將調(diào)整使用中 PVC 申領(lǐng)大小這一能力作為 Beta 特性支持;該特性在 1.11 版本以來處于 Alpha 階段。 ?
ExpandInUsePersistentVolumes?特性必須被啟用;在很多集群上,與此類似的 Beta 階段的特性是自動啟用的。
在這種情況下,你不需要刪除和重建正在使用某現(xiàn)有 PVC 的 Pod 或 Deployment。 所有使用中的 PVC 在其文件系統(tǒng)被擴充之后,立即可供其 Pod 使用。 此功能特性對于沒有被 Pod 或 Deployment 使用的 PVC 而言沒有效果。 你必須在執(zhí)行擴展操作之前創(chuàng)建一個使用該 PVC 的 Pod。
與其他卷類型類似,F(xiàn)lexVolume 卷也可以在被 Pod 使用期間執(zhí)行擴充操作。
FlexVolume 卷的重設(shè)大小只能在下層驅(qū)動支持重設(shè)大小的時候才可進行。
擴充 EBS 卷的操作非常耗時。同時還存在另一個配額限制: 每 6 小時只能執(zhí)行一次(尺寸)修改操作。
如果用戶指定的新大小過大,底層存儲系統(tǒng)無法滿足,PVC 的擴展將不斷重試, 直到用戶或集群管理員采取一些措施。這種情況是不希望發(fā)生的,因此 Kubernetes 提供了以下從此類故障中恢復(fù)的方法。
如果擴充下層存儲的操作失敗,集群管理員可以手動地恢復(fù) PVC 申領(lǐng)的狀態(tài)并 取消重設(shè)大小的請求。否則,在沒有管理員干預(yù)的情況下,控制器會反復(fù)重試 重設(shè)大小的操作。
Retain ?回收策略;Retain?,我們不會在重建 PVC 時丟失數(shù)據(jù)。claimRef ?項,這樣新的 PVC 可以綁定到該卷。 這一操作會使得 PV 卷變?yōu)?nbsp;"可用(Available)"。volumeName ?字段為 PV 卷的名稱。 這一操作將把新的 PVC 對象綁定到現(xiàn)有的 PV 卷。FEATURE STATE: Kubernetes v1.23 [alpha]
Kubernetes 從 1.23 版本開始將允許用戶恢復(fù)失敗的 PVC 擴展這一能力作為 alpha 特性支持。 ?
RecoverVolumeExpansionFailure?必須被啟用以允許使用此功能。
如果集群中的特性門控 ?ExpandPersistentVolumes ?和 ?RecoverVolumeExpansionFailure ?都已啟用,在 PVC 的擴展發(fā)生失敗時,你可以使用比先前請求的值更小的尺寸來重試擴展。 要使用一個更小的尺寸嘗試請求新的擴展,請編輯該 PVC 的 ?.spec.resources? 并選擇 一個比你之前所嘗試的值更小的值。 如果由于容量限制而無法成功擴展至更高的值,這將很有用。 如果發(fā)生了這種情況,或者你懷疑可能發(fā)生了這種情況,你可以通過指定一個在底層存儲供應(yīng)容量 限制內(nèi)的尺寸來重試擴展。你可以通過查看 ?.status.resizeStatus? 以及 PVC 上的事件 來監(jiān)控調(diào)整大小操作的狀態(tài)。
請注意, 盡管你可以指定比之前的請求更低的存儲量,新值必須仍然高于 ?.status.capacity?。 Kubernetes 不支持將 PVC 縮小到小于其當(dāng)前的尺寸。
PV 持久卷是用插件的形式來實現(xiàn)的。Kubernetes 目前支持以下插件:
以下的持久卷已被棄用。這意味著當(dāng)前仍是支持的,但是 Kubernetes 將來的發(fā)行版會將其移除。
舊版本的 Kubernetes 仍支持這些“樹內(nèi)(In-Tree)”持久卷類型:
photonPersistentDisk ?- Photon 控制器持久化盤。(v1.15 之后 不可用)每個 PV 對象都包含 ?spec ?部分和 ?status ?部分,分別對應(yīng)卷的規(guī)約和狀態(tài)。 PersistentVolume 對象的名稱必須是合法的 DNS 子域名.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
在集群中使用持久卷存儲通常需要一些特定于具體卷類型的輔助程序。 在這個例子中,PersistentVolume 是 NFS 類型的,因此需要輔助程序 ?
/sbin/mount.nfs? 來支持掛載 NFS 文件系統(tǒng)。
一般而言,每個 PV 卷都有確定的存儲容量。 容量屬性是使用 PV 對象的 ?capacity ?屬性來設(shè)置的。
目前,存儲大小是可以設(shè)置和請求的唯一資源。 未來可能會包含 IOPS、吞吐量等屬性。
FEATURE STATE: Kubernetes v1.18 [stable]
針對 PV 持久卷,Kubernetes 支持兩種卷模式(?volumeModes?):?Filesystem(文件系統(tǒng))? 和 ?Block(塊)?。 ?volumeMode ?是一個可選的 API 參數(shù)。 如果該參數(shù)被省略,默認(rèn)的卷模式是 ?Filesystem?。
?volumeMode ?屬性設(shè)置為 ?Filesystem ?的卷會被 Pod 掛載(Mount) 到某個目錄。 如果卷的存儲來自某塊設(shè)備而該設(shè)備目前為空,Kuberneretes 會在第一次掛載卷之前 在設(shè)備上創(chuàng)建文件系統(tǒng)。
你可以將 ?volumeMode ?設(shè)置為 ?Block?,以便將卷作為原始塊設(shè)備來使用。 這類卷以塊設(shè)備的方式交給 Pod 使用,其上沒有任何文件系統(tǒng)。 這種模式對于為 Pod 提供一種使用最快可能方式來訪問卷而言很有幫助,Pod 和 卷之間不存在文件系統(tǒng)層。另外,Pod 中運行的應(yīng)用必須知道如何處理原始塊設(shè)備。
PersistentVolume 卷可以用資源提供者所支持的任何方式掛載到宿主系統(tǒng)上。 如下表所示,提供者(驅(qū)動)的能力不同,每個 PV 卷的訪問模式都會設(shè)置為 對應(yīng)卷所支持的模式值。 例如,NFS 可以支持多個讀寫客戶,但是某個特定的 NFS PV 卷可能在服務(wù)器 上以只讀的方式導(dǎo)出。每個 PV 卷都會獲得自身的訪問模式集合,描述的是 特定 PV 卷的能力。
訪問模式有:
ReadWriteOnce?卷可以被一個節(jié)點以讀寫方式掛載。 ReadWriteOnce 訪問模式也允許運行在同一節(jié)點上的多個 Pod 訪問卷。<
ReadOnlyMany?卷可以被多個節(jié)點以只讀方式掛載。
ReadWriteMany?卷可以被多個節(jié)點以讀寫方式掛載。
ReadWriteOncePod?卷可以被單個 Pod 以讀寫方式掛載。 如果你想確保整個集群中只有一個 Pod 可以讀取或?qū)懭朐?nbsp;PVC, 請使用ReadWriteOncePod 訪問模式。這只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本。
在命令行接口(CLI)中,訪問模式也使用以下縮寫形式:
重要提醒! 每個卷同一時刻只能以一種訪問模式掛載,即使該卷能夠支持 多種訪問模式。例如,一個 GCEPersistentDisk 卷可以被某節(jié)點以 ReadWriteOnce 模式掛載,或者被多個節(jié)點以 ReadOnlyMany 模式掛載,但不可以同時以兩種模式 掛載。
| 卷插件 | ReadWriteOnce | ReadOnlyMany | ReadWriteMany | ReadWriteOncePod |
|---|---|---|---|---|
| AWSElasticBlockStore | - | - | - | |
| AzureFile | - | |||
| AzureDisk | - | - | - | |
| CephFS | - | |||
| Cinder | - | - | - | |
| CSI | 取決于驅(qū)動 | 取決于驅(qū)動 | 取決于驅(qū)動 | 取決于驅(qū)動 |
| FC | - | - | ||
| FlexVolume | 取決于驅(qū)動 | - | ||
| Flocker | - | - | - | |
| GCEPersistentDisk | - | - | ||
| Glusterfs | - | |||
| HostPath | - | - | - | |
| iSCSI | - | - | ||
| Quobyte | - | |||
| NFS | - | |||
| RBD | - | - | ||
| VsphereVolume | - | - (Pod 運行于同一節(jié)點上時可行) | - | |
| PortworxVolume | - | - | ||
| StorageOS | - | - | - |
每個 PV 可以屬于某個類(Class),通過將其 ?storageClassName ?屬性設(shè)置為某個 StorageClass 的名稱來指定。 特定類的 PV 卷只能綁定到請求該類存儲卷的 PVC 申領(lǐng)。 未設(shè)置 ?storageClassName ?的 PV 卷沒有類設(shè)定,只能綁定到那些沒有指定特定 存儲類的 PVC 申領(lǐng)。
早前,Kubernetes 使用注解 ?volume.beta.kubernetes.io/storage-class? 而不是 ?storageClassName ?屬性。這一注解目前仍然起作用,不過在將來的 Kubernetes 發(fā)布版本中該注解會被徹底廢棄。
目前的回收策略有:
rm -rf /thevolume/*?)目前,僅 NFS 和 HostPath 支持回收(Recycle)。 AWS EBS、GCE PD、Azure Disk 和 Cinder 卷都支持刪除(Delete)。
Kubernetes 管理員可以指定持久卷被掛載到節(jié)點上時使用的附加掛載選項。
并非所有持久卷類型都支持掛載選項。
以下卷類型支持掛載選項:
awsElasticBlockStore ?azureDisk ?azureFile ?cephfs ?cinder ?(已棄用于 v1.18)gcePersistentDisk ?glusterfs ?iscsi ?nfs ?quobyte ?(已棄用于 v1.22)rbd ?storageos ?(已棄用于 v1.22)vsphereVolume?Kubernetes 不對掛載選項執(zhí)行合法性檢查。如果掛載選項是非法的,掛載就會失敗。
早前,Kubernetes 使用注解 ?volume.beta.kubernetes.io/mount-options? 而不是 ?mountOptions ?屬性。這一注解目前仍然起作用,不過在將來的 Kubernetes 發(fā)布版本中該注解會被徹底廢棄。
每個 PV 卷可以通過設(shè)置節(jié)點親和性來定義一些約束,進而限制從哪些節(jié)點上可以訪問此卷。 使用這些卷的 Pod 只會被調(diào)度到節(jié)點親和性規(guī)則所選擇的節(jié)點上執(zhí)行。 要設(shè)置節(jié)點親和性,配置 PV 卷 ?.spec? 中的 ?nodeAffinity?。
對大多數(shù)類型的卷而言,你不需要設(shè)置節(jié)點親和性字段。 AWS EBS、 GCE PD 和 Azure Disk 卷類型都能 自動設(shè)置相關(guān)字段。 你需要為 local 卷顯式地設(shè)置 此屬性。
每個卷會處于以下階段(Phase)之一:
命令行接口能夠顯示綁定到某 PV 卷的 PVC 對象。
每個 PVC 對象都有 ?spec ?和 ?status ?部分,分別對應(yīng)申領(lǐng)的規(guī)約和狀態(tài)。 PersistentVolumeClaim 對象的名稱必須是合法的 DNS 子域名.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
申領(lǐng)在請求具有特定訪問模式的存儲時,使用與卷相同的訪問模式約定。
申領(lǐng)使用與卷相同的約定來表明是將卷作為文件系統(tǒng)還是塊設(shè)備來使用。
申領(lǐng)和 Pod 一樣,也可以請求特定數(shù)量的資源。在這個上下文中,請求的資源是存儲。 卷和申領(lǐng)都使用相同的 資源模型。
申領(lǐng)可以設(shè)置標(biāo)簽選擇算符 來進一步過濾卷集合。只有標(biāo)簽與選擇算符相匹配的卷能夠綁定到申領(lǐng)上。 選擇算符包含兩個字段:
matchLabels ?- 卷必須包含帶有此值的標(biāo)簽matchExpressions ?- 通過設(shè)定鍵(key)、值列表和操作符(operator) 來構(gòu)造的需求。合法的操作符有 In、NotIn、Exists 和 DoesNotExist。來自 ?matchLabels ?和 ?matchExpressions ?的所有需求都按邏輯與的方式組合在一起。 這些需求都必須被滿足才被視為匹配。
申領(lǐng)可以通過為 ?storageClassName ?屬性設(shè)置 StorageClass 的名稱來請求特定的存儲類。 只有所請求的類的 PV 卷,即 ?storageClassName ?值與 PVC 設(shè)置相同的 PV 卷, 才能綁定到 PVC 申領(lǐng)。
PVC 申領(lǐng)不必一定要請求某個類。如果 PVC 的 ?storageClassName ?屬性值設(shè)置為 ?""?, 則被視為要請求的是沒有設(shè)置存儲類的 PV 卷,因此這一 PVC 申領(lǐng)只能綁定到未設(shè)置 存儲類的 PV 卷(未設(shè)置注解或者注解值為 ?""? 的 PersistentVolume(PV)對象在系統(tǒng)中不會被刪除,因為這樣做可能會引起數(shù)據(jù)丟失。 未設(shè)置 ?storageClassName ?的 PVC 與此大不相同,也會被集群作不同處理。 具體篩查方式取決于 ?DefaultStorageClass ?準(zhǔn)入控制器插件 是否被啟用。
storageClassName ?的 PVC 都只能綁定到隸屬于默認(rèn)存儲類的 PV 卷。 設(shè)置默認(rèn) StorageClass 的工作是通過將對應(yīng) StorageClass 對象的注解 ?storageclass.kubernetes.io/is-default-class? 賦值為 ?true ?來完成的。 如果管理員未設(shè)置默認(rèn)存儲類,集群對 PVC 創(chuàng)建的處理方式與未啟用準(zhǔn)入控制器插件 時相同。如果設(shè)定的默認(rèn)存儲類不止一個,準(zhǔn)入控制插件會禁止所有創(chuàng)建 PVC 操作。storageClassName ?的 PVC 都只能綁定到未設(shè)置存儲類的 PV 卷。 在這種情況下,未設(shè)置 ?storageClassName ?的 PVC 與 ?storageClassName ?設(shè)置未 ?""? 的 PVC 的處理方式相同。取決于安裝方法,默認(rèn)的 StorageClass 可能在集群安裝期間由插件管理器(Addon Manager)部署到集群中。
當(dāng)某 PVC 除了請求 StorageClass 之外還設(shè)置了 ?selector?,則這兩種需求會按 邏輯與關(guān)系處理:只有隸屬于所請求類且?guī)в兴埱髽?biāo)簽的 PV 才能綁定到 PVC。
目前,設(shè)置了非空 ?
selector?的 PVC 對象無法讓集群為其動態(tài)供應(yīng) PV 卷。
早前,Kubernetes 使用注解 ?volume.beta.kubernetes.io/storage-class? 而不是 ?storageClassName ?屬性。這一注解目前仍然起作用,不過在將來的 Kubernetes 發(fā)布版本中該注解會被徹底廢棄。
Pod 將申領(lǐng)作為卷來使用,并藉此訪問存儲資源。 申領(lǐng)必須位于使用它的 Pod 所在的同一名字空間內(nèi)。 集群在 Pod 的名字空間中查找申領(lǐng),并使用它來獲得申領(lǐng)所使用的 PV 卷。 之后,卷會被掛載到宿主上并掛載到 Pod 中。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
PersistentVolume 卷的綁定是排他性的。 由于 PersistentVolumeClaim 是名字空間作用域的對象,使用 "Many" 模式(?ROX?、?RWX?)來掛載申領(lǐng)的操作只能在同一名字空間內(nèi)進行。
?hostPath ?PersistentVolume 使用節(jié)點上的文件或目錄來模擬網(wǎng)絡(luò)附加(network-attached)存儲。
FEATURE STATE: Kubernetes v1.18 [stable]
以下卷插件支持原始塊卷,包括其動態(tài)供應(yīng)(如果支持的話)的卷:
apiVersion: v1
kind: PersistentVolume
metadata:
name: block-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
volumeMode: Block
persistentVolumeReclaimPolicy: Retain
fc:
targetWWNs: ["50060e801049cfd1"]
lun: 0
readOnly: false
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi
FEATURE STATE: Kubernetes v1.22 [alpha]
Kubernetes 支持自定義的卷填充器;Kubernetes 1.18 版本引入了這個 alpha 特性。 Kubernetes 1.22 使用重新設(shè)計的 API 重新實現(xiàn)了該機制。 確認(rèn)你正在閱讀與你的集群版本一致的 Kubernetes 文檔。
要檢查版本,請輸入 ?kubectl version?。
要使用自定義的卷填充器,你必須為 kube-apiserver 和 kube-controller-manager 啟用 ?
AnyVolumeDataSource?特性門控。
卷填充器利用了 PVC 規(guī)約字段 ?dataSourceRef?。 不像 ?dataSource ?字段只能包含對另一個持久卷申領(lǐng)或卷快照的引用, ?dataSourceRef ?字段可以包含對同一命名空間中任何對象的引用(不包含除 PVC 以外的核心資源)。 對于啟用了特性門控的集群,使用 ?dataSourceRef ?比 ?dataSource ?更好。
?dataSourceRef ?字段的行為與 ?dataSource ?字段幾乎相同。 如果其中一個字段被指定而另一個字段沒有被指定,API 服務(wù)器將給兩個字段相同的值。 這兩個字段都不能在創(chuàng)建后改變,如果試圖為這兩個字段指定不同的值,將導(dǎo)致驗證錯誤。 因此,這兩個字段將總是有相同的內(nèi)容。
在 ?dataSourceRef ?字段和 ?dataSource ?字段之間有兩個用戶應(yīng)該注意的區(qū)別:
dataSource ?字段會忽略無效的值(如同是空值), 而 ?dataSourceRef ?字段永遠不會忽略值,并且若填入一個無效的值,會導(dǎo)致錯誤。 無效值指的是 PVC 之外的核心對象(沒有 apiGroup 的對象)。dataSourceRef ?字段可以包含不同類型的對象,而 ?dataSource ?字段只允許 PVC 和卷快照。用戶應(yīng)該始終在啟用了特性門控的集群上使用 ?dataSourceRef?,而在沒有啟用特性門控的集群上使用 ?dataSource?。 在任何情況下都沒有必要查看這兩個字段。 這兩個字段的值看似相同但是語義稍微不一樣,是為了向后兼容。 特別是混用舊版本和新版本的控制器時,它們能夠互通。
卷填充器是能創(chuàng)建非空卷的控制器, 其卷的內(nèi)容通過一個自定義資源決定。 用戶通過使用 ?dataSourceRef ?字段引用自定義資源來創(chuàng)建一個被填充的卷:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: populated-pvc
spec:
dataSourceRef:
name: example-name
kind: ExampleDataSource
apiGroup: example.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
因為卷填充器是外部組件,如果沒有安裝所有正確的組件,試圖創(chuàng)建一個使用卷填充器的 PVC 就會失敗。 外部控制器應(yīng)該在 PVC 上產(chǎn)生事件,以提供創(chuàng)建狀態(tài)的反饋,包括在由于缺少某些組件而無法創(chuàng)建 PVC 的情況下發(fā)出警告。
你可以把 alpha 版本的卷數(shù)據(jù)源驗證器 控制器安裝到你的集群中。 如果沒有填充器處理該數(shù)據(jù)源的情況下,該控制器會在 PVC 上產(chǎn)生警告事件。 當(dāng)一個合適的填充器被安裝到 PVC 上時,該控制器的職責(zé)是上報與卷創(chuàng)建有關(guān)的事件,以及在該過程中發(fā)生的問題。
apiVersion: v1
kind: Pod
metadata:
name: pod-with-block-volume
spec:
containers:
- name: fc-container
image: fedora:26
command: ["/bin/sh", "-c"]
args: [ "tail -f /dev/null" ]
volumeDevices:
- name: data
devicePath: /dev/xvda
volumes:
- name: data
persistentVolumeClaim:
claimName: block-pvc
向 Pod 中添加原始塊設(shè)備時,你要在容器內(nèi)設(shè)置設(shè)備路徑而不是掛載路徑。
如果用戶通過 PersistentVolumeClaim 規(guī)約的 ?volumeMode ?字段來表明對原始 塊設(shè)備的請求,綁定規(guī)則與之前版本中未在規(guī)約中考慮此模式的實現(xiàn)略有不同。 下面列舉的表格是用戶和管理員可以為請求原始塊設(shè)備所作設(shè)置的組合。 此表格表明在不同的組合下卷是否會被綁定。
靜態(tài)供應(yīng)卷的卷綁定矩陣:
| PV volumeMode | PVC volumeMode | Result |
|---|---|---|
| 未指定 | 未指定 | 綁定 |
| 未指定 | Block | 不綁定 |
| 未指定 | Filesystem | 綁定 |
| Block | 未指定 | 不綁定 |
| Block | Block | 綁定 |
| Block | Filesystem | 不綁定 |
| Filesystem | Filesystem | 綁定 |
| Filesystem | Block | 不綁定 |
| Filesystem | 未指定 | 綁定 |
Alpha 發(fā)行版本中僅支持靜態(tài)供應(yīng)的卷。 管理員需要在處理原始塊設(shè)備時小心處理這些值。
FEATURE STATE: Kubernetes v1.17 [beta]
卷快照(Volume Snapshot)功能的添加僅是為了支持 CSI 卷插件。
要啟用從卷快照數(shù)據(jù)源恢復(fù)數(shù)據(jù)卷的支持,可在 API 服務(wù)器和控制器管理器上啟用 ?VolumeSnapshotDataSource ?特性門控。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restore-pvc
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: new-snapshot-test
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
卷克隆功能特性僅適用于 CSI 卷插件。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-pvc
spec:
storageClassName: my-csi-plugin
dataSource:
name: existing-src-pvc-name
kind: PersistentVolumeClaim
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
如果你要編寫配置模板和示例用來在很多集群上運行并且需要持久性存儲,建議你使用以下模式:
persistentVolumeClaim.storageClassName? 字段中。 這樣會使得 PVC 在集群被管理員啟用了存儲類支持時能夠匹配到正確的存儲類,persistentVolumeClaim.storageClassName? 留空(nil)。 這樣,集群會使用默認(rèn) ?StorageClass ?為用戶自動供應(yīng)一個存儲卷。 很多集群環(huán)境都配置了默認(rèn)的 ?StorageClass?,或者管理員也可以自行創(chuàng)建默認(rèn)的 ?StorageClass?。

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流