Volume Snapshots¶
A snapshot is a point-in-time copy of one volume's data, taken and restored entirely from inside your own cluster.
This is the mechanism for losing data you meant to keep — a migration that went wrong, a schema change that corrupted a database, a deletion you regret. It is not the mechanism for losing the cluster; see Cluster Backup & Restore for that, and below for the difference.
Everything on this page runs against your cluster's kubeconfig.
What you have¶
Your cluster ships with a VolumeSnapshotClass and the controller behind it, delivered by the platform:
$ kubectl get volumesnapshotclass
NAME DRIVER DELETIONPOLICY AGE
kubevirt-csi-snapclass csi.kubevirt.io Delete 47h
Snapshots are a supported feature of this platform rather than a maybe. The storage behind your cluster is required to support them — it is how your worker nodes are created in the first place, so a platform where snapshots do not work is one where clusters do not boot.
Take one¶
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: postgres-data-2026-08-20
spec:
volumeSnapshotClassName: kubevirt-csi-snapclass
source:
persistentVolumeClaimName: postgres-data
$ kubectl apply -f snapshot.yaml
$ kubectl get volumesnapshot postgres-data-2026-08-20
NAME READYTOUSE SOURCEPVC RESTORESIZE AGE
postgres-data-2026-08-20 true postgres-data 20Gi 8s
Wait for READYTOUSE to be true before you rely on it.
A snapshot that is not ready yet is not a copy of anything.
A snapshot is not automatically consistent
The snapshot is taken at the block level, while your application is still writing. For a filesystem that is usually survivable; for a database it can produce a copy that needs recovery on start, or one that will not start at all.
Quiesce the writer first for anything that keeps state in memory:
- Use the application's own mechanism where it has one —
pg_start_backup,FLUSH TABLES WITH READ LOCK, afsfreeze. - Or scale the workload to zero, snapshot, and scale back up.
A snapshot of a stopped database is worth more than three snapshots of a running one.
Restore one¶
You do not restore into the existing volume. You create a new claim with the snapshot as its data source, and point your workload at that:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data-restored
spec:
dataSource:
name: postgres-data-2026-08-20
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes: [ "ReadWriteOnce" ]
storageClassName: kubevirt
resources:
requests:
storage: 20Gi # at least the snapshot's RESTORESIZE
Then repoint the workload — edit the Deployment's volume to the new claim, or for a StatefulSet, restore into the claim name its volumeClaimTemplates already generates.
Three things to get right:
| Size | resources.requests.storage must be at least the snapshot's RESTORESIZE. Smaller is rejected; larger provisions a bigger volume, which is legal and sometimes what you want. |
| The original is untouched | Restoring creates a second volume. The one you snapshotted keeps its data and keeps consuming quota until you delete it — which is what lets you compare the two before committing. |
| Quota | A restore is a new volume, so it needs headroom in your storage quota. A restore of a 20Gi snapshot needs 20Gi free, not zero. |
That last one is the one that bites during an incident. Check before you need to:
What snapshots consume¶
Snapshots live on the platform's storage and count against your storage quota, the same as volumes do.
They are not free and they are not archives.
A snapshot's deletion policy is Delete, so removing the VolumeSnapshot object removes the data behind it — and there is no retention mechanism, so a snapshot you took in March is still consuming budget today.
Prune them:
kubectl get volumesnapshot -A --sort-by=.metadata.creationTimestamp
kubectl delete volumesnapshot postgres-data-2026-03-01
A snapshot is not off-site, and does not survive the cluster
The snapshot sits on the same storage system as the volume it came from, inside the same platform. It protects you against a mistake. It does not protect you against losing the storage, the platform, or the cluster.
A snapshot also goes away with the cluster that owns it unless the volume behind it was set to Retain — see Volumes need Retain.
If the data matters beyond that, copy it somewhere else: a dump to object storage from inside a pod is unglamorous and is the thing that actually survives.
Which mechanism you actually need¶
The two are complementary, and neither substitutes for the other:
| Losing | Use | Because |
|---|---|---|
| Data inside a volume | VolumeSnapshot |
Restores the bytes, in place, in minutes. A ClusterBackup captures objects, not bytes. |
| The whole cluster | ClusterBackup + Retain |
Rebuilds the API objects into a new cluster and re-binds the volumes. A snapshot cannot recreate a cluster to mount it. |
| The storage, or the platform | Neither | Copy the data out. Both mechanisms live on the platform you are trying to survive. |
The realistic posture for something that matters: Retain on the volume, a ClusterBackup on a schedule, snapshots before anything risky, and a dump somewhere off-platform.
See Also: Cluster Backup & Restore · Persistent Storage