本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
Kubernetes 1.25:使用 Secret 進行節點驅動的 CSI 卷擴充套件
Kubernetes v1.25 於本月早些時候釋出,引入了一項新功能,允許你的叢集擴充套件儲存卷,即使訪問這些卷需要 Secret(例如:訪問 SAN 網路的憑據)來執行節點擴容操作。這項新行為處於 Alpha 階段,你必須啟用一個特性門控(CSINodeExpandSecret
)才能使用它。你還必須使用 CSI 儲存;此變更與 Kubernetes 內建的儲存驅動程式無關。
要開啟這個新的 Alpha 功能,你需要在 kube-apiserver 和 kubelet 中啟用 CSINodeExpandSecret
特性門控。這將開啟一個機制,在 NodeExpansion 期間將 secretRef
配置傳送給 CSI 驅動程式,從而利用該機制透過底層儲存系統執行節點側的擴容操作。
這是什麼意思?
在 Kubernetes v1.24 之前,你可以定義一個叢集級別的 StorageClass 來使用 StorageClass Secret,但你沒有任何機制來指定在儲存掛載到節點以及需要在節點側擴展卷時將用於操作的憑據。
Kubernetes CSI 已經為特定型別的卷大小調整實現了一個類似的機制;即針對 PersistentVolume 的大小調整,這種調整獨立於任何節點進行,被稱為控制器擴容(Controller Expansion)。在這種情況下,你將一個 PersistentVolume 與一個包含卷大小調整操作憑據的 Secret 關聯起來,以便進行控制器擴容。CSI 還支援一個 nodeExpandVolume
操作,CSI 驅動程式可以獨立於控制器擴容或與控制器擴容一起使用,這種情況下,大小調整是由卷所掛載的叢集節點驅動的。請閱讀 Kubernetes 1.24:卷擴容現已成為穩定特性
有時,CSI 驅動程式需要在進行節點級檔案系統擴充套件操作之前檢查後端塊儲存(或映像)的實際大小。這可以避免在檔案系統擴充套件期間從後端儲存叢集返回假陽性結果。
當 PersistentVolume 代表加密的塊儲存(例如使用 LUKS)時,你需要提供一個密碼來擴充套件裝置,並使其能夠在裝置上擴充套件檔案系統。
為了在節點擴容時進行各種驗證,CSI 驅動程式必須連線到後端儲存叢集。如果
nodeExpandVolume
請求包含一個secretRef
,那麼 CSI 驅動程式就可以利用它來連線到儲存叢集以執行叢集操作。
它是如何工作的?
為了從這個版本的 Kubernetes 中啟用此功能,SIG Storage 引入了一個名為 CSINodeExpandSecret
的新特性門控。一旦在叢集中啟用了該特性門控,NodeExpandVolume 請求就可以包含一個 secretRef
欄位。NodeExpandVolume 請求是 CSI 的一部分;例如,在從 Kubernetes 控制平面傳送到 CSI 驅動程式的請求中。
作為叢集操作員,你可以將這些 Secret 作為 StorageClass 中的一個不透明引數來指定,就像你已經可以指定其他 CSI Secret 資料一樣。StorageClass 需要設定一些 CSI 特定的引數。以下是這些引數的示例:
csi.storage.k8s.io/node-expand-secret-name: test-secret
csi.storage.k8s.io/node-expand-secret-namespace: default
如果啟用了特性門控並且儲存類攜帶了上述 Secret 配置,CSI Provisioner 就會在 NodeExpansion 請求中從 Secret 中接收憑據。
需要 Secret 才能進行線上擴容的 CSI 卷將設定 NodeExpandSecretRef 欄位。如果未設定,則 NodeExpandVolume CSI RPC 呼叫將在沒有 Secret 的情況下進行。
試一試
啟用
CSINodeExpandSecret
特性門控(請參閱 特性門控)。建立一個 Secret,然後建立一個使用該 Secret 的 StorageClass。
這是一個包含憑據的 Secret 的清單示例
apiVersion: v1
kind: Secret
metadata:
name: test-secret
namespace: default
data:
stringData:
username: admin
password: t0p-Secret
這是一個引用這些憑據的 StorageClass 的清單示例
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-blockstorage-sc
parameters:
csi.storage.k8s.io/node-expand-secret-name: test-secret # the name of the Secret
csi.storage.k8s.io/node-expand-secret-namespace: default # the namespace that the Secret is in
provisioner: blockstorage.cloudprovider.example
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
輸出示例
如果 PersistentVolumeClaim (PVC) 建立成功,你可以在 PersistentVolume 的 spec.csi
欄位中看到該配置(查詢 spec.csi.nodeExpandSecretRef
)。透過執行 kubectl get persistentvolume <pv_name> -o yaml
來檢查它是否正常工作。你應該會看到類似下面的內容。
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
pv.kubernetes.io/provisioned-by: blockstorage.cloudprovider.example
creationTimestamp: "2022-08-26T15:14:07Z"
finalizers:
- kubernetes.io/pv-protection
name: pvc-95eb531a-d675-49f6-940b-9bc3fde83eb0
resourceVersion: "420263"
uid: 6fa824d7-8a06-4e0c-b722-d3f897dcbd65
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 6Gi
claimRef:
apiVersion: v1
kind: PersistentVolumeClaim
name: csi-pvc
namespace: default
resourceVersion: "419862"
uid: 95eb531a-d675-49f6-940b-9bc3fde83eb0
csi:
driver: blockstorage.cloudprovider.example
nodeExpandSecretRef:
name: test-secret
namespace: default
volumeAttributes:
storage.kubernetes.io/csiProvisionerIdentity: 1648042783218-8081-blockstorage.cloudprovider.example
volumeHandle: e21c7809-aabb-11ec-917a-2e2e254eb4cf
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: topology.hostpath.csi/node
operator: In
values:
- racknode01
persistentVolumeReclaimPolicy: Delete
storageClassName: csi-blockstorage-sc
volumeMode: Filesystem
status:
phase: Bound
如果你隨後觸發線上儲存擴容,kubelet 會將適當的憑據傳遞給 CSI 驅動程式,透過載入該 Secret 並將資料傳遞給儲存驅動程式。
以下是一個除錯日誌示例
I0330 03:29:51.966241 1 server.go:101] GRPC call: /csi.v1.Node/NodeExpandVolume
I0330 03:29:51.966261 1 server.go:105] GRPC request: {"capacity_range":{"required_bytes":7516192768},"secrets":"***stripped***","staging_target_path":"/var/lib/kubelet/plugins/kubernetes.io/csi/blockstorage.cloudprovider.example/f7c62e6e08ce21e9b2a95c841df315ed4c25a15e91d8fcaf20e1c2305e5300ab/globalmount","volume_capability":{"AccessType":{"Mount":{}},"access_mode":{"mode":7}},"volume_id":"e21c7809-aabb-11ec-917a-2e2e254eb4cf","volume_path":"/var/lib/kubelet/pods/bcb1b2c4-5793-425c-acf1-47163a81b4d7/volumes/kubernetes.io~csi/pvc-95eb531a-d675-49f6-940b-9bc3fde83eb0/mount"}
I0330 03:29:51.966360 1 nodeserver.go:459] req:volume_id:"e21c7809-aabb-11ec-917a-2e2e254eb4cf" volume_path:"/var/lib/kubelet/pods/bcb1b2c4-5793-425c-acf1-47163a81b4d7/volumes/kubernetes.io~csi/pvc-95eb531a-d675-49f6-940b-9bc3fde83eb0/mount" capacity_range:<required_bytes:7516192768 > staging_target_path:"/var/lib/kubelet/plugins/kubernetes.io/csi/blockstorage.cloudprovider.example/f7c62e6e08ce21e9b2a95c841df315ed4c25a15e91d8fcaf20e1c2305e5300ab/globalmount" volume_capability:<mount:<> access_mode:<mode:SINGLE_NODE_MULTI_WRITER > > secrets:<key:"XXXXXX" value:"XXXXX" > secrets:<key:"XXXXX" value:"XXXXXX" >
未來展望
由於此功能仍處於 Alpha 階段,Kubernetes Storage SIG 期望從 CSI 驅動程式作者那裡獲得更多測試和實現的更新或反饋。社群計劃在未來的版本中最終將此功能提升到 Beta 階段。
參與或瞭解更多?
增強提案包含了關於此功能歷史和技術實現的許多細節。
要了解更多關於 Kubernetes 中基於 StorageClass 的動態供應,請參閱 儲存類 和 持久卷。
請加入 Kubernetes 儲存 SIG (特別興趣小組) 來幫助我們增強此功能。已經有很多好主意了,我們非常歡迎更多人參與進來!