docs: add recovery procedure documentation
This commit is contained in:
parent
4db9f14285
commit
93d861d7a7
281
docs/recovery-procedure.md
Normal file
281
docs/recovery-procedure.md
Normal 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.
|
||||
Loading…
Reference in New Issue
Block a user