
external-snapshotter快照删除策略详解Delete还是Retain一文避免存储资源泄漏【免费下载链接】external-snapshotterSidecar container that watches Kubernetes Snapshot CRD objects and triggers CreateSnapshot/DeleteSnapshot against a CSI endpoint.项目地址: https://gitcode.com/gh_mirrors/ex/external-snapshotter在 Kubernetes 中使用 CSI 存储快照时external-snapshotter是负责监听 VolumeSnapshot 对象并驱动 CSI 驱动创建/删除快照的核心组件。其中deletionPolicy删除策略是决定快照命运的关键字段选错Delete或Retain轻则数据无法回收重则底层存储被幽灵快照占满。本文将带你彻底搞懂这两种策略的差异、配置位置和源码执行流程帮你一文避开存储资源泄漏的坑。一、先搞清楚external-snapshotter 是怎么删快照的external-snapshotter 由两个组件协同工作见 README.md 和 deploy/kubernetes/ 部署清单snapshot-controller集群级控制器监听VolumeSnapshot对象负责创建/删除VolumeSnapshotContent对象csi-snapshotter sidecar与 CSI 驱动同 Pod 部署监听VolumeSnapshotContent对象真正调用 CSI 的CreateSnapshot/DeleteSnapshot接口操作底层存储。当你执行删除快照操作时真正调用 CSIDeleteSnapshot的时机完全由VolumeSnapshotContent.spec.deletionPolicy这个字段决定。二、Delete vs Retain一张表看懂两种策略策略的定义位于 client/apis/volumesnapshot/v1/types.go 第 445~457 行只有两个合法值策略删除 VolumeSnapshot 后VolumeSnapshotContent 对象底层物理快照Delete✅ 自动级联删除被删除通过 CSIDeleteSnapshot删除Retain⛔ 保留保留变成孤儿保留在存储系统中简单类比Delete删了 Kubernetes 对象存储上的快照跟着一起删资源自动回收省心Retain删了 Kubernetes 对象但快照留在原地需要管理员手动到存储侧清理——适合跨集群迁移、灾备归档等场景。 这正是资源泄漏的高发区用了Retain却忘了手动清理物理快照会一直占用存储容量。三、在哪里设置 deletionPolicy1️⃣ 动态快照写在 VolumeSnapshotClass 里对于通过 PVC 动态创建的快照策略由集群级资源VolumeSnapshotClass.deletionPolicy指定示例见 examples/kubernetes/snapshotclass-v1.yamlapiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass metadata: name: csi-hostpath-snapclass-v1 driver: hostpath.csi.k8s.io deletionPolicy: Delete快照创建时sidecar 会把 Class 中的策略自动抄写到VolumeSnapshotContent.spec.deletionPolicy源码见 pkg/common-controller/snapshot_controller.go 第 757 行。因此动态快照不需要也不应该手动改 Content 的策略。2️⃣ 预置快照必须手动填写如果是把集群外已存在的快照导入Kubernetes即预先创建VolumeSnapshotContentsource.snapshotHandle指向已有快照则必须在创建时手动指定deletionPolicy——因为此时没有 Class 可以继承字段说明见 client/apis/volumesnapshot/v1/types.go 第 312~323 行。⚠️ 常见错误预置快照忘写deletionPolicy: Delete结果用了Retain快照内容对象永远删不掉存储越堆越多。四、源码视角控制器到底怎么执行删除snapshot-controller 侧pkg/common-controller/snapshot_controller.go 第 260~274 行删除VolumeSnapshot时控制器找到绑定的 Content只按一条规则判断是否级联删除 Content 对象deleteContent (content.Spec.DeletionPolicy crdv1.VolumeSnapshotContentDelete)如果是Retain则只摘除 Snapshot 自身的 finalizerContent 对象原样保留。csi-snapshotter sidecar 侧pkg/sidecar-controller/snapshot_controller.go 第 61~86 行Content 对象被标记删除时sidecar 分两条路走Delete 策略且快照尚未删除 → 调用 CSIDeleteSnapshot删除物理快照实现位于 pkg/sidecar-controller/csi_handler.go 第 94 行起成功后清除snapshotHandle再移除 finalizerRetain 策略或物理快照已删→跳过 CSI 调用直接移除 finalizer 让 Content 对象消失物理快照留在存储系统里。卷组快照同理VolumeGroupSnapshotClass与VolumeGroupSnapshotContent也带有deletionPolicy字段定义见 client/apis/volumegroupsnapshot/v1/types.go 第 188~198、278~292 行。注意属于卷组快照的单个VolumeSnapshot不允许单独删除只能整体删除组快照策略执行逻辑见 pkg/common-controller/groupsnapshot_controller_helper.go。五、新手最容易踩的 3 个坑 ️Retain 快照没人管删除 VolumeSnapshot 后Content 和物理快照都还在。建议删除前用kubectl get volumesnapshotcontent巡检或建立定期清理孤儿 Content 的运维流程。Retain 的快照想复活这正是 Retain 的价值可以新建一个VolumeSnapshot通过spec.source.volumeSnapshotContentName重新绑定原有 Content 继续使用见 examples/kubernetes/snapshot-v1.yaml 与 examples/kubernetes/restore.yaml 中的用法。用快照恢复 PVC 时急删快照删除流程中有保护逻辑若快照正在被用于恢复 PVC控制器会发出SnapshotDeletePending事件并重试见 pkg/common-controller/snapshot_controller.go 第 288~292 行此时不要手动强删等恢复完成即可。六、Delete 还是 Retain选择指南 ✅场景推荐策略日常开发/测试快照随用随删Delete备份归档、跨集群迁移、灾备快照Retain快照可能被多个环境复用Retain用完手动清理预置快照导入管理员完全可控按需指定默认建议 Retain 防误删一句话总结生产环境想要省心就让VolumeSnapshotClass里写deletionPolicy: Delete让 external-snapshotter 自动级联清理只有明确需要保留物理快照的场景才用Retain并且一定要配套手动清理机制——这是避免存储资源泄漏的黄金法则。想深入了解 CRD 的完整字段定义可以查阅 client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml控制器单测中也有大量策略分支用例例如 pkg/common-controller/snapshot_delete_test.go 和 pkg/sidecar-controller/snapshot_delete_test.go值得对照阅读。【免费下载链接】external-snapshotterSidecar container that watches Kubernetes Snapshot CRD objects and triggers CreateSnapshot/DeleteSnapshot against a CSI endpoint.项目地址: https://gitcode.com/gh_mirrors/ex/external-snapshotter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考