CNPG-Backup/docs/recovery-procedure.md

281 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Procedimiento de Recuperación – CNPG-Backup
Este documento describe los pasos exactos para restaurar un cluster PostgreSQL usando los backups creados por la estrategia CloudNativePG definida en este repositorio.
## Escenario común de recuperación
| Evento | Acciones típicas |
|-------|----------------|
| **Corrupción del cluster** | Restaurar de un backup completo más WALs recientes |
| **Pérdida del nodo primario** | Escalar o restaurar en un nodo diferente |
| **Pérdida de datos accidental** | Point-In-Time Recovery (PITR) a un timestamp antes del incidente |
| **Migración a otro cluster** | Restaurar un backup completo (cold) sin WALs |
## Requisitos previos
- El plugin [Barman Cloud](https://cloudnative-pg.io/plugin-barman-cloud/) (`barman-cloud.cloudnative-pg.io`) debe estar instalado en el cluster:
```bash
kubectl apply -f https://github.com/cloudnative-pg/cnpg-i/releases/download/v0.5.0/manifest.yaml
```
- Las credenciales de ObjectStore (`object-store-creds`) deben existir en el namespace donde se restaurará.
- El bucket (`cnpg-backups`) debe ser accesible desde el namespace del nuevo cluster.
## Guía rápida de recuperación (comando único)
Para recuperar un cluster de múltiples nodos completo:
```bash
kubectl cnpg restore pg-backup \
--backup=latest \
--namespace=default \
--target='2026-09-01 12:00:00' \
--sudo-recovery
```
(El timestamp `--target` es opcional – omitirlo restaurará desde el backup más reciente)
## Paso a paso
### 1. Identificar un backup válido
Listar todos los recursos `Backup` ordenados por CreationTimestamp.
```bash
kubectl get backups -o wide
```
Salida esperada (columnas relevantes):
```
NAME AGE CLUSTER METHOD PHASE STARTED_AT COMPLETION DESTINATION
backup-1 2h pg-backup plugin completed 2026-09-06T02:00:00Z 2026-09-06T02:05:00Z s3://cnpg-backups/pg-backup/
backup-2 30m pg-backup plugin completed 2026-09-06T01:00:00Z 2026-09-06T01:03:00Z s3://cnpg-backups/pg-backup/
```
**¿Cómo usarlo?**
- `backup-1` – la restauración más reciente (recomendada para RTO mínimo).
- `backup-2` – una restauración intermedia para una recuperação al punto en el tiempo más antigua.
### 2. Restaurar desde el backup completo más reciente
Cuando se necesita un cluster nuevo (ej. reemplazo de nodos o reconstrucción post-falla) y no hay necesidad de recuperar un punto específico:
```bash
# Opción A – Usar el comando cnpg RESTOURE (recomendado)
kubectl cnpg restore pg-backup \
--backup=backup-1 \
--namespace=default \
--recovery-conf='application_name=restored_cluster'
# Opción B – Aplicar un recurso YAML de Cluster con bootstrap.recovery
cat <<EOF | kubectl apply -f -
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: pg-restored
namespace: default
spec:
instances: 3
imageName: ghcr.io/cloudnative-pg/postgresql:18.1-minimal-trixie
bootstrap:
recovery:
backup:
name: backup-1
# si el backup está en otro namespace, especifique el namespace aquí:
# namespace: default
recoveryTarget:
# por defecto, restaurar al momento del backup
# Opcionalmente, restaurar a un timestamp más antiguo:
targetTimeStamp: "2026-09-05T10:30:00Z"
# Opcionalmente, restaurar en un timestamp específico sin incluir el tiempo:
# targetTimeline: "2"
storage:
size: 50Gi
storageClass: standard
resources:
requests:
cpu: "500m"
memory: "256Mi"
limits:
cpu: "2"
memory: "1Gi"
backup:
target: "prefer-standby"
barmanObjectStore:
objectStore:
name: pg-backup-store
plugins:
- name: barman-cloud.cloudnative-pg.io
isWALArchiver: true
parameters:
barmanObjectName: pg-backup-store
serverName: pg-backup
EOF
```
### 3. Restaurar al Punto en el Tiempo (PITR)
Cuando se necesita recuperar de un backup y replayear WALs hasta un timestamp específico:
```bash
kubectl cnpg restore pg-backup \
--backup=backup-2 \
--namespace=default \
--target='2026-09-05 14:30:00' \
--recovery-conf='application_name=pitr_cluster' \
--sudo-recovery
```
**Explicación de los parámetros:**
| Parámetro | Función |
|-----------|----------|
| `--backup=backup-2` | Usar este backup como punto de partida para la restauración completa. |
| `--target='2026-09-05 14:30:00'` | Restaurar todos los WALs desde el backup hasta este timestamp (inclusive). |
| `--recovery-conf='application_name=pitr_cluster'` | Agregar `application_name` al archivo postgresql.conf del cluster restaurado – útil para identificar el cluster en el servidor. |
| `--sudo-recovery` | Usar un namespace de recuperación privilegiado (si no se especifica, el comando será ejecutado en el namespace actual). |
**¿Cómo se especifica una restauración PITR mediante YAML?**
```yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: pg-pitr
namespace: default
spec:
instances: 1 # Puede ser 1 inicialmente y escalar después
imageName: ghcr.io/cloudnative-pg/postgresql:18.1-minimal-trixie
bootstrap:
recovery:
backup:
name: backup-2 # El backup base completo del que se partirá
recoveryTarget:
targetTimeStamp: "2026-09-05T14:30:00Z" # El timestamp exacto al que se quiere restaurar
# También se puede usar targetImmediate (true) para restaurar a la instancia más reciente
# targetImmediate: true
# Si el backup no contiene WALs hasta el timestamp, es necesario incluir un backup más reciente:
# recoveryWalSource: "latest"
storage:
size: 20Gi # Comienzo pequeño; escalar si es necesario
storageClass: standard
resources:
requests:
cpu: "500m"
memory: "256Mi"
backup:
target: "prefer-standby"
barmanObjectStore:
objectStore:
name: pg-backup-store
plugins:
- name: barman-cloud.cloudnative-pg.io
isWALArchiver: true
parameters:
barmanObjectName: pg-backup-store
serverName: pg-backup
```
### 4. Ver el estado de una restauración
Ambos `kubectl cnpg restore` y crear un recurso `Cluster` con `bootstrap.recovery` serán administrados por el operador CloudNativePG.
```bash
# Monitorear el progreso – también funciona para restauraciones desde CLI
kubectl get cluster pg-restored -w
# Ver detalles completos
kubectl describe cluster pg-restored
# Seguir eventos bajo el evento del administrador
kubectl get events --field-selector involvedObject.name=pg-restored
# Una vez que el cluster esté listo:
kubectl get pod -l cnpg.io/cluster=pg-restored
kubectl exec -it <pg-pod> -- psql -U <user> -d <db>
```
### 5. Verificación y pruebas de restauración
Después de una restauración exitosa, realice estas verificaciones:
1. **Conexión y datos básicos**
```bash
kubectl exec -it $(kubectl get pod -l cnpg.io/cluster=pg-restored -o jsonpath='{.items[0].metadata.name}') -- psql -U app_user -d app_db -c "SELECT COUNT(*) FROM my_table;"
```
2. **Corrupción de WALs**
```bash
kubectl exec -it $(kubectl get pod -l cnpg.io/cluster=pg-restored -o jsonpath='{.items[0].metadata.name}') -- pg_verifybackup -D /var/lib/postgresql/data/temporary_backup_path
```
(El `pg_verifybackup` es provisto por CloudNativePG y puede ser ejecutado en un contenedor que acceda al backup)
3. **Puntuación de disponibilidad**
```bash
kubectl exec -it $(kubectl get pod -l cnpg.io/cluster=pg-restored -o jsonpath='{.items[0].metadata.name}') -- psql -U app_user -d postgres -c "SELECT pg_is_in_recovery();"
```
Debe devolver `f` (ya que el cluster restaurado estará en modo de recuperación hasta que se reanude el streaming de WALs).
### 6. Limpiar un cluster restaurado innecesario
Una vez verificado que el cluster restaurado está funcionando como se espera, se puede eliminar el cluster original si se planea reemplazarlo completamente:
```bash
kubectl delete cluster pg-backup --timeout=300s
```
Luego, renombre o reemplace el cluster restaurado (`pg-restored`) en el DNS/servicio de la aplicación si es necesario.
## Políticas de retención y cómo afectan a la recuperación
- **Backups base (`data.retentionPolicy`)**: `7 days` → los backups más antiguos de 7 días serán eliminados automáticamente por Barman Cloud. Asegúrese de recuperar todo lo necesario antes de que la retención elimine el backup.
- **WAL archives (`wal.retentionPolicy`)**: `14 days` → los WALs más antiguos de 14 días serán eliminados. Si se necesita una restauración PITR más antigua, solicite una extensión temporal del backup del object store o mantenga una réplica secundaria separada en otro bucket.
## Frecuencia de restauración recomendada
| Tasa de cambio | Retención recomendada de WAL | Frecuencia de backup base |
|------------|----------------------|-------------------|
| Alta (< 5 min) | 7 días | Cada 6 h (opcional) |
| Media (15–30 min) | 14 días | Diario (midnight) |
| Baja (> 2 h) | 30 días | Diario (mediodía) |
Los valores por defecto en este repositorio (`01-objectstore.yaml`) están configurados para una frecuencia media de cambio con retención diaria y de WALs.
## Casos de error comunes y soluciones
| Síntoma | Causa probable | Solución |
|---------|--------------|----------|
| `ERROR: file "pg_ident.conf" not found` | El backup se tomó de un cluster con configuración de autentificación personalizada | Copie `pg_ident.conf` desde el backup original en el nuevo cluster (o restaure el backup completo del cluster original) |
| `FATAL: password authentication failed for user "app"` | Las credenciales de autenticación no están presentes en el nuevo cluster | Aplique el `Secret` `postgresql-superuser` o cree una nueva contraseña con `kubectl create secret generic ...` |
| `RESTORE FAILED: WAL file not found in the object store` | El WAL necesario para la restauración PITR fue eliminado por la retención | Aumente el plazo de retención de WALs en `01-objectstore.yaml` o use un backup más reciente como punto de partida para la restauración. |
## Resumen rápido (cheat-sheet)
```bash
# Listar backups
kubectl get backups -o wide
# Restaurar al backup más reciente
kubectl cnpg restore pg-backup --backup=latest
# Restaurar al timestamp específico (PITR)
kubectl cnpg restore pg-backup --backup=backup-2 --target='2026-09-05 14:30:00'
# Monitorear la restauración
kubectl get cluster pg-restored -w
kubectl describe cluster pg-restored
# Probar la conexión después de la restauración
kubectl exec -it <pg-pod> -- psql -U app_user -d app_db -c "SELECT version();"
```
## Referencias
- [Documentación de CloudNativePG – Backups](https://cloudnative-pg.io/docs/current/backup/)
- [Documentación del plugin Barman Cloud – Retención](https://cloudnative-pg.io/plugin-barman-cloud/docs/retention/)
- [CloudNativePG – Recuperación PITR](https://cloudnative-pg.io/docs/current/recovery/)
Este procedimiento se actualiza cuando se usan nuevas versiones del plugin Barman Cloud o del operador CloudNativePG.