docs: add recovery procedure documentation

This commit is contained in:
Deibis Moreno 2026-09-05 21:29:45 -04:00
parent 4db9f14285
commit 93d861d7a7

281
docs/recovery-procedure.md Normal file
View File

@ -0,0 +1,281 @@
# 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.