Cross-cluster migration is the most common reason people use Velero. This episode guides an end-to-end migration: backup on cluster A, restore on cluster B using the same BSL, cloud/storage class differences, file-level backup practices when storage differs, and staging validation before cutover.

Up to episode 10, your backups and restores were still within "the same world" — the same cluster or the same namespace. Episode 11 removes that limit: moving a workload complete with its data from cluster A to cluster B. This is what makes Velero so beloved: cross-cluster migration without copying YAML manually and without losing volume data.
Think of the two clusters as two houses. The backup on cluster A is "a container with the entire contents of the house". Restore on cluster B is "unloading the container in the new house". The challenge isn't the move — it's making sure the container fits: the shelves (storage class), the rooms (namespace), and the electrical connections (service/ingress) in the new house must match.
The key to migration: both clusters use the same BSL — same bucket, same region, same credentials. The backup is created on cluster A, and cluster B (with Velero installed) will see that backup:
velero backup get
velero backup describe my-backup --detailsIf the two clusters are on different clouds (AWS → GCP), make sure each plugin is installed and the BSL points to a bucket both clouds can access (e.g. an S3 bucket GCP reads via interop, or vice versa).
Make a list of differences before restoring so there are no surprises:
gp2 (A) vs gp3 or standard-rwo (B).--namespace-mappings).Before migration, create a final checkpoint — a fresh backup that captures the current state:
velero backup create pre-migration \
--include-namespaces app \
--ttl 720hIf the two clusters have different storage classes, choose file-level backup (kopia) so the volume data is portable:
velero backup create pre-migration \
--include-namespaces app \
--default-volumes-to-fs-backupvelero restore create migration-restore \
--from-backup pre-migration \
--storage-class-mappings gp2:gp3--storage-class-mappings gp2:gp3 maps PVCs from cluster A's storage class to cluster B's storage class (a Velero 1.17+ feature).
kubectl get deploy,pvc -n app
kubectl exec -n app deploy/nginx -- cat /usr/share/nginx/html/index.html
kubectl get svc -n appImportant verification points: pod Running, PVC Bound, and data readable. Note the new Service IP — DNS on cluster A doesn't migrate with you.
Don't cut over directly. First restore to a staging namespace on cluster B, verify the data, then restore to the production namespace:
velero restore create staging-test \
--from-backup pre-migration \
--namespace-mappings app:app-staging \
--storage-class-mappings gp2:gp3This answers the question "will it actually run?" without risk. Once staging is proven, do the final restore to the original namespace.
Warning
Don't back up and restore with cloud snapshots when storage classes differ. An EBS snapshot can't become a GCP PD volume — the restore will fail. For cross-cloud migration, file-level (kopia/restic) is mandatory because the data is stored as plain files in the BSL.
A production migration usually follows this order:
velero backup create final-cutover --include-namespaces app --default-volumes-to-fs-backupBound — not PendingImagePullBackOff/CreateContainerConfigError errors)Tip
Keep the final backup at least until the post-cutover observation period ends. Many teams retain migration backups for 30 days as a "back to cluster A" safety net if problems surface in the first week.
Key takeaways:
--storage-class-mappings gp2:gp3 adapts PVCs on the destination cluster.In episode 12 next, we summarize everything at a strategic level: Disaster Recovery Plan — defining RPO/RTO, off-site backup to another region, writing the restore runbook, and running DR drills by deleting the cluster and restoring to a new one.