本文已发布一年以上。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。
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-provisioner
和 kube-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(如果存在)。
一些注意事项
- 该修复程序仅适用于 CSI 卷和迁移卷。树内卷将显示旧行为。
- 该修复程序作为
external-provisioner
中HonorPVReclaimPolicy
功能门下的 Alpha 功能引入。该功能默认禁用,需要显式启用。
参考
如何参与?
Kubernetes Slack 频道 SIG Storage 通信频道 是联系 SIG Storage 和迁移工作组的绝佳媒介。
特别感谢以下人员的深刻评论、全面考虑和宝贵贡献
- Jan Šafránek (jsafrane)
- Xing Yang (xing-yang)
- Matthew Wong (wongma7)
那些有兴趣参与 CSI 或 Kubernetes 存储系统任何部分的设计和开发的人员,请加入Kubernetes 存储特别兴趣小组 (SIG)。我们正在快速发展,并始终欢迎新的贡献者。