本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

Kubernetes 1.25:使用密鑰進行節點驅動的 CSI 卷擴展

Kubernetes v1.25 在本月稍早發布,推出一項新功能,讓您的叢集可以擴展儲存卷,即使存取這些卷需要密鑰 (例如:用於存取 SAN 光纖網路的憑證) 才能執行節點擴展操作。此新行為為 Alpha 階段,您必須啟用功能閘道 (CSINodeExpandSecret) 才能使用它。您也必須使用 CSI 儲存;此變更與 Kubernetes 內建的儲存驅動程式無關。

若要開啟此新的 Alpha 功能,您需要為 kube-apiserver 和 kubelet 啟用 CSINodeExpandSecret 功能閘道,這會啟用一種機制,將 secretRef 組態作為 CSI 驅動程式 NodeExpansion 的一部分傳送,以便利用相同的組態對底層儲存系統執行節點端擴展操作。

這一切是關於什麼?

在 Kubernetes v1.24 之前,您可以定義叢集層級的 StorageClass,以使用 StorageClass 密鑰,但您沒有任何機制可以指定在儲存裝置掛載到節點上以及卷必須在節點端擴展時,用於操作的憑證。

Kubernetes CSI 已經實作了類似的機制,適用於特定種類的卷調整大小;也就是說,PersistentVolume 的調整大小,其中調整大小的發生與任何稱為 Controller Expansion 的節點無關。在這種情況下,您可以將 PersistentVolume 與包含卷調整大小動作憑證的密鑰相關聯,以便可以進行控制器擴展。CSI 也支援 nodeExpandVolume 操作,CSI 驅動程式可以獨立於控制器擴展或與控制器擴展一起使用,其中調整大小是由叢集中卷已掛載的節點驅動。請閱讀 Kubernetes 1.24:卷擴展現已成為穩定功能

  • 有時,CSI 驅動程式需要在繼續進行節點層級檔案系統擴展操作之前,檢查後端區塊儲存 (或映像檔) 的實際大小。這可以避免在檔案系統擴展期間,後端儲存叢集傳回誤判的肯定結果。

  • 當 PersistentVolume 代表加密的區塊儲存 (例如使用 LUKS) 時,您需要提供密碼才能擴展裝置,並使其有可能在該裝置上擴增檔案系統。

  • 為了在節點擴展時進行各種驗證,CSI 驅動程式必須連接到後端儲存叢集。如果 nodeExpandVolume 請求包含 secretRef,則 CSI 驅動程式可以利用相同的 secretRef 連接到儲存叢集以執行叢集操作。

它是如何運作的?

為了從此 Kubernetes 版本啟用此功能,SIG Storage 引入了一個名為 CSINodeExpandSecret 的新功能閘道。一旦在叢集中啟用功能閘道,NodeExpandVolume 請求就可以包含 secretRef 欄位。NodeExpandVolume 請求是 CSI 的一部分;例如,在從 Kubernetes 控制平面傳送到 CSI 驅動程式的請求中。

作為叢集操作員,系統管理員可以在 StorageClass 中將這些密鑰指定為不透明參數,就像您已經可以指定其他 CSI 密鑰資料一樣。StorageClass 需要設定一些 CSI 特定的參數。以下是這些參數的範例

csi.storage.k8s.io/node-expand-secret-name: test-secret
csi.storage.k8s.io/node-expand-secret-namespace: default

如果已啟用功能閘道且 StorageClass 攜帶上述密鑰組態,則 CSI Provisioner 會從密鑰接收憑證,作為 NodeExpansion 請求的一部分。

線上擴展需要密鑰的 CSI 卷將會設定 NodeExpandSecretRef 欄位。如果未設定,則將在沒有密鑰的情況下進行 NodeExpandVolume CSI RPC 呼叫。

試用看看

  1. 啟用 CSINodeExpandSecret 功能閘道 (請參閱 功能閘道)。

  2. 建立密鑰,然後建立使用該密鑰的 StorageClass。

以下是保存憑證的密鑰範例資訊清單

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 驅動程式,方法是載入該密鑰並將資料傳遞給儲存驅動程式。

以下是範例偵錯記錄

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 的動態佈建,請參閱 Storage ClassesPersistent Volumes

請加入 Kubernetes Storage SIG (特殊興趣小組) 以參與,協助我們增強此功能。已經有很多好主意了,我們很樂意有更多!