11 KiB
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 (
barman-cloud.cloudnative-pg.io) debe estar instalado en el cluster: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:
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.
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:
# 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:
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?
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.
# 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:
-
Conexión y datos básicos
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;" -
Corrupción de WALs
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_verifybackupes provisto por CloudNativePG y puede ser ejecutado en un contenedor que acceda al backup) -
Puntuación de disponibilidad
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:
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)
# 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
- Documentación del plugin Barman Cloud – Retención
- CloudNativePG – Recuperación PITR
Este procedimiento se actualiza cuando se usan nuevas versiones del plugin Barman Cloud o del operador CloudNativePG.