Sobre nós Guias Projetos Contactos
Админка
please wait

Declaração do Problema

Precisa de proteger os seus sistemas contra a perda de dados, minimizar o tempo de indisponibilidade durante desastres e garantir a continuidade do negócio com procedimentos de recuperação testados.

Objectivos de Recuperação

MétricaDefiniçãoMetas Típicas
RPO (Recovery Point Objective)Perda máxima de dados aceitável0 - 24 horas
RTO (Recovery Time Objective)Tempo máximo de indisponibilidade aceitávelMinutos - horas

Arquitectura de Backup

┌─────────────────────────────────────────────────────────────────────────┐
│ Production Environment │
├────────────────┬────────────────┬────────────────┬─────────────────────┤
│ Kubernetes │ Database │ Object Store │ Configuration │
│ Workloads │ (Primary) │ (S3/MinIO) │ (GitOps Repo) │
└───────┬────────┴───────┬────────┴───────┬────────┴─────────┬───────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌───────────────────────────────────────────────────────────────────────┐
│ Backup Layer │
├────────────────┬────────────────┬────────────────┬────────────────────┤
│ Velero │ pg_dump / │ S3 Cross- │ Git Mirror │
│ Snapshots │ mysqldump │ Region │ │
└───────┬────────┴───────┬────────┴───────┬────────┴────────┬───────────┘
│ │ │ │
└────────────────┴────────────────┴──────────────────┘
│
┌───────────▼───────────┐
│ Offsite Backup │
│ Storage (S3/GCS) │
│ Different Region │
└───────────────────────┘

1. Backup de Kubernetes com Velero

Instalar o Velero

# Instalar a CLI do Velero
wget https://github.com/vmware-tanzu/velero/releases/download/v1.12.0/velero-v1.12.0-linux-amd64.tar.gz
tar -xvf velero-v1.12.0-linux-amd64.tar.gz
mv velero-v1.12.0-linux-amd64/velero /usr/local/bin/
# Instalar o Velero no cluster
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.0 \
--bucket velero-backups \
--secret-file ./credentials-velero \
--backup-location-config region=us-west-2,s3ForcePathStyle="true",s3Url=https://s3.us-west-2.amazonaws.com \
--snapshot-location-config region=us-west-2

credentials-velero

[default]
aws_access_key_id=YOUR_ACCESS_KEY
aws_secret_access_key=YOUR_SECRET_KEY

Agendamentos de Backup

apiVersion: velero.io/v1
kind: Schedule
metadata:
name: daily-backup
namespace: velero
spec:
schedule: "0 2 * * *" # Diariamente às 2:00
template:
includedNamespaces:
- production
- staging
excludedResources:
- events
- pods
storageLocation: default
ttl: 720h # Retenção de 30 dias
snapshotVolumes: true
volumeSnapshotLocations:
- default
---
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: hourly-backup
namespace: velero
spec:
schedule: "0 * * * *" # A cada hora
template:
includedNamespaces:
- production
includedResources:
- configmaps
- secrets
- deployments
- services
- ingresses
ttl: 168h # Retenção de 7 dias
snapshotVolumes: false

Backup Manual

# Criar backup de todos os recursos de produção
velero backup create production-backup-$(date +%Y%m%d) \
--include-namespaces production \
--snapshot-volumes
# Criar backup antes de alterações importantes
velero backup create pre-migration-backup \
--include-namespaces production \
--wait

Restaurar a partir de Backup

# Listar backups
velero backup get
# Restaurar para o mesmo cluster
velero restore create --from-backup production-backup-20240115 \
--include-namespaces production
# Restaurar para um namespace diferente (para testes)
velero restore create --from-backup production-backup-20240115 \
--namespace-mappings production:restore-test

2. Estratégias de Backup de Bases de Dados

Arquivo Contínuo de PostgreSQL (WAL)

# postgresql.conf
archive_mode = on
archive_command = 'aws s3 cp %p s3://db-backups/wal/%f'
wal_level = replica
# Script de backup base
##!/bin/bash
BACKUP_NAME="base-$(date +%Y%m%d_%H%M%S)"
pg_basebackup -D /tmp/$BACKUP_NAME -Ft -z -Xs -P
aws s3 cp /tmp/$BACKUP_NAME.tar.gz s3://db-backups/base/$BACKUP_NAME.tar.gz
rm -rf /tmp/$BACKUP_NAME*

Backup de PostgreSQL com pgBackRest

# /etc/pgbackrest/pgbackrest.conf
[global]
repo1-path=/backup/pgbackrest
repo1-retention-full=2
repo1-retention-diff=14
repo1-cipher-type=aes-256-cbc
repo1-cipher-pass=your-encryption-key
[main]
pg1-path=/var/lib/pgsql/data
# Backup completo (semanal)
pgbackrest --stanza=main backup --type=full
# Backup diferencial (diário)
pgbackrest --stanza=main backup --type=diff
# Recuperação point-in-time
pgbackrest --stanza=main restore \
--type=time \
--target="2024-01-15 10:30:00"

Backup de MySQL/Percona com Percona XtraBackup

