What Velero actually backs up
- Cluster resources — Deployments, StatefulSets, Services, ConfigMaps, Secrets, RBAC, CRDs, custom resources. Stored as YAML in an S3 bucket.
- Persistent volume data — via two mechanisms:
- CSI snapshots (fast; storage-driver-native; require a snapshot-capable storage class)
- File-system backup via Kopia or Restic (slower; copies file contents; works on any volume type)
Pick the right PV backup mode per workload — CSI snapshots for production speed, file-system backup as the universal fallback.
Install
You need S3-compatible storage (real AWS S3, MinIO see that tutorial, Backblaze B2, etc.). Create a bucket + credentials:
# credentials-velero (for the install command)
[default]
aws_access_key_id = <key>
aws_secret_access_key = <secret>
# Install Velero into the cluster via the CLI
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.10.0 \
--bucket velero-backups \
--backup-location-config region=us-east-1,s3ForcePathStyle=true,s3Url=https://s3.example.com \
--secret-file ./credentials-velero \
--use-node-agent \
--uploader-type kopia \
--default-volumes-to-fs-backup # opt-in to fs-backup of every PV by default
Or via Helm chart. Velero runs as a Deployment in the velero namespace; the node-agent DaemonSet handles file-system backup of PV contents.
Take your first backup
# Whole-namespace backup
velero backup create my-app-2026-05-22 \
--include-namespaces my-app
# By label selector
velero backup create critical \
--selector "tier=critical" \
--include-cluster-resources
# Status
velero backup describe my-app-2026-05-22
velero backup logs my-app-2026-05-22
Velero scans the included namespaces, dumps every resource as YAML to S3, and triggers PV backups (CSI snapshots and/or file-system copies depending on the volume's storage class).
Schedules
# Recurring schedule (nightly at 03:30 UTC, 30-day retention)
velero schedule create nightly \
--schedule "30 3 * * *" \
--include-namespaces my-app \
--ttl 720h # 30 days
# List
velero schedule get
# Pause / unpause
velero schedule pause nightly
velero schedule unpause nightly
Each scheduled fire creates a Backup resource named nightly-2026XXXXTNNNNNN. After ttl, Velero auto-deletes the backup + cleans up the S3 contents.
Restore
# Restore from a specific backup
velero restore create --from-backup my-app-2026-05-22
# Restore into a different namespace (e.g. for testing)
velero restore create --from-backup my-app-2026-05-22 \
--namespace-mappings my-app:my-app-restored
# Status
velero restore describe my-app-2026-05-22-XXXXXX
velero restore logs <name>
Velero recreates the resources in dependency order; restores PVCs which bind to either restored CSI-snapshot PVs (for snapshot mode) or empty PVs that the node-agent fills from the file-system backup.
Per-PV backup mode
For mixed environments where some PVs use CSI snapshots (RBD, Longhorn, EBS) and others need file-system backup (NFS, local-path), annotate pods to opt-in/out:
# Per-pod, opt this PV out of file-system backup
apiVersion: v1
kind: Pod
metadata:
annotations:
backup.velero.io/backup-volumes-excludes: "tmp-cache,logs"
# Or opt-in (without the global --default-volumes-to-fs-backup flag)
backup.velero.io/backup-volumes: "data,uploads"
Or set the default at install time + opt-out at the pod level. Or use Velero's VolumeSnapshotClass + storage-class mapping for CSI-snapshot routing.
Cluster migration
The "back up cluster A, restore to cluster B" workflow is what makes Velero indispensable for cluster upgrades / region moves / disaster recovery:
# On cluster A
velero backup create migrate-prep --include-namespaces my-app
# Wait for S3 upload
# On cluster B (with Velero installed, same bucket as backup location)
velero backup get # Should see migrate-prep in the list
velero restore create --from-backup migrate-prep
Cluster B's PVCs bind to its own storage; CSI snapshots aren't portable across clusters (different storage backends), so for cross-cluster restore use file-system backup (Kopia or Restic). Velero handles the dance.
Excludes for sensible defaults
Some things you don't want restored:
velero backup create my-app \
--include-namespaces my-app \
--exclude-resources events,events.events.k8s.io,replicasets.apps \
--exclude-namespaces kube-system,kube-public
Or globally via the Velero deployment's args. Events + ReplicaSets are autogenerated and noisy; excluding them keeps backup size down.
Hooks
For workloads that need a quiesce-before-backup (databases mid-transaction), Velero pre/post hooks run a command inside the pod at backup time:
apiVersion: v1
kind: Pod
metadata:
annotations:
pre.hook.backup.velero.io/command: '["/bin/sh", "-c", "pg_dumpall > /backup/dump.sql"]'
pre.hook.backup.velero.io/timeout: "5m"
post.hook.backup.velero.io/command: '["/bin/sh", "-c", "rm /backup/dump.sql"]'
Or use pre/post via the Backup spec for selecting pods by label. Useful pattern: a sidecar that runs pg_dump on pre-hook, and Velero file-system-backs-up the resulting dump file.
Backup encryption
Velero doesn't encrypt at the application layer; rely on:
- S3 server-side encryption (SSE-S3, SSE-KMS) on the bucket.
- For file-system backups via Kopia, configure a repository password (set at install time with
--uploader-type kopia).
For belt-and-suspenders, layer LUKS or age-encryption on the S3 path, accepting that you operate the keys.
Backup of the Velero backup metadata itself
The backups live in S3 plus Velero's resource state in the cluster. If the cluster is permanently lost, Velero can rebuild state by reading the bucket on a fresh install pointed at the same location. This is the "S3 + bucket-region-replication = real DR" guarantee.
What Velero isn't
- Not a database backup tool — it copies PV contents at the file level; for transactional DBs, prefer pg_dump / WAL-G / mongodump via hooks.
- Not an etcd backup — control-plane etcd has its own backup story (snapshotted to disk by your distro: k3s does it automatically, k0s and kubeadm have their own commands).
- Not a continuous-replication system — backups are point-in-time. For "near-zero RPO," use storage-layer replication (RBD mirroring, etc.) in addition.
For "I run Kubernetes and need restore-from-disaster + occasional namespace-level rollback," Velero is the canonical tool in 2026.