本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
介紹 PersistentVolumes 的單 Pod 存取模式
上個月發布的 Kubernetes v1.22 為永續性磁碟區和永續性磁碟區宣告引入了新的 ReadWriteOncePod 存取模式。透過此 Alpha 功能,Kubernetes 允許您將磁碟區存取限制為叢集中的單一 Pod。
什麼是存取模式,它們為何重要?
使用儲存空間時,有多種方式可以對該儲存空間的使用方式進行建模。
例如,像網路檔案共用這樣的儲存系統可以有多個使用者同時讀取和寫入資料。在其他情況下,也許每個人都允許讀取資料,但不允許寫入資料。對於高度敏感的資料,也許只允許一個使用者讀取和寫入資料,而其他人都不允許。
在 Kubernetes 的世界中,存取模式是您可以定義永續儲存空間如何使用的方式。這些存取模式是永續性磁碟區 (PV) 和永續性磁碟區宣告 (PVC) 規格的一部分。
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: shared-cache
spec:
accessModes:
- ReadWriteMany # Allow many nodes to access shared-cache simultaneously.
resources:
requests:
storage: 1Gi
在 v1.22 之前,Kubernetes 為 PV 和 PVC 提供了三種存取模式
- ReadWriteOnce – 磁碟區可以由單一節點掛載為讀寫
- ReadOnlyMany – 磁碟區可以由多個節點以唯讀方式掛載
- ReadWriteMany – 磁碟區可以由多個節點掛載為讀寫
這些存取模式由 Kubernetes 元件(如 kube-controller-manager
和 kubelet
)強制執行,以確保只有某些 Pod 允許存取給定的永續性磁碟區。
這個新的存取模式是什麼,它是如何運作的?
Kubernetes v1.22 為 PV 和 PVC 引入了第四種存取模式,您可以將其用於 CSI 磁碟區
- ReadWriteOncePod – 磁碟區可以由單一 Pod 掛載為讀寫
如果您建立一個 Pod,其 PVC 使用 ReadWriteOncePod 存取模式,Kubernetes 可確保該 Pod 是整個叢集中唯一可以讀取該 PVC 或寫入其中的 Pod。
如果您建立另一個 Pod,該 Pod 引用具有此存取模式的相同 PVC,則該 Pod 將無法啟動,因為 PVC 已被另一個 Pod 使用。例如
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 1s default-scheduler 0/1 nodes are available: 1 node has pod using PersistentVolumeClaim with the same name and ReadWriteOncePod access mode.
這與 ReadWriteOnce 存取模式有何不同?
ReadWriteOnce 存取模式將磁碟區存取限制為單一節點,這表示同一節點上的多個 Pod 可能可以從同一磁碟區讀取和寫入。對於某些應用程式來說,這可能是一個主要問題,特別是如果它們需要最多一個寫入器來保證資料安全。
使用 ReadWriteOncePod,這些問題將會消失。在您的 PVC 上設定存取模式,Kubernetes 保證只有單一 Pod 可以存取。
我該如何使用它?
ReadWriteOncePod 存取模式在 Kubernetes v1.22 中處於 Alpha 階段,僅支援 CSI 磁碟區。第一步,您需要為 kube-apiserver
、kube-scheduler
和 kubelet
啟用 ReadWriteOncePod 功能閘道。您可以透過設定命令列引數來啟用此功能
--feature-gates="...,ReadWriteOncePod=true"
您還需要將以下 CSI Sidecar 更新到這些版本或更高版本
建立永續性磁碟區宣告
為了將 ReadWriteOncePod 存取模式用於您的 PV 和 PVC,您需要使用存取模式建立新的 PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: single-writer-only
spec:
accessModes:
- ReadWriteOncePod # Allow only a single pod to access single-writer-only.
resources:
requests:
storage: 1Gi
如果您的儲存外掛程式支援動態佈建,則將建立新的永續性磁碟區,並套用 ReadWriteOncePod 存取模式。
遷移現有的永續性磁碟區
如果您有現有的永續性磁碟區,則可以將它們遷移為使用 ReadWriteOncePod。
在本範例中,我們已經有一個「cat-pictures-pvc」永續性磁碟區宣告,它繫結到「cat-pictures-pv」永續性磁碟區,以及一個使用此永續性磁碟區宣告的「cat-pictures-writer」部署。
第一步,您需要編輯永續性磁碟區的 spec.persistentVolumeReclaimPolicy
並將其設定為 Retain
。這可確保當我們刪除對應的永續性磁碟區宣告時,您的永續性磁碟區不會被刪除
kubectl patch pv cat-pictures-pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
接下來,您需要停止任何正在使用繫結到您要遷移的永續性磁碟區的永續性磁碟區宣告的工作負載,然後刪除永續性磁碟區宣告。
完成後,您需要清除永續性磁碟區的 spec.claimRef.uid
,以確保永續性磁碟區宣告可以在重新建立時繫結到它
kubectl scale --replicas=0 deployment cat-pictures-writer
kubectl delete pvc cat-pictures-pvc
kubectl patch pv cat-pictures-pv -p '{"spec":{"claimRef":{"uid":""}}}'
之後,您需要將永續性磁碟區的存取模式替換為 ReadWriteOncePod
kubectl patch pv cat-pictures-pv -p '{"spec":{"accessModes":["ReadWriteOncePod"]}}'
注意
ReadWriteOncePod 存取模式不能與其他存取模式結合使用。更新時,請確保 ReadWriteOncePod 是永續性磁碟區上唯一的存取模式,否則請求將會失敗。接下來,您需要修改永續性磁碟區宣告,以將 ReadWriteOncePod 設定為唯一的存取模式。您還應該將永續性磁碟區宣告的 spec.volumeName
設定為您的永續性磁碟區的名稱。
完成此操作後,您可以重新建立永續性磁碟區宣告並啟動您的工作負載
# IMPORTANT: Make sure to edit your PVC in cat-pictures-pvc.yaml before applying. You need to:
# - Set ReadWriteOncePod as the only access mode
# - Set spec.volumeName to "cat-pictures-pv"
kubectl apply -f cat-pictures-pvc.yaml
kubectl apply -f cat-pictures-writer-deployment.yaml
最後,您可以編輯永續性磁碟區的 spec.persistentVolumeReclaimPolicy
,如果之前已更改,則將其設定回 Delete
。
kubectl patch pv cat-pictures-pv -p '{"spec":{"persistentVolumeReclaimPolicy":"Delete"}}'
您可以閱讀設定 Pod 以使用永續性磁碟區進行儲存,以取得有關使用永續性磁碟區和永續性磁碟區宣告的更多詳細資訊。
哪些磁碟區外掛程式支援此功能?
唯一支援此功能的磁碟區外掛程式是 CSI 驅動程式。SIG Storage 不計劃為樹狀外掛程式提供支援,因為它們正作為 CSI 遷移的一部分被棄用。對於喜歡將舊版樹狀磁碟區 API 與已啟用的 CSI 遷移一起使用的使用者,可能會考慮在 Beta 版中提供支援。
作為儲存廠商,我該如何為我的 CSI 驅動程式新增對此存取模式的支援?
ReadWriteOncePod 存取模式將開箱即用,無需對 CSI 驅動程式進行任何必要的更新,但確實需要更新 CSI Sidecar。話雖如此,如果您想隨時掌握 CSI 規格 (v1.5.0+) 的最新變更,請繼續閱讀。
為了消除舊版 SINGLE_NODE_WRITER
存取模式的歧義,CSI 規格中引入了兩種新的存取模式。它們是 SINGLE_NODE_SINGLE_WRITER
和 SINGLE_NODE_MULTI_WRITER
。為了向 Sidecar(例如 external-provisioner)傳達您的驅動程式理解並接受這兩種新的 CSI 存取模式,您的驅動程式還需要針對控制器服務和節點服務宣傳 SINGLE_NODE_MULTI_WRITER
功能。
如果您想了解這些存取模式和功能位元的動機,您也可以閱讀 KEP-2485(ReadWriteOncePod 永續性磁碟區存取模式)的CSI 規格變更、磁碟區功能章節。
更新您的 CSI 驅動程式以使用新的介面
第一步,您需要將驅動程式的 container-storage-interface
相依性更新到 v1.5.0+,其中包含對這些新存取模式和功能的支援。
接受新的 CSI 存取模式
如果您的 CSI 驅動程式包含用於驗證請求的 CSI 存取模式的邏輯,則可能需要更新它。如果它目前接受 SINGLE_NODE_WRITER
,則應更新為也接受 SINGLE_NODE_SINGLE_WRITER
和 SINGLE_NODE_MULTI_WRITER
。
以GCP PD CSI 驅動程式驗證邏輯為例,以下說明如何擴展
diff --git a/pkg/gce-pd-csi-driver/utils.go b/pkg/gce-pd-csi-driver/utils.go
index 281242c..b6c5229 100644
--- a/pkg/gce-pd-csi-driver/utils.go
+++ b/pkg/gce-pd-csi-driver/utils.go
@@ -123,6 +123,8 @@ func validateAccessMode(am *csi.VolumeCapability_AccessMode) error {
case csi.VolumeCapability_AccessMode_SINGLE_NODE_READER_ONLY:
case csi.VolumeCapability_AccessMode_MULTI_NODE_READER_ONLY:
case csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER:
+ case csi.VolumeCapability_AccessMode_SINGLE_NODE_SINGLE_WRITER:
+ case csi.VolumeCapability_AccessMode_SINGLE_NODE_MULTI_WRITER:
default:
return fmt.Errorf("%v access mode is not supported for for PD", am.GetMode())
}
宣告新的 CSI 控制器和節點服務功能
您的 CSI 驅動程式也需要傳回新的 SINGLE_NODE_MULTI_WRITER
功能,作為 ControllerGetCapabilities
和 NodeGetCapabilities
RPC 的一部分。
以GCP PD CSI 驅動程式功能宣告邏輯為例,以下說明如何擴展
diff --git a/pkg/gce-pd-csi-driver/gce-pd-driver.go b/pkg/gce-pd-csi-driver/gce-pd-driver.go
index 45903f3..0d7ea26 100644
--- a/pkg/gce-pd-csi-driver/gce-pd-driver.go
+++ b/pkg/gce-pd-csi-driver/gce-pd-driver.go
@@ -56,6 +56,8 @@ func (gceDriver *GCEDriver) SetupGCEDriver(name, vendorVersion string, extraVolu
csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
csi.VolumeCapability_AccessMode_MULTI_NODE_READER_ONLY,
csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
+ csi.VolumeCapability_AccessMode_SINGLE_NODE_SINGLE_WRITER,
+ csi.VolumeCapability_AccessMode_SINGLE_NODE_MULTI_WRITER,
}
gceDriver.AddVolumeCapabilityAccessModes(vcam)
csc := []csi.ControllerServiceCapability_RPC_Type{
@@ -67,12 +69,14 @@ func (gceDriver *GCEDriver) SetupGCEDriver(name, vendorVersion string, extraVolu
csi.ControllerServiceCapability_RPC_EXPAND_VOLUME,
csi.ControllerServiceCapability_RPC_LIST_VOLUMES,
csi.ControllerServiceCapability_RPC_LIST_VOLUMES_PUBLISHED_NODES,
+ csi.ControllerServiceCapability_RPC_SINGLE_NODE_MULTI_WRITER,
}
gceDriver.AddControllerServiceCapabilities(csc)
ns := []csi.NodeServiceCapability_RPC_Type{
csi.NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME,
csi.NodeServiceCapability_RPC_EXPAND_VOLUME,
csi.NodeServiceCapability_RPC_GET_VOLUME_STATS,
+ csi.NodeServiceCapability_RPC_SINGLE_NODE_MULTI_WRITER,
}
gceDriver.AddNodeServiceCapabilities(ns)
實作 NodePublishVolume
行為
CSI 規範概述了針對 NodePublishVolume
RPC 的預期行為,當針對相同卷但使用不同引數(如目標路徑)多次呼叫時。關於在您的驅動程式中實作時的預期行為的更多詳細資訊,請參閱 CSI 規範的 NodePublishVolume 區段中的第二個表格。
更新您的 CSI Sidecar
當部署您的 CSI 驅動程式時,您必須將以下 CSI Sidecar 更新到依賴 CSI 規範 v1.5.0+ 和 Kubernetes v1.22 API 的版本。最低要求的版本為
下一步是什麼?
作為此功能的 Beta 畢業階段的一部分,SIG Storage 計劃更新 Kubernetes 排程器,以支援與 ReadWriteOncePod 儲存相關的 Pod 搶佔。這表示如果兩個 Pod 要求使用 ReadWriteOncePod 的 PersistentVolumeClaim,則具有最高優先順序的 Pod 將獲得 PersistentVolumeClaim 的存取權,而任何優先順序較低的 Pod 將從節點搶佔,並且無法存取 PersistentVolumeClaim。
如何瞭解更多資訊?
請參閱 KEP-2485 以取得關於 ReadWriteOncePod 存取模式和 CSI 規範變更動機的更多詳細資訊。
如何參與?
Kubernetes #csi Slack 頻道和任何標準 SIG Storage 通訊頻道都是聯繫 SIG Storage 和 CSI 團隊的絕佳媒介。
特別感謝以下人員的深刻見解的審閱和設計考量
- Abdullah Gharaibeh (ahg-g)
- Aldo Culquicondor (alculquicondor)
- Ben Swartzlander (bswartz)
- Deep Debroy (ddebroy)
- Hemant Kumar (gnufied)
- Humble Devassy Chirammal (humblec)
- James DeFelice (jdef)
- Jan Šafránek (jsafrane)
- Jing Xu (jingxu97)
- Jordan Liggitt (liggitt)
- Michelle Au (msau42)
- Saad Ali (saad-ali)
- Tim Hockin (thockin)
- Xing Yang (xing-yang)
如果您有興趣參與 CSI 或 Kubernetes 儲存系統任何部分的設計和開發,請加入 Kubernetes Storage Special Interest Group (SIG)。我們正在快速成長,並且隨時歡迎新的貢獻者。