Problema

En muchos homelabs el crecimiento rápido genera dos cuellos de botella habituales: capacidad de memoria insuficiente para ejecutar varios laboratorios simultáneos y acceso a GPU para workloads de IA o renderizado dentro de VMs. Cuando el hardware se reparte entre una workstation (Xeon) y una PC de escritorio (Intel Core Ultra), la arquitectura de la placa base y la configuración de IOMMU pueden impedir que la GPU sea asignada de forma estable a una VM. Además, la mezcla de canales de RAM (dual‑channel vs quad‑channel) y la falta de balanceo pueden degradar el rendimiento de los servicios críticos (SIEM, firewalls, controladoras de red). El desafío es diseñar una arquitectura que permita:

  1. Escalar la RAM a 128 GB o más sin perder ancho de banda.
  2. Pasar la GPU a VMs de IA o análisis de seguridad sin crashes.
  3. Separar el plano de gestión (PC de escritorio) del plano de carga (workstation) manteniendo conectividad de red y almacenamiento compartido.

Causa

Los fallos más frecuentes provienen de tres áreas:

1. Configuración de IOMMU y ACS

Muchas placas base no habilitan automáticamente la separación de grupos de dispositivos PCIe. Si la GPU y el controlador de red comparten el mismo IOMMU group, el passthrough falla o produce “device locked” en el arranque de la VM.

2. Distribución de módulos de RAM

Instalar módulos de distinta capacidad o velocidad en ranuras que no forman pares de canal genera un modo “flex mode”. En sistemas con Xeon, el rendimiento cae notablemente cuando los canales no están balanceados, especialmente bajo carga de ZFS y VM intensivas en memoria.

3. Topología de red y almacenamiento

Con varios firewalls y routers en la misma rack, la falta de VLANs o de una red de gestión dedicada puede saturar el enlace de 1 GbE que conecta la workstation a los discos NVMe, provocando latencias en los backups y en la replicación de ZFS.

Solución

A. Habilitar IOMMU y aplicar ACS override

  1. Editar /etc/default/grub para añadir los parámetros de kernel:
    • intel_iommu=on o amd_iommu=on según la CPU.
    • iommu=pt para pasar la traducción a la VM.
  2. Regenerar GRUB y reiniciar.
  3. Instalar vfio-pci y crear una regla udev que asocie la GPU a vfio-pci.
  4. Si la GPU y el NIC comparten grupo, aplicar acs_override=1 en el módulo vfio-pci.

B. Balancear la RAM

  1. Comprar pares idénticos de DDR4/DDR5 (misma capacidad, latencia y velocidad).
  2. Instalar los módulos en ranuras que formen pares de canal (consultar el manual de la placa).
  3. Verificar el modo de canal con dmidecode -t memory o lshw -c memory.
  4. En caso de limitaciones presupuestarias, usar “flex mode” solo para los módulos de menor capacidad y reservar los canales completos para los módulos de mayor capacidad.

C. Separar plano de gestión

  1. Configurar una VLAN de gestión (por ejemplo, VLAN 10) en el switch Cisco C9200L.
  2. Asignar a la workstation y a la PC de escritorio interfaces de gestión en esa VLAN.
  3. Mantener el tráfico de laboratorio en VLANs diferentes (20‑30) para firewalls y routers.
  4. Usar un NAS/NVMe shared pool conectado vía 10 GbE (o 25 GbE) para los discos de VM. En Proxmox, crear un zfs pool y exponerlo como iSCSI o NFS a los nodos de gestión.

D. Configurar GPU passthrough en Proxmox

  1. Crear una VM con machine: q35, bios: ovmf.
  2. En la definición de la VM, añadir la GPU como hostpci0: 01:00.0,pcie=1,x-vga=1.
  3. Desactivar el controlador de pantalla en la VM (nomodeset) y asegurarse de que el vfio-pci no está cargado en el host para esa GPU.

E. Optimizar ZFS y VM memory

  1. Activar zfs_arc_max acorde a la RAM disponible (ej. 64 GB en una máquina de 128 GB).
  2. Asignar balloon a las VMs que no requieren toda la memoria.
  3. Usar virtio-scsi-pci y virtio-balloon para I/O y gestión dinámica de RAM.

Cuándo aplicar esta solución

  • Síntomas: VMs que no arrancan con GPU, caídas de rendimiento bajo carga de ZFS, errores de “device locked” en Proxmox, latencias altas en backups.
  • Entorno: Homelabs con al menos una workstation Xeon o una PC de escritorio con GPU dedicada, y múltiples VMs que requieren aceleración de hardware.
  • No aplica: Configuraciones donde la GPU se usa exclusivamente en el host (no en VMs) o cuando el presupuesto impide adquirir pares de RAM idénticos; en esos casos, el paso de GPU puede omitirse y la RAM se gestiona como está.

Código

# 1. Habilitar IOMMU en GRUB
sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on iommu=pt /' /etc/default/grub
update-grub

# 2. Crear regla udev para la GPU (ejemplo NVIDIA)
cat <<EOF > /etc/udev/rules.d/99-vfio.rules
SUBSYSTEM=="pci", ATTRS{vendor}=="0x10de", ATTRS{device}=="0x1e84", DRIVER=="", ATTR{driver_override}="vfio-pci"
EOF
udevadm control --reload
modprobe -r nvidia
modprobe vfio-pci

# 3. Aplicar ACS override (si necesario)
echo "options vfio-pci disable_idle_d3=1" > /etc/modprobe.d/vfio-pci.conf

Verificación

  1. IOMMU activo: dmesg | grep -i iommu debe mostrar “Intel-IOMMU enabled” o “AMD-Vi: IOMMU enabled”.
  2. GPU asignada a VFIO: lspci -nnk | grep -A2 -i nvidia debe indicar Kernel driver in use: vfio-pci.
  3. Canales de RAM: lshw -c memory | grep -i channel debe listar “dual‑channel” o “quad‑channel” según la configuración.
  4. VM arranca con GPU: Dentro de la VM, ejecutar lspci | grep -i nvidia y comprobar que la GPU aparece.
  5. Rendimiento ZFS: zpool iostat -v y observar que el ARC no supera el límite configurado.

Notas adicionales

  • ACS override puede romper la seguridad de aislamiento de dispositivos. Úsalo solo cuando el hardware no permite separar grupos de IOMMU de forma nativa.
  • En entornos con PCIe 4.0, verifica que la ranura de la GPU está operando a la velocidad máxima (lspci -vvv -s 01:00.0 | grep LnkCap).
  • Si la workstation tiene ECC RAM, asegúrate de que la BIOS no desactiva ECC al habilitar el modo de canal mixto.
  • Para laboratorios de ciberseguridad que usan Kali o RustDesk, asignar la GPU solo a la VM que realmente la necesita reduce la carga térmica del host.
  • Mantén una copia de seguridad de la configuración de GRUB antes de editarla; un error puede dejar el host sin arranque.