This episode assembles the production restore workflow: full restore to a new cluster, production→staging namespace mapping for testing and DR, and troubleshooting failed restores — pending PVCs, different storage classes, and the `--storage-class-mappings` solution available since Velero 1.17.

In episode 5 we already restored into a different namespace and did selective restore. Episode 10 raises the bar: assembling a restore workflow that's actually used in production — from full restore to a new cluster, mapping namespaces for simulation, to handling the most common restore failures. This is the material you reopen during an incident.
Remember the archive analogy: you already know how to reprint a document (episode 5). Now you learn to reprint an entire archive room in a different building — complete with rules about which shelves move, and what to do when a shelf doesn't fit in the new building.
This is the flow used to move environments or simulate disaster:
velero backup get on the new cluster — old backups are visible.velero backup get
velero backup describe my-backup --detailsvelero restore create --from-backup my-backup
velero restore getkubectl get deploy,pvc -A
kubectl exec -n app deploy/nginx -- cat /usr/share/nginx/html/index.htmlVelero restores resources in a specific order: namespaces first, then volumes/CSI, then workloads, then Services and Ingresses. This isn't accidental — a Deployment needs its PVC to exist before the pod is created, and a Service needs a selector that already exists. Velero 1.18 also added restore ordering fixes for Role/RoleBinding/ClusterRole so RBAC-based applications restore correctly.
The most commonly used DR/testing workflow: bringing production data into a staging environment without touching production.
velero restore create dr-test \
--from-backup my-backup \
--namespace-mappings app:app-stagingAll resources from the app namespace are recreated in app-staging — including new PVCs with restored data. Velero automatically creates the target namespace if it doesn't exist.
velero restore create multi-ns \
--from-backup my-backup \
--namespace-mappings prod-web:staging-web,prod-api:staging-apiNote
Namespace mapping changes only the namespace, not the resource names inside it. A Deployment named nginx stays named nginx in the new namespace. Conflicts only happen if the resource name already exists in the target namespace — in that case, restore marks the item as "already exists" and skips it.
The restore finishes but a PVC hangs in Pending status:
kubectl get pvc -n app-staging
kubectl describe pvc app-data -n app-stagingThe most common cause: the storage class doesn't exist on the target cluster (e.g. a backup from EKS gp2 restored to a cluster that only has gp3), or the node has no access to the volume. Check the storage classes:
kubectl get storageclassSince Velero 1.17, you can map the backup's storage class to a storage class on the target cluster:
velero restore create fix-sc \
--from-backup my-backup \
--storage-class-mappings gp2:gp3Backups referencing the gp2 storage class are now restored with gp3. This feature addresses a very common cross-cloud and cross-cluster problem — we use it again in episode 11.
The target namespace already has resources with the same name. By default Velero skips existing resources. To overwrite them:
velero restore create force-restore \
--from-backup my-backup \
--namespace-mappings app:app-staging \
--existing-resource-policy update--existing-resource-policy update forces Velero to update resources that already exist (be careful — this overwrites configuration someone else may have modified).
Velero 1.18 added RBAC restore ordering rules, but one thing still surprises beginners: a restored Secret doesn't "revive" an already-existing Deployment because Deployments only read Secrets when a pod is created. The cleanest solution: restore in a single operation, then delete the pod so the Deployment creates a new pod that reads the latest Secret — or use a reload mechanism (e.g. a restart annotation).
Tip
Debugging restore pattern: velero restore describe <name> --details gives you the list of succeeded, skipped, and failed resources. Go straight to velero restore logs <name> for the error messages — usually the error is clear, like storageclass.storage.k8s.io "gp2" not found.
Key takeaways:
--namespace-mappings prod:staging maps a restore for testing/DR without touching prod.Pending PVC is almost always about storage class — check with kubectl get storageclass.--storage-class-mappings gp2:gp3 (Velero 1.17+) resolves storage class differences across clusters.In episode 11 next, we use all these foundations for Velero's most compelling purpose: cross-cluster migration — backup on cluster A, restore on cluster B with a shared BSL, managing cloud/storage class differences, and validating in staging before switch over.