Skip to main content

Command Palette

Search for a command to run...

How I Migrated an AKS Cluster Across Regions Using Velero

Updated
5 min read
How I Migrated an AKS Cluster Across Regions Using Velero
S

DevOps & Cloud Engineer — building scalable, automated, and intelligent systems. Developer of sorts | Automator | Innovator

Migrating an entire Kubernetes cluster is one of those tasks that sounds straightforward until you actually begin. When I recently needed to migrate an Azure Kubernetes Service (AKS) cluster from the Central India region to the East US region, the process involved more considerations than simply exporting YAML files and applying them elsewhere.

The requirement was clear. Migrate every workload, every Persistent Volume Claim, every Secret, every ConfigMap, every Custom Resource Definition, and all namespace-level objects. Everything had to move with accuracy.

After evaluating different approaches, Velero turned out to be the most reliable and practical tool for a complete AKS region migration. Velero supports backup and restoration of cluster state as well as persistent storage, and its Azure plugin works smoothly with both Azure Blob Storage and Azure Disk snapshots.

This guide describes the exact steps I followed, the challenges I encountered, and the final workflow that resulted in a successful migration.


1. Why Velero Is Ideal for AKS Region Migration

Velero has several advantages for full-cluster migration:

Backup and restore of namespaced and cluster-level resources

This includes Deployments, StatefulSets, Services, Secrets, ConfigMaps, RBAC objects, and Custom Resources.

Support for disk snapshots

This is essential when migrating workloads that depend on Persistent Volume Claims.

Version compatibility with AKS

Velero supports most Kubernetes API versions used in AKS.

Easy restoration into a completely new cluster

This is useful when the source and destination are in different regions.


2. Preparing Azure for Velero

Velero requires an Azure Blob Storage account and a resource group for snapshot management.

Step 1: Create a Storage Account

Choose a region for the storage account. You can use either the source or destination region because Velero backups are region independent.

az storage account create \
    --name veleroaccount123 \
    --resource-group velero-rg \
    --location eastus \
    --sku Standard_GRS

Step 2: Create a Blob Container

az storage container create \
    --name velero-backups \
    --account-name veleroaccount123

Step 3: Create a Service Principal or Use a Managed Identity

In my case, I used a managed identity created for Velero with the required permissions:

  • Contributor role on the Resource Group

  • Storage Blob Data Contributor on the Storage Account

This avoids the need for storing client secrets.


3. Installing Velero on the Source AKS Cluster

Once the storage and identity were ready, I installed Velero on the source cluster.

Step 1: Install Velero CLI

brew install velero

(Or download from the official GitHub releases page if not using macOS.)

Step 2: Install Velero on the Cluster

velero install \
    --provider azure \
    --plugins velero/velero-plugin-for-microsoft-azure:v1.10.0 \
    --bucket velero-backups \
    --secret-file ./credentials-velero \
    --backup-location-config resourceGroup=velero-rg,storageAccount=veleroaccount123 \
    --use-volume-snapshots=true \
    --snapshot-location-config resourceGroup=velero-rg

Now Velero runs inside the cluster with all necessary permissions.


4. Creating Backups

I wanted a complete backup of every namespace, every CRD, and all persistent volumes.

Step 1: Confirm Velero Is Healthy

velero version
kubectl get pods -n velero

Step 2: Run a Full Cluster Backup

velero backup create aks-full-backup \
    --include-namespaces '*' \
    --wait

The backup took several minutes because the cluster had StatefulSets and large PVCs.

Step 3: Verify the Backup

velero backup describe aks-full-backup
velero backup logs aks-full-backup

At this stage I had a complete backup stored in Azure Blob Storage and snapshots created for all PVCs.


5. Creating the Destination AKS Cluster

I created a new cluster in East US with the same Kubernetes version as the source cluster. Matching the Kubernetes version is important because restoring cluster-level objects may otherwise cause compatibility issues.

az aks create \
  --resource-group uspreprod-rg \
  --name uspreprod-aks \
  --location eastus \
  --node-count 3 \
  --kubernetes-version 1.29

After the cluster was ready, I connected to it:

az aks get-credentials \
    --resource-group uspreprod-rg \
    --name uspreprod-aks \
    --overwrite-existing

6. Installing Velero on the Destination Cluster

The installation process is similar to the source cluster:

velero install \
    --provider azure \
    --plugins velero/velero-plugin-for-microsoft-azure:v1.10.0 \
    --bucket velero-backups \
    --secret-file ./credentials-velero \
    --backup-location-config resourceGroup=velero-rg,storageAccount=veleroaccount123 \
    --use-volume-snapshots=true \
    --snapshot-location-config resourceGroup=velero-rg

Velero now has access to the same storage account and snapshots that were created from the source cluster.


7. Restoring the Full Backup

Step 1: Trigger the Restore

velero restore create aks-full-restore \
    --from-backup aks-full-backup \
    --wait

Velero recreated:

  • Namespaces

  • Deployments

  • StatefulSets

  • Services

  • Ingress objects

  • Secrets and ConfigMaps

  • CRDs and CRs

  • Everything linked to snapshots

Step 2: Verify Restore Objects

velero restore describe aks-full-restore
velero restore logs aks-full-restore

Step 3: Validate Cluster State

I validated that workloads came up correctly:

kubectl get pods --all-namespaces
kubectl get pvc --all-namespaces
kubectl get ingress --all-namespaces

Any workload that depended on Persistent Volumes was able to recover because the Azure snapshots were restored successfully.


8. Issues Encountered and Fixes

Missing CRDs Before Restore

Some CRDs must exist before restoring their corresponding objects.
Solution: Install CRDs manually or let Velero restore cluster-level CRDs first.

Snapshot Restore Delay

Azure snapshots sometimes take time to rehydrate into new disks.
Solution: Wait a few minutes and reapply StatefulSets if needed.

Identity Permission Issues

The managed identity must have Contributor access on both resource groups.
Without this, PVC restore will fail.

Ingress Controller Differences

The new cluster may create a different external IP for the ingress controller.
Update DNS records accordingly.


9. Final Thoughts

Migrating an AKS cluster across regions can feel overwhelming due to the number of moving parts involved. Velero simplifies the process significantly by offering a predictable and reliable way to back up and restore clusters at scale.

In my case, Velero successfully migrated every namespace, every workload, and every Persistent Volume from the Central India AKS cluster to a completely new cluster in East US. The process was clean, repeatable, and did not require manual recreation of YAML files.

If you are planning a similar migration, I strongly recommend preparing the destination cluster with the same Kubernetes version, ensuring proper identity permissions, and validating your snapshot restores.

Velero is a powerful tool, and with the right configuration, it can handle migrations across regions with very little manual effort.

More from this blog

C

CodeOps Studies

39 posts

Simple write-ups on day to day code or devops experiments, tests etc.