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

Kubernetes 1.31:防止在亂序刪除時出現 PersistentVolume 洩漏

PersistentVolume(簡稱 PV)與回收策略(Reclaim Policy)相關聯。回收策略用於確定在刪除與 PV 繫結的 PVC 時,儲存後端需要採取的操作。當回收策略為 Delete 時,期望儲存後端釋放為 PV 分配的儲存資源。本質上,回收策略需要在刪除 PV 時得到遵守。

在最近釋出的 Kubernetes v1.31 中,一個 Beta 功能可以讓你配置叢集以這種方式執行,並遵守所配置的回收策略。

在以前的 Kubernetes 版本中,回收是如何工作的?

PersistentVolumeClaim(簡稱 PVC)是使用者對儲存的請求。如果找到了一個新建立的 PV 或一個匹配的 PV,則認為 PV 和 PVC 是繫結的。PV 本身由儲存後端分配的卷支援。

通常,如果要刪除卷,期望的是刪除已繫結的 PV-PVC 對中的 PVC。但是,並沒有限制在刪除 PVC 之前刪除 PV。

首先,我將演示在執行舊版 Kubernetes 的叢集上的行為。

檢索一個與 PV 繫結的 PVC

檢索一個現有的 PVC example-vanilla-block-pvc

kubectl get pvc example-vanilla-block-pvc

以下輸出顯示了 PVC 及其繫結的 PV;PV 顯示在 VOLUME 列下

NAME                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS               AGE
example-vanilla-block-pvc   Bound    pvc-6791fdd4-5fad-438e-a7fb-16410363e3da   5Gi        RWO            example-vanilla-block-sc   19s

刪除 PV

當我嘗試刪除一個已繫結的 PV 時,kubectl 會話會阻塞,kubectl 工具不會將控制權返回給 shell;例如

kubectl delete pv pvc-6791fdd4-5fad-438e-a7fb-16410363e3da
persistentvolume "pvc-6791fdd4-5fad-438e-a7fb-16410363e3da" deleted
^C

檢索 PV

kubectl get pv pvc-6791fdd4-5fad-438e-a7fb-16410363e3da

可以觀察到 PV 處於 Terminating 狀態

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS        CLAIM                               STORAGECLASS               REASON   AGE
pvc-6791fdd4-5fad-438e-a7fb-16410363e3da   5Gi        RWO            Delete           Terminating   default/example-vanilla-block-pvc   example-vanilla-block-sc            2m23s

刪除 PVC

kubectl delete pvc example-vanilla-block-pvc

如果 PVC 成功刪除,會看到以下輸出

persistentvolumeclaim "example-vanilla-block-pvc" deleted

叢集中的 PV 物件也會被刪除。當嘗試檢索 PV 時,會發現 PV 不再存在

kubectl get pv pvc-6791fdd4-5fad-438e-a7fb-16410363e3da
Error from server (NotFound): persistentvolumes "pvc-6791fdd4-5fad-438e-a7fb-16410363e3da" not found

儘管 PV 被刪除了,但底層的儲存資源並未被刪除,需要手動移除。

總而言之,在某些情況下,與 PersistentVolume 關聯的回收策略當前被忽略。對於一個 Bound 狀態的 PV-PVC 對,PV-PVC 的刪除順序決定了 PV 回收策略是否被遵守。如果先刪除 PVC,回收策略會被遵守;然而,如果先於 PVC 刪除 PV,回收策略則不會被執行。這種行為導致外部基礎設施中關聯的儲存資產不會被移除。

Kubernetes v1.31 中的 PV 回收策略

新的行為確保了當使用者嘗試手動刪除 PV 時,底層的儲存物件會從後端被刪除。

如何啟用新行為?

要利用這一新行為,你必須將叢集升級到 Kubernetes v1.31 版本,並執行 CSI external-provisioner5.0.1 或更高版本。

它是如何工作的?

對於 CSI 卷,新行為透過在新的和現有的 PV 上新增一個終結器(finalizer) external-provisioner.volume.kubernetes.io/finalizer 來實現。只有在後端儲存被刪除後,這個終結器才會被移除。`

一個帶有終結器的 PV 示例,注意終結器列表中的新終結器

kubectl get pv pvc-a7b7e3ba-f837-45ba-b243-dec7d8aaed53 -o yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: csi.vsphere.vmware.com
  creationTimestamp: "2021-11-17T19:28:56Z"
  finalizers:
  - kubernetes.io/pv-protection
  - external-provisioner.volume.kubernetes.io/finalizer
  name: pvc-a7b7e3ba-f837-45ba-b243-dec7d8aaed53
  resourceVersion: "194711"
  uid: 087f14f2-4157-4e95-8a70-8294b039d30e
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 1Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: example-vanilla-block-pvc
    namespace: default
    resourceVersion: "194677"
    uid: a7b7e3ba-f837-45ba-b243-dec7d8aaed53
  csi:
    driver: csi.vsphere.vmware.com
    fsType: ext4
    volumeAttributes:
      storage.kubernetes.io/csiProvisionerIdentity: 1637110610497-8081-csi.vsphere.vmware.com
      type: vSphere CNS Block Volume
    volumeHandle: 2dacf297-803f-4ccc-afc7-3d3c3f02051e
  persistentVolumeReclaimPolicy: Delete
  storageClassName: example-vanilla-block-sc
  volumeMode: Filesystem
status:
  phase: Bound

終結器可防止此 PersistentVolume 從叢集中被移除。如前所述,只有在從儲存後端成功刪除 PV 物件後,終結器才會從該物件中移除。要了解有關終結器的更多資訊,請參閱使用終結器控制刪除

類似地,終結器 kubernetes.io/pv-controller 會被新增到動態供應的樹內外掛卷中。

CSI 遷移的卷呢?

該修復也適用於 CSI 遷移的卷。

一些注意事項

此修復不適用於靜態供應的樹內外掛卷。

參考資料

我如何參與?

Kubernetes Slack 頻道 SIG Storage 通訊渠道是聯絡 SIG Storage 和遷移工作組團隊的絕佳媒介。

特別感謝以下人員的深刻見解、周詳考慮和寶貴貢獻

  • Fan Baofa (carlory)
  • Jan Šafránek (jsafrane)
  • Xing Yang (xing-yang)
  • Matthew Wong (wongma7)

如果你有興趣參與 CSI 或 Kubernetes 儲存系統任何部分的設計和開發,請加入 Kubernetes 儲存特別興趣小組 (SIG)。我們正在快速發展,並隨時歡迎新的貢獻者。