Skip to content
You are reading dev: the documentation of main. The last release, 0.1.0, predates this site.

Restore a backup

This guide restores one namespace from a backup taken by the velero module, on AWS or GCP. It is an operator’s task: a Restore can rewrite any namespace.

What you need: the velero CLI 1.18, a kubeconfig with cluster-admin rights, and the module’s server running (kubectl -n velero get deploy velero shows it available).

Velero never overwrites an object that exists: it skips it. The namespace must be empty first, and stay empty until the restore.

Backups are named after their Schedule, velero-<frequency>-<retention>, with a timestamp:

Terminal window
velero schedule get
velero backup get --selector velero.io/schedule-name=velero-daily-7d

Check the one you pick is Completed and holds your namespace and its volumes:

Terminal window
velero backup describe <backup> --details

On GCP, what describe reads from the bucket, and velero backup logs, fail: they go through a URL signed as a Google service account, which the module has none of (velero). Read the logs from the bucket:

Terminal window
gcloud storage cat gs://<cluster>-velero-<project number>/backups/<backup>/<backup>-logs.gz | gunzip

Otherwise Argo CD recreates an empty claim, and Velero skips the one it should restore:

Terminal window
argocd app set <app> --sync-policy none
Terminal window
kubectl delete namespace <namespace> --wait

--include-namespaces keeps the restore to your namespace, since a policy’s backup holds every labelled object of the cluster:

Terminal window
velero restore create <restore> --from-backup <backup> --include-namespaces <namespace> --wait

The restore is Completed, every claim Bound, the pods running; then check the data from inside your application. On PartiallyFailed, read velero restore logs <restore>, or on GCP gs://<cluster>-velero-<project number>/restores/<restore>/restore-<restore>-logs.gz.

Terminal window
velero restore describe <restore> --details
kubectl -n <namespace> get pvc,pods

Argo CD adopts the restored objects:

Terminal window
argocd app set <app> --sync-policy automated

Delete it while the module is still on: its finalizer is released only by the Velero server, and one left behind holds the velero namespace in Terminating once the module is off.

Terminal window
velero restore delete <restore> --confirm

If the module is already off, remove the finalizer by hand:

Terminal window
kubectl -n velero patch restore <restore> --type merge -p '{"metadata":{"finalizers":null}}'

Rebuild the cluster with the same name, in the same account and region on AWS, in the same project on GCP, and turn crossplane and velero on again: Crossplane adopts the bucket left behind, and Velero reads every backup back from it. Then restore from step 1. A cluster rebuilt under another name cannot reach the old bucket.

Measured on floci k3s, 2026-10-02: a namespace restored from a node-agent backup, Completed in 10 s, the file read back unchanged. Measured on the sandbox’s GKE Autopilot, 2026-10-16: a Persistent Disk snapshot backed up and restored with its data. The full rebuild and an EBS snapshot restore on AWS are not measured yet.