Problema

Los entusiastas de homelab suelen combinar servidores bare‑metal, máquinas virtuales y contenedores para ejecutar Plex, herramientas de gestión de medios, IA local y servicios de respaldo. Cuando la cantidad de componentes supera la docena, aparecen síntomas típicos: caídas intermitentes de servicios, pérdida de datos en volúmenes compartidos, dificultades para aplicar actualizaciones sin interrupciones y una visibilidad limitada del estado del sistema. El patrón subyacente es una arquitectura fragmentada que carece de monitorización centralizada, gestión de backups coherente y segmentación de red adecuada. Cualquier falla en el almacenamiento, la red o la capa de virtualización puede propagarse rápidamente, convirtiendo un pequeño inconveniente en una caída total del laboratorio.

Causa

  1. Almacenamiento heterogéneo sin política de redundancia clara

    • RAIDZ1/Z2 en discos de medios y NVMe en espejo para el arranque son comunes, pero la falta de un plan de migración automática entre capas (boot → VM storage → media) deja puntos únicos de falla.
  2. Redes VLAN mal aisladas

    • Cuando los servicios de gestión (Grafana, Portainer) comparten la misma VLAN que el tráfico de medios, un pico de ancho de banda o un ataque de denegación puede saturar el enlace y afectar la disponibilidad de los contenedores críticos.
  3. Actualizaciones sin orquestación

    • Herramientas como Watchtower actualizan imágenes Docker en caliente, pero sin pruebas de compatibilidad pueden romper dependencias (por ejemplo, cambios en la API de Radarr que rompen Plex webhook).
  4. Backups parciales o fuera de sincronía

    • Ejecutar Proxmox Backup Server (PBS) con un solo datastore local y otro en S3 sin validar la integridad de los snapshots lleva a restauraciones incompletas.
  5. Passthrough de GPU sin aislamiento de recursos

    • Pasar una Tesla T4 y una RTX 2000 Ada a una única VM para IA y transcodificación funciona, pero la falta de límites de CPU/memoria puede colapsar otras VMs cuando la carga de inferencia aumenta.

Solución

1. Arquitectura de almacenamiento coherente

  • Define capas de datos:

    • Boot: espejo RAID1 NVMe (mínimo 2 TB).
    • VM: ZFS pool con RAIDZ1 para rendimiento y snapshots.
    • Media: RAIDZ2 + hot‑spare, exportado vía NFS.
  • Automatiza la replicación: usa zfs send/receive programado con cron para replicar los snapshots de VM a un datastore secundario en B2. Mantén al menos dos copias fuera del sitio.

2. Segmentación de red con VLANs y bonding

  • Crea tres VLANs obligatorias:

    1. Management (puertos de administración, Grafana, Portainer).
    2. Lab (VMs, contenedores, GPU passthrough).
    3. Media (NFS, Plex, qBittorrent).
  • Configura bonding 10 GbE en modo LACP para redundancia y ancho de banda agregado. En Proxmox, asigna cada bridge a la VLAN correspondiente y usa firewall interno para bloquear tráfico no autorizado entre ellas.

3. Orquestación de actualizaciones

  • Sustituye Watchtower por Portainer Stacks con versiones pin‑eadas en docker-compose.yml.
  • Añade una fase de pruebas en una VM “staging” que replica la configuración de producción. Usa docker compose up -d --no-deps --build para validar antes de desplegar al entorno real.
  • Documenta los cambios en Gitea y habilita CI con GitHub Actions (o GitLab CI) que ejecute docker compose config y docker compose pull en la VM de staging.

4. Backup integral y verificación

  • Configura dos datastores en PBS:

    • Local: iSCSI LUN con ZFS, snapshots cada 4 h.
    • Remoto: bucket B2 con política de retención de 30 días.
  • Programa una tarea de integrity check semanal que compare el hash de los snapshots con el almacenado en B2:

