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
-
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.
-
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.
-
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).
-
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.
-
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/receiveprogramado concronpara 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:
- Management (puertos de administración, Grafana, Portainer).
- Lab (VMs, contenedores, GPU passthrough).
- 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
firewallinterno 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 --buildpara 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 configydocker compose pullen 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" [email protected]
fi
done
- Usa
pbs-client prunepara 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 ally--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-pullen 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
- Almacenamiento:
zpool statusdebe mostrar todos los vdev sin errores;zfs list -t snapshotconfirma la existencia de snapshots recientes. - Red:
ip -d link show vmbr0muestra la VLAN 10;iperf3 -c <peer>verifica 10 GbE throughput > 9 Gbps. - Backup: Ejecuta
pbs-client list-snapshotsy revisa que el último snapshot tenga estadoOK. - Monitorización: En Grafana, verifica que los paneles de CPU, NFS latency y PBS health muestren datos sin gaps.
- 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 adden 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.