深色模式
快照与数据备份恢复
摘要:本文面向 SRE,讲解 Kubernetes 原生卷快照机制(VolumeSnapshot,GA 于 v1.20)与基于它的备份恢复流程。覆盖架构组件、创建/恢复 YAML、deletionPolicy、应用一致性限制、快照拓扑,以及它与 Velero、数据库逻辑备份的分工。适用 Kubernetes v1.28+;快照为 v1.20+ 稳定能力。
适用版本与前提
- Kubernetes:v1.28+(卷快照 GA 于 v1.20;CRD 位于
snapshot.storage.k8s.io/v1) - 组件:集群已安装 VolumeSnapshot CRD、snapshot-controller、validating webhook,且 CSI 驱动支持快照
- 前提:已理解 CSI 驱动 与 PV/PVC
背景与问题
数据库升级前、误删表前,需要一份"时间点副本"。传统做法是在存储端手动打快照或 mysqldump,与 K8s 资源脱节。Kubernetes 把快照标准化为 VolumeSnapshot API,让"给 PVC 打快照、从快照恢复新 PVC"成为声明式操作,可被 GitOps/自动化调用。
生产危险
Kubernetes 的快照 API 不提供任何应用一致性保证。它只是存储层的块/文件系统时间点副本。数据库等应用必须先 quiesce(暂停写入 / freeze 文件系统)再打快照,否则恢复出的数据可能损坏。不要把它当成"可靠备份"的唯一手段。
架构与组件
- VolumeSnapshot:用户对快照的请求(类 PVC);
- VolumeSnapshotContent:集群中的实际快照资源(类 PV);
- VolumeSnapshotClass:快照的"类别",选驱动、传参数、定
deletionPolicy(类 StorageClass); - snapshot-controller:集群级,负责绑定与生命周期(每集群一份,需 leader election);
- csi-snapshotter:边车,每个支持快照的 CSI 驱动各一份;
- validating webhook:强烈建议安装,防止无效快照对象阻碍后续升级清理。
INFO
VolumeSnapshot/Content/Class 都是 CRD,不在核心 API;且仅 CSI 驱动支持。in-tree 卷无法用 K8s 快照。集群发行版通常已捆绑安装,裸集群需手动装 CRD + controller + webhook(注意命名空间与 leader election)。
操作步骤
步骤 1:创建 VolumeSnapshotClass
yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-snapclass
driver: ebs.csi.aws.com
deletionPolicy: Retain # 删 VolumeSnapshot 时保留后端快照
parameters:
csi.storage.k8s.io/snapshotter-secret-name: "" # 厂商特定,按需1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
deletionPolicy:
Delete:删 VolumeSnapshot 同时删后端快照(默认常见);Retain:保留后端快照,便于长期归档,但需手动清理防泄漏。
步骤 2:从 PVC 动态打快照
yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: db-snapshot-20261008
namespace: prod
spec:
volumeSnapshotClassName: csi-snapclass
source:
persistentVolumeClaimName: db-data-pvc # 源 PVC1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
等待 status.readyToUse: true:
bash
kubectl get volumesnapshot -n prod db-snapshot-20261008 -o jsonpath='{.status.readyToUse}'1
版本相关
快照进行中,源 PVC 受保护不会立即删除("PVC as snapshot source protection"),避免打快照时数据丢失。该保护在快照 readyToUse 或中止后才解除。
步骤 3:从快照恢复新卷
快照不能"回滚"已有 PVC,只能用来供给一个新 PVC(K8s 快照的限制):
yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-restore-pvc
namespace: prod
spec:
accessModes:
- ReadWriteOnce
storageClassName: ebs-sc
resources:
requests:
storage: 20Gi
dataSource:
name: db-snapshot-20261008
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
挂载到新 Pod 即可读取/校验恢复数据,再决定是否切换主库。
预置快照(导入已有后端快照)
由管理员先建 VolumeSnapshotContent(指 snapshotHandle),再建指向它的 VolumeSnapshot(source.volumeSnapshotContentName)。适合把存储端手工快照导入 K8s 管理。
删除策略与清理
bash
# deletionPolicy=Delete 的快照,删除即删后端
kubectl delete volumesnapshot -n prod db-snapshot-20261008
# Retain 的快照删除后,后端仍保留,需到存储端清理1
2
3
2
3
生产危险
快照会持续占用后端容量(尤其是 Retain)。缺乏清理策略会导致"快照蔓延"占满存储配额。务必配合 retention 规则与监控报警。
快照拓扑(多可用区)
多 AZ 集群中,某 AZ 的卷快照只在同 AZ 可用。开启 VolumeSnapshotTopology 特性门(alpha,位于 csi-snapshotter / external-provisioner)后,快照的可用拓扑会被记录到 VolumeSnapshotContent.spec.nodeAffinity,恢复时据此把新卷放到数据可达的 AZ。未开启时跨 AZ 恢复可能失败 [版本相关,alpha 特性,生产使用前验证]。
备份恢复体系:快照不是全部
- CSI 快照:快(元数据操作),适合同后端快速克隆/回滚,但跨存储/跨云不可移植,且需应用一致性处理。
- Velero:备份 K8s 资源 + 卷(可用 CSI 快照或 Restic 文件系统备份),适合整机/集群迁移、跨云。需确认 Velero 版本与目标 K8s 兼容
[厂商特定]。 - 数据库逻辑备份(dump):可跨版本、可单表恢复、可压缩归档到对象存储,是"最后一道防线",与快照互补。
生产建议
三层组合:① 定时 CSI 快照(小时级 RPO,快速回滚);② 每日逻辑 dump 到对象存储(跨存储可移植);③ 关键集群用 Velero 周期性全量。快照不能替代异地/离线备份。
监控与可观测性
- 报警
VolumeSnapshot.status.readyToUse长时间为 false(快照卡住); - 监控后端快照数量与容量占比,防快照蔓延;
- 记录快照创建/恢复耗时,评估 RTO;
- 对敏感 PVC 的快照操作加 RBAC 限制与审计。
常见坑
- 误以为快照能"回滚"现有 PVC——K8s 只能从快照建新卷,不能原地还原。
- 以为快照即应用一致——数据库必须先 freeze,否则恢复即损坏。
deletionPolicy: Retain不清理 → 后端容量泄漏。- 集群没装 validating webhook,导致无效快照对象在升级时无法清理(官方明确警告)。
参考资料
- Kubernetes 官方文档 - Volume Snapshots,访问日期:2026-10-08。
- Kubernetes 官方博客 - Volume Snapshot Moves to GA (v1.20),访问日期:2026-10-08。
- external-snapshotter README (kubernetes-csi),访问日期:2026-10-08。
- Velero 官方文档,访问日期:2026-10-08。