#!/usr/bin/env bash
# Verifica integridad de snapshots PBS vs B2
for snap in $(pbs-client list-snapshots --json | jq -r '.[].id'); do
    local_hash=$(pbs-client get-snapshot $snap --hash)
    remote_hash=$(aws s3api head-object --bucket my-b2-bucket --key snapshots/$snap.hash --query ETag --output text)
    if [[ "$local_hash" != "$remote_hash" ]]; then
        echo "Mismatch en $snap" | mail -s "PBS integrity alert" admin@example.com
    fi
done
  • Usa pbs-client prune para eliminar snapshots viejos según la política de retención.

5. Aislamiento de recursos de GPU

  • En la VM que recibe los GPUs, habilita cgroups para limitar CPU y memoria de los procesos de inferencia.
  • Crea contenedores Docker con --gpus all y --cpus="2" para tareas de transcodificación, dejando recursos libres para la VM de desarrollo.

6. Monitorización unificada

  • Centraliza logs con Grafana Loki + Promtail en cada host y contenedor.

  • Configura alertas en Grafana Alerting para:

    • Uso de CPU > 80 % en la VM GPU por más de 5 min.
    • Latencia NFS > 200 ms.
    • Fallos de backup PBS.
  • Usa Uptime Kuma para ping interno de los servicios críticos (Plex, Immich, Gitea).

7. Gestión de configuración

  • Mantén todo en Ansible: playbooks para crear bridges, VLANs, pools ZFS y despliegues Docker.
  • Versiona los playbooks en Gitea y ejecuta ansible-pull en cada nodo al iniciar.

Cuándo aplicar esta solución

  • Síntomas: interrupciones de Plex durante descargas, errores de backup, caída de dashboards Grafana, alta latencia en NFS, reinicios inesperados de contenedores tras actualizaciones.
  • Entorno: homelabs con >2 TB de datos, al menos una VM con GPU passthrough y varios contenedores Docker críticos.
  • No aplica: configuraciones extremadamente simples (una sola VM sin almacenamiento compartido) donde la sobrecarga de VLANs y ZFS no justifica el esfuerzo.

Código

# Creación de bridge con VLAN en Proxmox (ejemplo)
cat <<EOF > /etc/network/interfaces.d/vmbr0.cfg
auto vmbr0
iface vmbr0 inet static
    address 10.0.10.1/24
    bridge-ports eth0
    bridge-stp off
    bridge-fd 0
    post-up ip link set vmbr0 up
    post-up ip link set vmbr0 type vlan id 10
EOF

systemctl restart networking

Verificación

  1. Almacenamiento: zpool status debe mostrar todos los vdev sin errores; zfs list -t snapshot confirma la existencia de snapshots recientes.
  2. Red: ip -d link show vmbr0 muestra la VLAN 10; iperf3 -c <peer> verifica 10 GbE throughput > 9 Gbps.
  3. Backup: Ejecuta pbs-client list-snapshots y revisa que el último snapshot tenga estado OK.
  4. Monitorización: En Grafana, verifica que los paneles de CPU, NFS latency y PBS health muestren datos sin gaps.
  5. Alertas: Genera una condición artificial (p.ej., stress --cpu 8) y confirma que la alerta de CPU se dispara en Grafana.

Notas adicionales

  • Hot‑spare: siempre reserva al menos un disco de la misma capacidad que el RAIDZ2 para reemplazos rápidos.
  • Sincronización de tiempo: NTP en todos los nodos evita discrepancias en timestamps de logs y backups.
  • Seguridad de VPN: mantén el túnel WireGuard para qBittorrent aislado en su propia VLAN; evita que el tráfico P2P impacte la red de gestión.
  • Escalabilidad: cuando añadas más discos, expande el pool ZFS con zpool add en lugar de crear nuevos vdevs, para preservar la capacidad de snapshots.
  • Documentación: guarda diagramas de red y topología en un repositorio Markdown; actualízalos con cada cambio de hardware.