# Backup completo
xtrabackup --backup --target-dir=/backup/full/$(date +%Y%m%d)
# Backup incremental
xtrabackup --backup --target-dir=/backup/incr/$(date +%Y%m%d) \
--incremental-basedir=/backup/full/20240115
# Preparar para o restauro
xtrabackup --prepare --target-dir=/backup/full/20240115
xtrabackup --prepare --target-dir=/backup/full/20240115 \
--incremental-dir=/backup/incr/20240116
# Restauro
systemctl stop mysql
rm -rf /var/lib/mysql/*
xtrabackup --copy-back --target-dir=/backup/full/20240115
chown -R mysql:mysql /var/lib/mysql
systemctl start mysql

Kubernetes CronJob para Backup de Base de Dados

apiVersion: batch/v1
kind: CronJob
metadata:
name: database-backup
namespace: production
spec:
schedule: "0 3 * * *"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: postgres:15
command:
- /bin/bash
- -c
- |
set -e
BACKUP_NAME="backup-$(date +%Y%m%d-%H%M%S).sql.gz"
pg_dump -h $DB_HOST -U $DB_USER $DB_NAME | gzip > /tmp/$BACKUP_NAME
aws s3 cp /tmp/$BACKUP_NAME s3://db-backups/postgres/$BACKUP_NAME
# Limpar backups antigos (manter os últimos 30)
aws s3 ls s3://db-backups/postgres/ | sort -r | tail -n +31 | \
awk '{print $4}' | xargs -I {} aws s3 rm s3://db-backups/postgres/{}
env:
- name: DB_HOST
value: postgres-service
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_NAME
value: production
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: s3-credentials
key: access-key
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: s3-credentials
key: secret-key

3. Recuperação de Desastres Multi-Região

Configuração Activo-Passivo

# Região primária
apiVersion: v1
kind: Service
metadata:
name: app-primary
annotations:
external-dns.alpha.kubernetes.io/hostname: app.example.com
external-dns.alpha.kubernetes.io/ttl: "60"
spec:
type: LoadBalancer
selector:
app: myapp
---
# Região secundária (standby)
apiVersion: v1
kind: Service
metadata:
name: app-secondary
annotations:
# Registo DNS activado apenas durante o failover
external-dns.alpha.kubernetes.io/hostname: app-dr.example.com
spec:
type: LoadBalancer
selector:
app: myapp

Replicação de Base de Dados entre Regiões

# Réplica cross-region do CloudNativePG
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: postgres-replica
namespace: production
spec:
instances: 2
replica:
enabled: true
source: postgres-primary
externalClusters:
- name: postgres-primary
connectionParameters:
host: postgres-primary.us-west-2.rds.amazonaws.com
user: replicator
password:
name: replication-credentials
key: password

4. Verificação e Testes de Backup

Testes Automatizados de Restauro

apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-verification
spec:
schedule: "0 6 * * 0" # Semanalmente ao domingo
jobTemplate:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: verify
image: backup-verifier:latest
command:
- /bin/bash
- -c
- |
set -e
# Obter o backup mais recente
LATEST=$(aws s3 ls s3://db-backups/postgres/ | sort -r | head -1 | awk '{print $4}')
# Descarregar e restaurar para a base de dados de teste
aws s3 cp s3://db-backups/postgres/$LATEST /tmp/backup.sql.gz
gunzip /tmp/backup.sql.gz
# Criar base de dados de teste
psql -h $TEST_DB_HOST -U $DB_USER -c "DROP DATABASE IF EXISTS backup_test"
psql -h $TEST_DB_HOST -U $DB_USER -c "CREATE DATABASE backup_test"
psql -h $TEST_DB_HOST -U $DB_USER -d backup_test -f /tmp/backup.sql
# Executar queries de verificação
USERS=$(psql -h $TEST_DB_HOST -U $DB_USER -d backup_test -t -c "SELECT COUNT(*) FROM users")
ORDERS=$(psql -h $TEST_DB_HOST -U $DB_USER -d backup_test -t -c "SELECT COUNT(*) FROM orders")
# Verificar a integridade dos dados
if [ "$USERS" -gt 0 ] && [ "$ORDERS" -gt 0 ]; then
echo "Backup verification PASSED"
curl -X POST $SLACK_WEBHOOK -d '{"text":"✅ Weekly backup verification passed"}'
else
echo "Backup verification FAILED"
curl -X POST $SLACK_WEBHOOK -d '{"text":"❌ Weekly backup verification FAILED"}'
exit 1
fi
# Limpeza
psql -h $TEST_DB_HOST -U $DB_USER -c "DROP DATABASE backup_test"

5. Runbook de Recuperação de Desastres

Checklist de Activação de DR

## Disaster Recovery Activation
### Pre-Activation (Assess)
- [ ] Confirm primary site is unavailable
- [ ] Estimate time to recover primary
- [ ] Get management approval for failover
- [ ] Notify stakeholders
### Activation (Execute)
1. [ ] Verify DR site health
```bash
kubectl get nodes
kubectl get pods -A
```
2. [ ] Activate database replica
```bash
# Promote PostgreSQL replica
kubectl exec -it postgres-0 -- pg_ctl promote
```
3. [ ] Update DNS records
```bash
# Point traffic to DR site
aws route53 change-resource-record-sets ...
```
4. [ ] Verify application connectivity
```bash
curl -I https://app.example.com/health
```
5. [ ] Monitor for errors
```bash
kubectl logs -f deployment/myapp
```
### Post-Activation (Verify)
- [ ] Verify all services operational
- [ ] Check database consistency
- [ ] Monitor error rates
- [ ] Communicate status to stakeholders
- [ ] Document timeline and actions taken
### Failback (Return to Primary)
- [ ] Restore primary site
- [ ] Sync data from DR to primary
- [ ] Test primary site
- [ ] Switch traffic back
- [ ] Deactivate DR site

6. Encriptação e Segurança de Backups

Encriptar Backups em Repouso

# Utilizar GPG para encriptação de backups
pg_dump mydb | gpg --encrypt --recipient [email protected] > backup.sql.gpg
# Utilizar OpenSSL
pg_dump mydb | openssl enc -aes-256-cbc -salt -pass file:/path/to/keyfile > backup.sql.enc
# Desencriptar
openssl enc -d -aes-256-cbc -pass file:/path/to/keyfile < backup.sql.enc | psql mydb

Política de Bucket S3

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EnforceEncryption",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::db-backups/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
},
{
"Sid": "RestrictAccess",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::db-backups",
"arn:aws:s3:::db-backups/*"
],
"Condition": {
"NotIpAddress": {
"aws:SourceIp": ["10.0.0.0/8"]
}
}
}
]
}

A Mentalidade de DR de um Senior

O Problema do etcd: Backups do Estado do Cluster

O estado do seu cluster Kubernetes vive no etcd. Se o etcd falhar e não tiver um backup, terá de reconstruir todo o cluster a partir do zero.

Backups de etcd Encriptados:

# Criar backup encriptado
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%Y%m%d).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
--key=/etc/kubernetes/pki/etcd/healthcheck-client.key
# Encriptar e carregar
gpg --encrypt --recipient [email protected] /backup/etcd-*.db
aws s3 cp /backup/etcd-*.db.gpg s3://cluster-backups/etcd/

Agende isto, no mínimo, diariamente. Um backup de etcd desactualizado é melhor do que não ter backup.

Filosofia de Testes: Backups Não Testados Não Valem Nada

Regra Senior: um backup que não foi testado não é um backup — é uma esperança.

O que Testar: 1. Consegue descarregar o backup? (Rede, permissões, chaves de encriptação) 2. Consegue restaurar o backup? (Formato, corrupção, completude) 3. Os dados estão correctos? (Contagens de linhas, checksums, testes da aplicação) 4. Quanto tempo demora o restauro? (Cumpre o seu RTO?)

Agende testes automatizados de restauro semanalmente. Se um teste falhar, alguém deve ser notificado via pager.

O Framework de Decisão de Failover

O failover é caro e arriscado. Utilize este framework:

PerguntaSe SimSe Não
O site primário está completamente indisponível?Continuar para a próximaAguardar e monitorizar
A recuperação vai demorar mais do que o RTO?Continuar para a próximaAguardar e recuperar
Os dados no site de DR estão actuais (dentro do RPO)?Avançar com o failoverAvaliar o risco de perda de dados
As partes interessadas aprovam a perda de dados?Executar o failoverAguardar ou encontrar alternativas

Nunca faça failover sem aprovação explícita. A pessoa que decide deve compreender as implicações da perda de dados.

Failback: A Metade Esquecida

Planear o failover sem planear o failback deixa-o preso em modo de DR indefinidamente.

Considerações de Failback:

  • Como sincroniza os dados de volta para o site primário?
  • Como verifica que o primário está saudável antes de mudar?
  • Como minimiza o tempo de indisponibilidade da segunda mudança?
  • E se o primário falhar novamente durante o failback?

Documente e teste os procedimentos de failback em conjunto com o failover.

Checklist de DR

Estratégia de Backup

  • [ ] RPO e RTO definidos e documentados
  • [ ] Todos os dados críticos identificados
  • [ ] Agendamentos de backup automatizados configurados
  • [ ] Backups armazenados offsite/entre regiões
  • [ ] Encriptação de backups activada
  • [ ] Políticas de retenção de backups definidas
  • [ ] Backups de etcd agendados para clusters Kubernetes

Capacidade de Recuperação

  • [ ] Site de DR provisionado e testado
  • [ ] Replicação de base de dados configurada
  • [ ] Failover de DNS configurado
  • [ ] Runbooks de recuperação documentados
  • [ ] Recuperação testada trimestralmente
  • [ ] Procedimentos de failback documentados

Verificação

  • [ ] Verificação automatizada de backups (semanal)
  • [ ] Testes regulares de restauro
  • [ ] Exercícios de DR realizados
  • [ ] Tempo de recuperação medido face ao RTO
  • [ ] Integridade dos dados verificada após o restauro

Artigos Relacionados na Wiki

 
 
 
Языки
Темы
Copyright © 1999 — 2026
ZK Interactive