Failover playbook¶
Last updated: 2026-07-12
Qué hacer cuando un host del cluster muere. Documento de emergencia: pensado para leer rápido cuando algo está mal, no para mantenimiento normal.
Antes de leer: si la VM o LXC solo está en estado raro (frozen, OOM, kernel panic), prueba primero
qm reset / qm reboot / pct rebootdesde el otro nodo. Esto aplica solo si el guest está irrecuperable o el host físico está caído.
Inventario crítico¶
Reparto real de guests (verificado 2026-07-12 con pct list/qm list):
- proxmox-50 (el nodo "gordo", Ryzen): VM 171, VM 208, LXC 100, 102, 110, 172, 186 (PBS), 251, 270 (caddy-primary), 280 (rp-server), 281 (wp-pulse).
- proxmox2-51 (el nodo pequeño, N5095): LXC 123 (cf), 155 (wg), 200 (n8n), 271 (caddy-secondary). Solo 4 guests.
| Guest | Host actual | RAM | Replica | Backup PBS | Notas |
|---|---|---|---|---|---|
| VM 171 ha (HomeAssistant) | proxmox-50 | 6 GB | → proxmox2 cada 15min | 03:00 daily, keep 7 | USB BT pinneado a proxmox-50 — failover a pmx2 requiere editar config para quitar usb0 |
| VM 208 ubuntu-media-server | proxmox-50 | 12 GB | ❌ no replica | 03:00 daily, keep 7 | Heavy lifter — Loki, Grafana, Alertmanager, media stack, PocketID (Caddy NO está aquí — vive en 270/271) |
| LXC 100 Vera/clawdbot | proxmox-50 | 4 GB | ❌ no replica | 04:30 daily, keep 7 | Bot Telegram (Vera) + relay de alertas backup-freshness. Sin él no salen avisos a Telegram vía CT100 |
| LXC 186 pbs | proxmox-50 | 2 GB | ❌ no replica (es el destino) | ❌ N/A | Backup destination. Ojo: si cae proxmox-50, cae PBS → no se puede restaurar de PBS hasta recuperarlo |
| LXC 270 caddy-primary | proxmox-50 | — | ❌ no replica | 05:00 daily, keep 7 | CRÍTICO — edge caddy primario (VIP keepalived .250) |
| LXC 280 rp-server | proxmox-50 | — | ❌ no replica | 05:00 daily, keep 7 | CRÍTICO — reverse proxy / remote-pulse |
| LXC 281 wp-pulse | proxmox-50 | — | ❌ no replica | 02:00 daily, keep 7 | wp-pulse control plane (/srv/wp-pulse/sites excluido, re-pullable) |
| LXC 102 iarq-bkp | proxmox-50 | — | ❌ no replica | 05:30 daily, keep 7 | misc CT (.113) |
| LXC 110 tv-gw | proxmox-50 | — | ❌ no replica | 05:30 daily, keep 7 | misc CT (.210) |
| LXC 172 ha-ml | proxmox-50 | — | ❌ no replica | 05:30 daily, keep 7 | misc CT |
| LXC 251 rag | proxmox-50 | — | ❌ no replica | 05:30 daily, keep 7 | misc CT (.188) |
| LXC 123 cf | proxmox2-51 | 256 MB | → proxmox cada 15min | 01:00 daily, keep 7 | Cloudflare tunnel daemon — sin él no hay ingress externo |
| LXC 155 wg | proxmox2-51 | 256 MB | → proxmox cada 15min | 01:00 daily, keep 7 | Wireguard |
| LXC 200 n8n | proxmox2-51 | 1 GB | ❌ no replica | 02:00 daily, keep 7 | Alert hub legacy (ver alerting-flow.md) |
| LXC 271 caddy-secondary | proxmox2-51 | — | ❌ no replica | 05:00 daily, keep 7 | CRÍTICO — edge caddy secundario (VIP failover) |
Decomisados (ya no existen): LXC 253 (era clawdbot → migrado a CT100) y LXC 249 (beszel).
Escenario A — proxmox-50 down (el grave)¶
Impacto inmediato: cae CASI TODO — VM 171 (HA), VM 208 (Loki/Grafana/Alertmanager/media/PocketID), Vera/CT100 (relay de alertas), PBS/CT186, caddy-primary (270), rp-server (280), wp-pulse (281) y los misc CTs (102/110/172/251). Sobreviven solo en proxmox2-51: cf (123), wg (155), n8n (200) y caddy-secondary (271).
Buenas noticias: el VIP keepalived .250 debería hacer failover a caddy-secondary (271) + cloudflared (123) sigue vivo → el ingress externo probablemente sobrevive (aunque sin upstreams sanos hasta restaurar VM208).
Mala noticia clave: PBS (CT186) está caído → no se puede restaurar de PBS hasta recuperarlo. Y sin Vera/CT100 no salen avisos a Telegram.
Pasos (SSH a [email protected]):
- Recuperar PBS primero (bloquea todo lo demás): PBS (CT186) vivía en proxmox-50. Sus chunks están en el terramaster NFS (intacto). Redesplegar un PBS temporal en proxmox2 (o arrancar una réplica) apuntando al datastore existente en el NAS, o montar el NAS y restaurar con
proxmox-backup-client. Sin PBS accesible, lospct restore/qmrestorede abajo no funcionan. - HA — failover manual (USB no estará disponible): HA arranca sin Bluetooth (presence detection fallará). Aceptable temporalmente. (171 SÍ tiene réplica → arranque rápido, no necesita PBS.)
- VM 208 (sin réplica) — restore desde PBS a proxmox2 (requiere PBS del paso 1): Tarda ~20-25 min con 140 GB. Recupera Loki/Grafana/Alertmanager/media/PocketID.
- Vera/CT100, wp-pulse/281, misc CTs — restore desde PBS según prioridad (CT100 primero para recuperar alertas Telegram):
- Edge caddy-primary (270) + rp-server (280) — el 271 ya cubre el routing vía VIP; restaurar 270/280 para volver a HA:
- Verificar rutas:
pct exec 271 -- caddy validate --config /etc/caddy/Caddyfiley re-correrhomelab-ctl.py sync --yes(desde VM208, ya restaurada) para reapuntar ingress.
Tiempo estimado: HA en <5 min (réplica); pero VM208/servicios dependen de recuperar PBS primero → realistamente 30-60 min hasta tener el grueso operativo.
Escenario B — proxmox2-51 down (el leve)¶
Impacto inmediato: caen solo cf (123), wg (155), n8n (200) y caddy-secondary (271). Todo lo demás sigue vivo en proxmox-50: HA, media, Vera/CT100, PBS, caddy-primary (270), rp-server (280), wp-pulse (281) y los misc CTs.
- Routing entrante: caddy-primary (270) sigue vivo → el VIP
.250se mantiene/failover a 270. Pero cloudflared (123) cae → sin él no hay ingress externo hasta restaurarlo. El acceso LAN directo sigue. - PBS sigue vivo → los restores son fáciles.
Pasos (SSH a [email protected]):
- Prioridad — cloudflared (123): sin él no entra tráfico de Cloudflare. Está replicado → arranque rápido:
- caddy-secondary (271) — restore desde PBS (sin réplica). No urge si 270 ya sirve el VIP, pero recupera la HA del edge:
- n8n (200) — restore desde PBS (flujo de alertas legacy, baja prioridad):
- Verificar:
curl -sI https://finanzas.monxas.casa/(a través de CF → cloudflared → VIP → caddy) yhomelab-ctl.py sync --yessi cambió alguna IP.
Nota: Vera/CT100, caddy-primary (270), rp-server (280), wp-pulse (281) y los misc CTs no se caen en este escenario (viven en proxmox-50) — no requieren acción.
Tiempo estimado: <5 min para cf/wg (replicados), +10 min cada restore desde PBS (271, 200).
Drill no destructivo (validado 2026-04-26)¶
Para verificar que un backup PBS es restaurable sin tocar producción:
# Pick free VMID (verifica con qm/pct status NNN)
DRILL=999
# Listar backups disponibles (LXCs)
pvesm list pbs | grep ct/200
# Restore a VMID temporal con red aislada (IP libre, NO el VIP .250)
pct restore $DRILL pbs:backup/ct/200/<TIMESTAMP> \
--storage zfs-ha --hostname drill-temp --unprivileged 1 \
--memory 1024 --cores 2 --onboot 0 \
--net0 name=eth0,bridge=vmbr0,ip=192.168.0.249/24,gw=192.168.0.1 \
--tags drill-temp
pct start $DRILL
sleep 5
# Verificar servicio + DB integrity
pct exec $DRILL -- systemctl is-active n8n
curl -s http://192.168.0.249:5678/healthz
pct exec $DRILL -- sqlite3 /root/.n8n/database.sqlite \
'SELECT count(*) FROM workflow_entity;'
# Cleanup
pct stop $DRILL && pct destroy $DRILL
Para VMs (qmrestore en lugar de pct restore — usa el volid pbs:backup/..., no una ruta de filesystem):
qmrestore pbs:backup/vm/171/<TIMESTAMP> $DRILL --storage zfs-ha
qm set $DRILL --net0 virtio=...,bridge=vmbr0 # IP no conflict
qm set $DRILL --delete usb0 # quitar USB pinning
qm start $DRILL
# verificar luego destroy
Frecuencia automatizada: cron en proxmox-50 (/etc/cron.d/pbs-drill). LXC random mensual día 1 a 05:05, VM random trimestral día 15 a 05:05 (Ene/Abr/Jul/Oct). Detalles en scripts/pbs-drill.md. Drill manual también disponible (procedimiento arriba).
Recovery time objectives (RTO actuales)¶
| Pérdida | RTO realista | Notas |
|---|---|---|
| LXC replicado (123/155/171) | <5 min | mv config + start, no necesita PBS |
| LXC no replicado | 10-15 min | restore PBS |
| Edge caddy (270 o 271) | El otro cubre vía VIP; restore 10-15 min | keepalived VIP .250 failover automático |
| VM 171 (HA) sin USB | <5 min | failover, perdiendo BT |
| VM 208 entera | 25-30 min | restore 140 GB desde PBS |
| proxmox-50 down (Escenario A) | 30-60 min | PBS cae con él → recuperar PBS primero |
| Cluster entero (ambos hosts) | horas | redesplegar PBS desde cero + secuencial |
Lo que SÍ duele si pasa¶
-
Si terramaster (PBS storage) muere: pierdes TODOS los backups históricos. PBS solo guarda metadata, los chunks viven en el NAS. Mitigación: copia mensual offline del NAS a disco externo. Esta copia mensual NO está implementada hoy — añadir al backlog si se vuelve crítico.
-
Si Movistar router muere: sin DNS local, sin internet. Wireguard sigue para acceso interno-a-interno solo si el WG endpoint está en otra red. Mitigación: tener un spare router pre-configurado.
-
Si proxmox-50 muere (Escenario A): cae PBS con él. Los chunks en el terramaster NFS sobreviven, pero hay que redesplegar/arrancar PBS (temporal en proxmox2 o restaurar CT186) apuntando al datastore existente antes de poder restaurar nada más. Es la dependencia crítica del escenario.