Kubernetes 1.31:防止无序删除时 PersistentVolume 泄漏

PersistentVolume(简称 PV) 具有与之关联的回收策略。 回收策略用于确定在删除绑定到 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 删除的顺序决定了回收策略是否被执行。 如果 PVC 先被删除,则回收策略被执行;但如果在删除 PVC 之前 PV 被删除, 则回收策略不会被执行。因此,外部基础设施中关联的存储资产未被移除。

Kubernetes v1.31 的 PV 回收策略

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

如何启用新的行为?

要利用新的行为,你必须将集群升级到 Kubernetes v1.31 版本,并运行 CSI external-provisioner v5.0.1 或更高版本。

工作方式

对于 CSI 卷,新的行为是通过在新创建和现有的 PV 上添加 Finalizer external-provisioner.volume.kubernetes.io/finalizer 来实现的。 只有在后端存储被删除后,Finalizer 才会被移除。

下面是一个带 Finalizer 的 PV 示例,请注意 Finalizer 列表中的新 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 防止此 PersistentVolume 从集群中被移除。如前文所述,Finalizer 仅在从存储后端被成功删除后才会从 PV 对象中被移除。进一步了解 Finalizer, 请参阅使用 Finalizer 控制删除

同样,Finalizer 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 Storage 系统任何部分的设计和开发,请加入 Kubernetes Storage SIG。 我们正在快速成长,始终欢迎新的贡献者。