本文已发布一年以上。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.23:防止删除顺序错误时出现 PersistentVolume 泄漏

PersistentVolume(简称 PV)与 回收策略相关联。回收策略用于确定在删除 PV 时存储后端需要执行的操作。当回收策略为 Delete 时,预期存储后端会释放为 PV 分配的存储资源。本质上,回收策略需要在 PV 删除时得到遵守。

在最近的 Kubernetes v1.23 版本中,一项 Alpha 功能允许您配置集群以使其按此方式运行并遵守配置的回收策略。

在之前的 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 及其 Bound 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 工具不会将控制权返回给 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 已被删除,但底层存储资源并未删除,需要手动删除。

总而言之,与 Persistent Volume 关联的回收策略在某些情况下当前会被忽略。对于 Bound 的 PV-PVC 对,PV-PVC 删除的顺序决定了是否遵守 PV 回收策略。如果先删除 PVC,则会遵守回收策略;但是,如果在删除 PVC 之前删除 PV,则不会执行回收策略。由于此行为,外部基础设施中相关的存储资产不会被删除。

Kubernetes v1.23 的 PV 回收策略

新行为确保当用户尝试手动删除 PV 时,底层存储对象会从后端删除。

如何启用新行为?

要使用新行为,您必须将集群升级到 Kubernetes 的 v1.23 版本。您需要确保正在运行 CSI external-provisioner 版本 4.0.0 或更高版本。您还必须为 external-provisionerkube-controller-manager 启用 HonorPVReclaimPolicy 功能门

如果您未使用 CSI 驱动程序与存储后端集成,则此修复程序不可用。Kubernetes 项目目前没有计划修复树内存储驱动程序的错误:这些树内驱动程序的未来是弃用和迁移到 CSI。

它是如何工作的?

通过在新的和现有的 PV 上添加 finalizer external-provisioner.volume.kubernetes.io/finalizer来实现新行为,只有在从后端删除存储后才会删除 finalizer。

带有 finalizer 的 PV 示例,请注意 finalizers 列表中的新 finalizer

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

finalizer 的存在阻止了 PV 对象从集群中被删除。如前所述,仅在从存储后端成功删除后,才从 PV 对象中删除 finalizer。要了解有关 finalizer 的更多信息,请参阅使用 Finalizers 控制删除

CSI 迁移卷呢?

此修复程序也适用于 CSI 迁移卷。但是,如果在 1.23 上启用功能 HonorPVReclaimPolicy 并且禁用 CSI 迁移,则会从 PV 对象中删除 finalizer(如果存在)。

一些注意事项

  1. 该修复程序仅适用于 CSI 卷和迁移卷。树内卷将显示旧行为。
  2. 该修复程序作为 external-provisionerHonorPVReclaimPolicy 功能门下的 Alpha 功能引入。该功能默认禁用,需要显式启用。

参考

如何参与?

Kubernetes Slack 频道 SIG Storage 通信频道 是联系 SIG Storage 和迁移工作组的绝佳媒介。

特别感谢以下人员的深刻评论、全面考虑和宝贵贡献

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

那些有兴趣参与 CSI 或 Kubernetes 存储系统任何部分的设计和开发的人员,请加入Kubernetes 存储特别兴趣小组 (SIG)。我们正在快速发展,并始终欢迎新的贡献者。