Amazon EKS — Volume Snapshots
EBS snapshots provide point-in-time backups of persistent volumes. The CSI snapshot controller and EBS CSI Driver work together to create, manage, and restore snapshots through native Kubernetes APIs.
Prerequisites
Install the Snapshot Controller
The CSI snapshot controller is not installed by default:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml
Verify:
kubectl get pods -n kube-system -l app=snapshot-controller
kubectl get crd | grep snapshot
VolumeSnapshotClass
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: ebs-snapshot-class
driver: ebs.csi.aws.com
deletionPolicy: Retain # Keep EBS snapshot even if K8s VolumeSnapshot is deleted
| Policy | Behavior |
|---|---|
Delete |
EBS snapshot is deleted when VolumeSnapshot is removed |
Retain |
EBS snapshot persists — must be manually cleaned up |
Creating a Snapshot
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: postgres-snapshot-2025-02-09
namespace: production
spec:
volumeSnapshotClassName: ebs-snapshot-class
source:
persistentVolumeClaimName: data-postgres-0
kubectl apply -f snapshot.yaml
kubectl get volumesnapshot -n production
kubectl describe volumesnapshot postgres-snapshot-2025-02-09 -n production
Restoring from a Snapshot
Create a new PVC from a snapshot:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-postgres-restored
namespace: production
spec:
accessModes:
- ReadWriteOnce
storageClassName: gp3
resources:
requests:
storage: 50Gi
dataSource:
name: postgres-snapshot-2025-02-09
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
Cross-AZ Restore
EBS snapshots are regional — you can restore a snapshot into any AZ in the same region:
- Create a snapshot from the source PVC
- Delete or stop the workload using the old PVC
- Create a new PVC from the snapshot (use
WaitForFirstConsumerto bind to the correct AZ)
Backup Strategies
Scheduled Snapshots with CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: db-snapshot
namespace: production
spec:
schedule: "0 3 * * *" # Daily at 3 AM
jobTemplate:
spec:
template:
spec:
serviceAccountName: snapshot-sa
containers:
- name: snapshot
image: bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
DATE=$(date +%Y-%m-%d)
cat <<SNAP | kubectl apply -f -
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: postgres-snap-$DATE
namespace: production
spec:
volumeSnapshotClassName: ebs-snapshot-class
source:
persistentVolumeClaimName: data-postgres-0
SNAP
restartPolicy: OnFailure
Velero for Full Cluster Backup
Velero backs up Kubernetes resources AND persistent volumes:
# Install Velero with AWS plugin
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.9.0 \
--bucket my-velero-backup-bucket \
--backup-location-config region=us-east-1 \
--snapshot-location-config region=us-east-1 \
--use-node-agent
# Create a backup
velero backup create daily-backup --include-namespaces production
# Schedule daily backups
velero schedule create daily --schedule="0 3 * * *" --include-namespaces production
# Restore
velero restore create --from-backup daily-backup
Best Practices
- Use
Retaindeletion policy for production snapshot classes - Automate snapshots — CronJobs or Velero schedules
- Test restores regularly — a backup that hasn’t been tested is not a backup
- Set retention policies — clean up old snapshots to control costs
- Use Velero for disaster recovery — backs up both K8s resources and volumes together
- Tag snapshots — include application, date, and environment for easy identification