Velero and etcd snapshots protect different layers of a Kubernetes cluster. See what each backs up, what each misses, and why most DR needs both.
Picture a team running self-managed Kubernetes on EC2 with a disciplined etcd routine: automated snapshots every six hours, encrypted, shipped off-cluster, restore-tested quarterly. Then a bad Helm upgrade deletes every PVC in the production namespace. The control plane is healthy and the snapshots are fine. None of it helps, because etcd only knows that a PersistentVolumeClaim object existed, not what was on the volume.
That is why "Velero vs etcd snapshot" is a misleading comparison. They are not two answers to the same question. They protect different layers, and the failures that take out one rarely take out the other.
An etcd snapshot protects the cluster's control-plane state: every object the API server stores. Velero protects applications: it exports Kubernetes resources through the API and can also back up the data on persistent volumes. One rebuilds the cluster's brain, the other rebuilds your workloads and their data.
Notice what is missing from each side. The snapshot has no volume data, and Velero has no path to a control plane that is completely down.
An etcd snapshot is a point-in-time copy of the entire etcd keyspace: Deployments, Services, Secrets, ConfigMaps, CRDs, RBAC and the PV and PVC objects. It does not contain the contents of any volume. On a kubeadm cluster you take one with etcdctl from a control-plane node.
ETCDCTL_API=3 etcdctl \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ snapshot save /backup/etcd-$(date +%F-%H%M).db ## verify the file before you trust itetcdutl snapshot status /backup/etcd-2026-10-12-0200.dbRestoring uses etcdutl in etcd 3.5 and later, and writes a fresh data directory that you then point the etcd static pod at:
etcdutl snapshot restore /backup/etcd-2026-10-12-0200.db \ --data-dir /var/lib/etcd-restoreDistributions such as k3s and RKE2 ship their own snapshot commands and scheduling, so use those instead of calling etcdctl yourself.
š Remember: Restoring a snapshot rewinds the whole cluster to that moment. Anything created after the snapshot, including deployments and secrets, is gone, and the restore is tied to the cluster's etcd version and topology.
Velero calls the Kubernetes API, serializes the resources you select into an object-storage bucket (S3, GCS or Azure Blob), and can also capture volume data. It can restore into the same cluster or a different compatible one, and it works at namespace or resource granularity.
## nightly backup of one namespace, kept for 30 daysvelero schedule create payments-daily \ --schedule "0 2 * * *" \ --include-namespaces payments \ --snapshot-move-data \ --ttl 720h ## inspect a finished backupvelero backup describe payments-daily-20261012020000 --detailsThere are three ways Velero handles volume data, and the choice decides your recovery options:
--snapshot-move-data): the snapshot contents are copied into the backup bucket, so a replicated bucket becomes your cross-region copy.Velero backups are crash-consistent by default. The next section shows how to make them application-consistent.
š” Tip: Velero backups contain Secrets in plain Kubernetes form. Encrypt the bucket with a KMS key, restrict who can read it, and enable object lock or versioning so ransomware cannot delete your backups.
Use backup hooks to pause writes before the snapshot and resume them after. Without hooks, a snapshot taken mid-write can capture a half-written database page, and the restored database may need crash recovery or fail integrity checks.
apiVersion: velero.io/v1kind: Schedulemetadata: name: payments-daily namespace: velerospec: schedule: "0 2 * * *" template: includedNamespaces: ["payments"] snapshotMoveData: true ttl: 720h hooks: resources: - name: freeze-db labelSelector: matchLabels: app: postgres pre: - exec: container: fsfreeze command: ["/sbin/fsfreeze","--freeze","/data"] post: - exec: container: fsfreeze command: ["/sbin/fsfreeze","--unfreeze","/data"]This example assumes a small privileged sidecar named fsfreeze that shares the data volume. Keep the freeze window short, because writes block while the filesystem is frozen. For larger databases, a native logical or physical backup (pg_dump, pg_basebackup, mysqldump) alongside Velero is often the safer second copy.
No. On managed Kubernetes the provider runs etcd inside the control plane and does not expose it, so there is nothing for you to snapshot. Your responsibility is the layer above: resources and volume data, which is exactly what Velero covers.
This is why Velero dominates DR conversations as managed clusters become the default. The provider's SLA covers control-plane availability, and your backups cover everything you deploy onto it.
On self-managed clusters (kubeadm, k3s, RKE2) you own etcd, and losing it without a snapshot is unrecoverable. Running pods may keep running for a while on kubelet state, but you cannot schedule, scale or change anything until the control plane is back.
Use the failure you are planning for to choose the tool. Most application-layer disasters need Velero, and most control-plane disasters need an etcd snapshot.
| Failure | etcd snapshot | Velero |
|---|---|---|
| Corrupted etcd or lost member | Yes | No |
| Deleted namespace | Partly, whole cluster | Yes |
| PVC data wiped | No | Yes |
| Migrate to another cluster | No | Yes |
| API server will not start | Yes | No |
The "partly" in the deleted-namespace row matters. Restoring etcd would recover the namespace's objects, but it rewinds every other namespace too, so it is a blunt tool for a precise problem.
A backup is only real once you have restored from it. Run restore drills into a scratch namespace or cluster on a schedule, and record how long each one takes.
## restore into a different namespace to avoid touching productionvelero restore create drill-$(date +%F) \ --from-backup payments-daily-20261012020000 \ --namespace-mappings payments:payments-drill ## watch progress and check for warningsvelero restore describe drill-2026-10-12 --detailskubectl get pods,pvc -n payments-drillFor etcd, restore a snapshot into a throwaway control plane and confirm kubectl get nodes and kubectl get ns behave as expected. Then run an application-level check: log in, read a known record, run a database integrity query.
A drill passes only if you can answer three questions: did the data come back, how long did it take, and does that time fit your RTO? Write the numbers down after every drill so you can see the trend.
What each layer covers:
| Factor | etcd snapshot | Velero |
|---|---|---|
| Protects | Control-plane state | Resources and PV data |
| Restore target | Same cluster | Same or different |
| Managed K8s | Not available | Primary mechanism |
Operational fit:
| Factor | etcd snapshot | Velero |
|---|---|---|
| Granularity | Whole cluster | Namespace or resource |
| Needs API server | No | Yes |
| Typical cadence | Every few hours | Hourly to daily |
Two alternatives are worth knowing. GitOps tools such as Argo CD or Flux rebuild resource definitions from Git, but they do not back up volume data or objects created outside Git. Storage-level replication protects data but not your Kubernetes objects. Treat both as complements to Velero, not replacements.
On self-managed Kubernetes, run both and treat them as covering different recovery objectives.
On managed Kubernetes there is no etcd decision to make, so put your effort into Velero's volume strategy and restore drills. A backup you have never restored from is, for practical purposes, not a backup.
Noteš References and Further Reading
- Velero Documentation - Official backup, restore and data movement reference
- Operating etcd Clusters for Kubernetes - Official snapshot and restore steps
- etcd Disaster Recovery - Upstream recovery guide
- Kubernetes Volume Snapshots - How CSI snapshots work
No. etcd stores the PVC and PV objects, which are only references. If a bad upgrade deletes PVCs and the reclaim policy is Delete, the underlying volumes can be destroyed, and no etcd snapshot can bring back the bytes. You need volume snapshots or file-level backup, which Velero provides.
No. The provider runs etcd as part of the managed control plane and does not expose it, so you cannot run etcdctl against it. On managed Kubernetes your own backup layer is API-level, which is what Velero does, and control-plane recovery is the provider's responsibility.
No. Velero works by calling the Kubernetes API, so with the API server down it has nothing to call. On a self-managed cluster you first restore the control plane from an etcd snapshot, or rebuild a new cluster, and then use Velero to restore applications into it.
Usually not. A CSI snapshot normally lives in the same region and account as the volume, so a regional outage or account compromise takes both. Use Velero data movement (--snapshot-move-data) or file-system backup so volume data lands in an object-storage bucket replicated to another region.
CSI and file-level backups are crash-consistent by default. Add Velero pre and post backup hooks to quiesce the database, for example flushing and freezing writes, or back up with the database's native tool as well. Then restore into a scratch namespace and run integrity checks to prove it.
Discussion0