Velero no AKS para Backup e Restore Cross-Region

Neste artigo você vai instalar o Velero nos dois clusters AKS do lab — Brazil South e East US — configurado com backend no Azure Blob Storage RA-GZRS criado no Art. 08. O Velero usa o plugin oficial para Azure e o modo CSI com Node Agent para capturar snapshots de volumes persistentes junto com os manifestos Kubernetes. O resultado é um backup completo de namespace que pode ser restaurado no cluster secundário com um único comando — exatamente o que é necessário durante um evento de DR quando a região primária está indisponível. O artigo cobre instalação via Helm, backup manual, restore cross-region e schedule automático diário com retenção de 30 dias. O velero backup restore aks é a solução nativa para DR de workloads Kubernetes com backend na geo-replicação do Azure Blob.
- 📖 Art. 01: Planejamento de DR Azure e Landing Zone
- 📖 Art. 02: Hub-Spoke Landing Zone com Terraform
- 📖 Art. 03: Azure Firewall e NSGs na Landing Zone
- 📖 Art. 04: Azure Bastion na Landing Zone sem IP Público
- 📖 Art. 05: Azure Front Door e Traffic Manager para Failover
- 📖 Art. 06: DNS Privado Multi-Região no Azure
- 📖 Art. 07: Azure Site Recovery para VMs Multi-Região
- 📖 Art. 08: Azure Storage com Geo-Replicação para DR
- 📖 Art. 09: AKS Multi-Região com Failover no Azure
- ⚙️ Art. 10 (este): Velero no AKS para Backup e Restore Cross-Region
- 🔒 Art. 11: Runbooks de Failover no Azure Automation
- 🔒 Art. 12: Simular um DR no Azure sem Impacto em Produção
- 🔒 Art. 13: Monitoramento do DR no Azure com Azure Monitor
Sumário
- Velero e sua função no DR do AKS
- Arquitetura do lab
- Pré-requisitos
- Passo 1 — Criar Service Principal para o Velero
- Passo 2 — Configurar os Helm values por cluster
- Passo 3 — Instalar o Velero via Helm
- Passo 4 — Verificar a instalação
- Passo 5 — Backup manual de namespace
- Passo 6 — Restore cross-region no cluster East US
- Passo 7 — Schedule de backup automático
- Troubleshooting
- Limpeza dos recursos
- Próximos passos
Velero e sua função no DR do AKS
O velero backup restore aks é a solução open-source para backup, restore e migração de recursos Kubernetes e volumes persistentes. No contexto de DR, ele preenche uma lacuna importante: enquanto o Azure Container Registry garante que as imagens estejam disponíveis nas duas regiões (Art. 09) e o Front Door redireciona o tráfego (Art. 05), o Velero garante que o estado interno do cluster — ConfigMaps, Secrets, PVCs, Deployments personalizados — possa ser recriado no cluster secundário com fidelidade.
O Velero opera em dois modos para volumes persistentes. No modo File System Backup (antigo restic), ele faz backup dos arquivos dentro dos volumes diretamente para o blob storage. No modo CSI Snapshots (habilitado com features: EnableCSI), ele usa a API de VolumeSnapshot do Kubernetes para acionar snapshots nativos do provider de disco — no caso do AKS, o Azure Disk CSI Driver cria snapshots de discos gerenciados via a API do Azure. O modo CSI é mais rápido para volumes grandes e produz snapshots consistentes, mas requer o Node Agent (DaemonSet) para coordenar a captura.
O backend do velero backup restore aks neste lab é o container backups da Storage Account stblogcastilhobrazil criada no Art. 08 com replicação RA-GZRS. Isso significa que os backups são automaticamente replicados para East US — quando o cluster secundário precisa fazer o restore, ele lê do endpoint da réplica sem depender da disponibilidade de Brazil South.
Arquitetura do lab
| Componente | Cluster BRS | Cluster EUS |
|---|---|---|
| Velero versão (Helm chart) | 7.1.0 | 7.1.0 |
| Plugin Azure | velero-plugin-for-microsoft-azure:v1.10.0 | velero-plugin-for-microsoft-azure:v1.10.0 |
| Backup Storage Location | stblogcastilhobrazil / container backups | stblogcastilhobrazil / container backups |
| Volume Snapshot Location RG | rg-blog-castilho-workload-brazilsouth | rg-blog-castilho-workload-eastus |
| Node Agent (DaemonSet) | Habilitado | Habilitado |
| CSI Features | EnableCSI | EnableCSI |
Ambos os clusters apontam para o mesmo Backup Storage Location — o container backups em stblogcastilhobrazil. Isso é intencional: os backups feitos no cluster primário ficam visíveis para o cluster secundário sem qualquer sincronização adicional, pois a Storage Account RA-GZRS replica os dados automaticamente. O Volume Snapshot Location, por outro lado, é diferente por cluster porque os snapshots de disco são recursos regionais — um snapshot criado em Brazil South não pode ser usado diretamente em East US (para restore cross-region com volumes, o Velero usa o File System Backup como fallback ou você precisa copiar o snapshot manualmente).
Pré-requisitos
- Art. 08 deployado — Storage Account
stblogcastilhobrazilcom containerbackupsexistente - Art. 09 deployado — clusters
aks-blog-castilho-brazilsoutheaks-blog-castilho-eastusrodando - Kubeconfigs dos dois clusters obtidos via
az aks get-credentials - Helm ≥ 3.0 instalado localmente
- CLI do Velero instalado localmente (para os comandos de backup/restore)
- Azure CLI autenticado com permissões para criar Service Principals
# Instalar o CLI do Velero (Linux)
VELERO_VERSION=v1.13.0
curl -sL "https://github.com/vmware-tanzu/velero/releases/download/${VELERO_VERSION}/velero-${VELERO_VERSION}-linux-amd64.tar.gz" \
| tar -xz --strip-components=1 -C /usr/local/bin velero-${VELERO_VERSION}-linux-amd64/velero
velero version --client-only
.env local (não versionado) ou o Azure Key Vault para armazenar segredos.
Passo 1 — Criar Service Principal para o Velero
O Velero precisa de um Service Principal com permissões para ler e gravar no Storage Account e para criar snapshots de disco. O papel Contributor no Resource Group de workload cobre ambas as necessidades neste lab:
>SUBSCRIPTION_ID=""
RG_BRS="rg-blog-castilho-workload-brazilsouth"
RG_EUS="rg-blog-castilho-workload-eastus"
# Criar o Service Principal
SP=$(az ad sp create-for-rbac \
--name "sp-velero-blog-castilho" \
--role Contributor \
--scopes \
"/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RG_BRS" \
"/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RG_EUS" \
--output json)
echo "CLIENT_ID: $(echo $SP | jq -r .appId)"
echo "CLIENT_SECRET: $(echo $SP | jq -r .password)"
echo "TENANT_ID: $(echo $SP | jq -r .tenant)"
# Guardar em .env (não versionar!)
cat > .env <
Passo 2 — Configurar os Helm values por cluster
Os values do Helm configuram o plugin Azure, o Backup Storage Location apontando para o container backups da Storage Account RA-GZRS e o Volume Snapshot Location com o Resource Group de cada região. A diferença entre os dois arquivos é apenas o resourceGroup do volumeSnapshotLocation e das credenciais do SP:
# scripts/art-10-velero-aks/velero-values-brazilsouth.yaml
initContainers:
- name: velero-plugin-for-azure
image: velero/velero-plugin-for-microsoft-azure:v1.10.0
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /target
name: plugins
configuration:
backupStorageLocation:
- name: default
provider: azure
bucket: backups
config:
storageAccount: stblogcastilhobrazil
resourceGroup: rg-blog-castilho-workload-brazilsouth
storageAccountKeyEnvVar: AZURE_STORAGE_ACCOUNT_ACCESS_KEY
volumeSnapshotLocation:
- name: default
provider: azure
config:
resourceGroup: rg-blog-castilho-workload-brazilsouth
credentials:
useSecret: true
secretContents:
cloud: |
AZURE_SUBSCRIPTION_ID=${AZURE_SUBSCRIPTION_ID}
AZURE_TENANT_ID=${AZURE_TENANT_ID}
AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
AZURE_RESOURCE_GROUP=rg-blog-castilho-workload-brazilsouth
AZURE_CLOUD_NAME=AzurePublicCloud
features: EnableCSI
deployNodeAgent: true
O arquivo para East US é idêntico, com duas diferenças: resourceGroup do volumeSnapshotLocation muda para rg-blog-castilho-workload-eastus, e AZURE_RESOURCE_GROUP nas credenciais também aponta para East US. O backupStorageLocation continua apontando para a mesma Storage Account de Brazil South, pois a RA-GZRS disponibiliza os dados na réplica de East US automaticamente.
O campo storageAccountKeyEnvVar: AZURE_STORAGE_ACCOUNT_ACCESS_KEY instrui o plugin a usar a chave de acesso da Storage Account em vez de RBAC. Para obter a chave e incluí-la nas credenciais do Helm, adicione ao seu .env:
>SA_KEY=$(az storage account keys list \
--account-name stblogcastilhobrazil \
--resource-group rg-blog-castilho-workload-brazilsouth \
--query "[0].value" -o tsv)
export AZURE_STORAGE_ACCOUNT_ACCESS_KEY="$SA_KEY"
Passo 3 — Instalar o Velero via Helm
O script 01-install-velero.sh instala o Velero nos dois clusters em sequência, aplicando o values file específico de cada região. O Helm chart versão 7.1.0 é o que corresponde ao Velero 1.13.x:
# Carregar credenciais
source .env
# Instalar nos dois clusters
bash scripts/art-10-velero-aks/01-install-velero.sh
O script executa os seguintes passos para cada cluster:
>helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm repo update
helm upgrade --install velero vmware-tanzu/velero \
--namespace velero \
--create-namespace \
--version 7.1.0 \
--values velero-values-brazilsouth.yaml \
--kube-context aks-blog-castilho-brazilsouth
kubectl wait --for=condition=ready pod \
-l app.kubernetes.io/name=velero \
-n velero \
--timeout=120s \
--context aks-blog-castilho-brazilsouth
Passo 4 — Verificar a instalação
Após a instalação, verifique se o velero backup restore aks está conectado ao Storage Account e se os locations estão disponíveis:
# Verificar status no cluster primário
velero backup-location get --kubecontext aks-blog-castilho-brazilsouth
# NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT
# default azure backups Available ... ReadWrite true
velero snapshot-location get --kubecontext aks-blog-castilho-brazilsouth
# NAME PROVIDER
# default azure
# Verificar os pods do Velero e Node Agent
kubectl get pods -n velero --context aks-blog-castilho-brazilsouth
# NAME READY STATUS RESTARTS
# velero-xxx-yyy 1/1 Running 0
# node-agent-aaa 1/1 Running 0 <- DaemonSet, 1 por node
# node-agent-bbb 1/1 Running 0
# Repetir para East US
velero backup-location get --kubecontext aks-blog-castilho-eastus
O status Available no Backup Storage Location confirma que o Velero conseguiu autenticar no Storage Account e que o container backups está acessível. Se o status for Unavailable, verifique as credenciais do Service Principal e se a Storage Account permite acesso da rede do cluster (o public_network_access_enabled = false do Art. 08 requer que o acesso venha via Private Endpoint ou que você configure a exceção de rede).
Passo 5 — Backup manual de namespace
Com o Velero instalado, faça um backup do namespace app-producao onde a aplicação demo foi deployada no Art. 09:
># Backup do namespace app-producao no cluster primário
bash scripts/art-10-velero-aks/02-create-backup.sh \
aks-blog-castilho-brazilsouth \
app-producao
# O script cria um backup com nome: backup-app-producao-YYYYMMDD-HHMM
O script cria o backup e aguarda sua conclusão:
>BACKUP_NAME="backup-app-producao-$(date +%Y%m%d-%H%M)"
velero backup create "$BACKUP_NAME" \
--include-namespaces app-producao \
--snapshot-volumes=true \
--storage-location default \
--kubecontext aks-blog-castilho-brazilsouth
# Aguardar conclusão
velero backup wait "$BACKUP_NAME" \
--kubecontext aks-blog-castilho-brazilsouth
# Ver detalhes do backup
velero backup describe "$BACKUP_NAME" --details \
--kubecontext aks-blog-castilho-brazilsouth
O output de velero backup describe mostra o número de itens coletados por tipo de recurso (Deployments, Services, ConfigMaps, etc.) e o status de cada PVC snapshot. Um backup bem-sucedido tem Phase: Completed e zero warnings críticos:
># Saída esperada (resumida):
# Name: backup-app-producao-20260603-1430
# Namespace: velero
# Labels: velero.io/storage-location=default
# Phase: Completed
#
# Started: 2026-06-03 14:30:00 +0000 UTC
# Completed: 2026-06-03 14:30:42 +0000 UTC
#
# Expiration: 2026-07-03 14:30:00 +0000 UTC
#
# Resource List:
# apps/v1/Deployment: 1
# v1/Namespace: 1
# v1/Service: 1
Passo 6 — Restore cross-region no cluster East US
Com o velero backup restore aks e o backup concluído e replicado para East US via RA-GZRS, execute o restore no cluster secundário. O script 03-restore-backup.sh recebe o nome do backup como argumento e faz o restore diretamente no contexto de East US:
># Restore no cluster East US
bash scripts/art-10-velero-aks/03-restore-backup.sh \
backup-app-producao-20260603-1430
O script executa:
>velero restore create "restore-$(date +%Y%m%d-%H%M)" \
--from-backup backup-app-producao-20260603-1430 \
--kubecontext aks-blog-castilho-eastus
velero restore wait "restore-..." \
--kubecontext aks-blog-castilho-eastus
velero restore describe "restore-..." --details \
--kubecontext aks-blog-castilho-eastus
Após o restore, verifique se os recursos foram recriados no cluster de East US:
># Verificar recursos restaurados
kubectl get all -n app-producao --context aks-blog-castilho-eastus
# NAME READY STATUS RESTARTS
# pod/dr-demo-xxx-yyy 1/1 Running 0
# pod/dr-demo-xxx-zzz 1/1 Running 0
#
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
# service/dr-demo LoadBalancer 10.x.x.x 20.y.y.y 80:30xxx/TCP
# Confirmar que a aplicação responde
kubectl get svc dr-demo -n app-producao \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}' \
--context aks-blog-castilho-eastus
O restore recria o namespace, o Deployment e o Service. Como a aplicação usa a imagem do ACR geo-replicado (acrblogcastilho.azurecr.io/dr-demo:eastus), o pull é local — sem tráfego cross-region para obter a imagem. O Service do tipo LoadBalancer provisiona um novo IP externo em East US, que pode ser adicionado como origin no Front Door para completar o failover.
Passo 7 — Schedule de backup automático
Para um DR efetivo, o backup precisa ser recorrente. O script 04-schedule-backup.sh cria um schedule diário às 02:00 UTC com TTL de 720 horas (30 dias), garantindo que sempre haja backups recentes disponíveis para restore:
># Criar schedule no cluster primário
bash scripts/art-10-velero-aks/04-schedule-backup.sh \
aks-blog-castilho-brazilsouth
O schedule é criado com:
>velero schedule create schedule-diario \
--schedule "0 2 * * *" \
--include-namespaces app-producao \
--snapshot-volumes=true \
--storage-location default \
--ttl 720h \
--kubecontext aks-blog-castilho-brazilsouth
# Verificar schedules ativos
velero schedule get --kubecontext aks-blog-castilho-brazilsouth
# NAME STATUS CREATED SCHEDULE LAST BACKUP
# schedule-diario Enabled 2026-06-03 ... 0 2 * * * n/a
Com o TTL de 720h e execuções diárias, você mantém até 30 backups — suficiente para atender um RPO de 24 horas. Para RPOs menores, reduza o intervalo do schedule (por exemplo, "0 */6 * * *" para de 6 em 6 horas) e ajuste o TTL proporcionalmente. Os backups são nomeados automaticamente pelo Velero como schedule-diario-YYYYMMDD-HHMMSS.
Troubleshooting
| Problema | Causa | Solução |
|---|---|---|
Backup Storage Location com status Unavailable | Credenciais do SP incorretas ou Storage Account com acesso público desabilitado bloqueando o Velero | Verificar se AZURE_CLIENT_ID e AZURE_CLIENT_SECRET estão corretos e se o SP tem role Contributor no RG de workload. Se a SA tem public_network_access_enabled = false, o cluster precisa acessar via Private Endpoint ou adicionar exceção de rede |
Backup com Phase: PartiallyFailed nos PVCs | Node Agent não está rodando ou o CSI Driver não suporta VolumeSnapshots | Verificar se o DaemonSet node-agent tem um pod em cada node: kubectl get ds node-agent -n velero. Confirmar que o VolumeSnapshotClass do Azure Disk CSI está instalado |
Restore com Phase: Failed — namespace já existe | O namespace app-producao já existe no cluster de destino | Adicionar --existing-resource-policy=update ao comando de restore para atualizar recursos existentes em vez de falhar |
| Pull da imagem falhando após restore no EUS | Role AcrPull da kubelet identity do cluster EUS não está configurada | Verificar o role assignment do Art. 09: o cluster EUS precisa do role AcrPull no ACR. O restore recria o Deployment mas não recria IAM do cluster |
velero backup-location get trava sem resposta | Pod do Velero não está rodando ou crashloopando | Verificar logs: kubectl logs -n velero -l app.kubernetes.io/name=velero --context <ctx> |
Limpeza dos recursos
># Remover schedules e backups
velero schedule delete schedule-diario --kubecontext aks-blog-castilho-brazilsouth --confirm
velero backup delete --all --kubecontext aks-blog-castilho-brazilsouth --confirm
# Desinstalar o Velero dos clusters
helm uninstall velero -n velero --kube-context aks-blog-castilho-brazilsouth
helm uninstall velero -n velero --kube-context aks-blog-castilho-eastus
# Remover o namespace
kubectl delete namespace velero --context aks-blog-castilho-brazilsouth
kubectl delete namespace velero --context aks-blog-castilho-eastus
# Remover o Service Principal
az ad sp delete --id "$(az ad sp list --display-name sp-velero-blog-castilho --query '[0].appId' -o tsv)"
Próximos passos
Com o velero backup restore aks configurado, os backups de namespace são realizados diariamente e podem ser restaurados no cluster secundário em minutos. O Art. 11 avança para a orquestração completa do failover: Runbooks PowerShell no Azure Automation que coordenam o ASR (failover de VMs), o Traffic Manager, o AKS e o Front Door em uma sequência automatizada — transformando as peças individuais desta série em um procedimento de DR executável com um webhook.
- 📖 Art. 01: Planejamento de DR Azure e Landing Zone
- 📖 Art. 02: Hub-Spoke Landing Zone com Terraform
- 📖 Art. 03: Azure Firewall e NSGs na Landing Zone
- 📖 Art. 04: Azure Bastion na Landing Zone sem IP Público
- 📖 Art. 05: Azure Front Door e Traffic Manager para Failover
- 📖 Art. 06: DNS Privado Multi-Região no Azure
- 📖 Art. 07: Azure Site Recovery para VMs Multi-Região
- 📖 Art. 08: Azure Storage com Geo-Replicação para DR
- 📖 Art. 09: AKS Multi-Região com Failover no Azure
- ⚙️ Art. 10 (este): Velero no AKS para Backup e Restore Cross-Region
- 🔒 Art. 11: Runbooks de Failover no Azure Automation
- 🔒 Art. 12: Simular um DR no Azure sem Impacto em Produção
- 🔒 Art. 13: Monitoramento do DR no Azure com Azure Monitor
Interessado em saber mais sobre artigos relacionados ao Microsoft Azure CLIQUE AQUI
🚀 Vamos nos conectar?
Não perca nenhuma oportunidade! Cadastre-se nas minhas redes e no canal do YouTube para receber conteúdos de TI, Cloud, Azure, Kubernetes e DevOps em primeira mão.
Dica: No Facebook, todos os artigos do blog são publicados automaticamente. Vale a pena curtir!
💬 Dúvidas ou Problemas?
Com o intuito de ajudar a comunidade, caso você tenha dúvidas ou encontre problemas na execução dos comandos deste artigo, deixe um comentário abaixo. Responderei o mais breve possível!
Muito obrigado pela visita e até o próximo post!
Jefferson Castilho Especialista em Cloud & DevOps.Este guia técnico é exclusivo do Blog do Castilho. Explore nossa para mais conteúdos sobre IA e Cloud.


