Contenido
Proteger GPUs compartidas
Aislamiento, servicios expuestos y respuesta a incidentes
Los clústeres de GPU son compartidos, valiosos y están llenos de código que nadie auditó del todo, lo que los vuelve blancos atractivos. Este capítulo cubre cómo se comparten y aíslan las GPUs, cómo obtienen acceso los contenedores a los dispositivos y cómo ocurre y se contiene el abuso más común (minería no autorizada a través de un notebook expuesto). Todo aquí es defensivo.
6.1Contenedores y GPUs
Una imagen de contenedor trae el runtime de CUDA y las bibliotecas, pero el driver de la GPU debe venir del host (es un módulo del kernel). El NVIDIA Container Toolkit une ambos. Al iniciar, monta las bibliotecas de espacio de usuario del driver y los nodos de dispositivo /dev/nvidia* dentro del contenedor.
Reglas prácticas
- Fija las imágenes a una versión de CUDA que el driver del host soporte (ver pila CUDA).
- Los sitios de HPC suelen usar Enroot/Pyxis o Apptainer con Slurm. Ejecutan imágenes sin privilegios, una gran ventaja de seguridad.
- Nunca ejecutes contenedores de entrenamiento con
--privileged. El runtime debe dar acceso a dispositivos de forma acotada.
Ángulo de seguridad: los nodos de dispositivo son la GPU. Cualquier cosa que pueda abrir /dev/nvidia* fuera del control del planificador puede usar la GPU. Así es exactamente como un minero no autorizado se esconde a plena vista. Ver Cryptojacking en clústeres de GPU y multi-tenencia.
6.2Multi-tenencia y GPUs compartidas
Los clústeres compartidos deben decidir cómo comparten las GPUs los distintos inquilinos:
| Enfoque | Aislamiento | Bueno para |
|---|---|---|
| Asignación de GPU completa (forzada por el planificador) | Fuerte | Entrenamiento, cualquier cosa seria |
| Instancias MIG | Fuerte (memoria y SM particionados por hardware) | Inferencia, notebooks, CI |
| MPS (Multi-Process Service) | Débil: una falla en el espacio de direcciones compartido puede afectar a otros | Trabajos cooperativos de un mismo equipo |
| Time-slicing | Ninguno para la memoria; cambios de contexto | Solo desarrollo y pruebas |
Hacer cumplir importa más que la política. El planificador debe ser el único camino hacia una GPU: los controles de dispositivos de cgroups restringen /dev/nvidia* a procesos dentro de una asignación. Sin eso, cualquier usuario con shell en un nodo puede usar en silencio las GPUs libres. Ver Cryptojacking en clústeres de GPU.
Combínalo con cuentas de mínimo privilegio, sin usuarios de servicio compartidos, logs de auditoría y contabilidad por inquilino para que el uso sea visible y justo (ver Planificación fair-share).
6.3Multi-Instance GPU (MIG)
MIG (A100, H100 y posteriores) divide una GPU en hasta 7 instancias. Cada una recibe una porción dedicada de SM, caché L2 y HBM, con sus propios controladores de memoria. Las fallas y la presión de memoria de una instancia no afectan a otra, lo que hace de MIG la opción más fuerte para compartir GPU. Ver multi-tenencia.
Los perfiles se nombran por slices de cómputo y memoria; por ejemplo, en una H100 de 80 GB: 1g.10gb, 2g.20gb, 3g.40gb, 4g.40gb, 7g.80gb. No todas las combinaciones caben. La colocación sigue reglas fijas sobre qué slices pueden ir juntos.
Cuándo usarlo: inferencia, notebooks y cargas de CI que necesitan una fracción de GPU y no deben interferir entre sí. Cuándo no: trabajos de entrenamiento grandes. Esos quieren GPUs completas y NVLink, que las instancias MIG no pueden usar para comunicación peer-to-peer.
Juega con el particionador de abajo para ver cómo encajan los perfiles.
6.4Notebooks y paneles expuestos
Jupyter está diseñado para ejecutar código arbitrario: esa es la idea. Con --ip=0.0.0.0 y la autenticación desactivada (token y contraseña vacíos), cualquiera que alcance el puerto puede ejecutar comandos como el usuario del notebook. Lo mismo aplica a muchos paneles de ML, trackers de experimentos e interfaces de inferencia.
Patrones más seguros
- Escucha en
127.0.0.1y accede con un túnel SSH o un gateway autenticado (JupyterHub con SSO). - Nunca desactives tokens ni contraseñas. Usa TLS cuando el tráfico salga del host.
- Pon firewall a los nodos de cómputo: solo las redes del planificador, de monitoreo y de administración deberían alcanzarlos.
- Ejecuta los notebooks dentro de asignaciones del planificador, para que tengan límite de tiempo y queden contabilizados.
Cómo detectarlo: ss -tlnp muestra listeners en 0.0.0.0. Los logs del servidor registran solicitudes desde IP inesperadas. El monitoreo de red señala conexiones entrantes a nodos de cómputo desde afuera.
$ ss -tlnp
LISTEN 0 128 0.0.0.0:8888 0.0.0.0:* users:(("python3",pid=2741))6.5Cryptojacking en clústeres de GPU
Las GPUs son valiosas, y los atacantes que logran ejecutar código en un nodo de GPU muy a menudo simplemente minan criptomonedas. Puertas de entrada comunes:
- Servicios expuestos sin autenticación: notebooks, paneles e interfaces de herramientas de ML en
0.0.0.0(ver notebooks expuestos). - Credenciales y claves de API filtradas en imágenes, repositorios o scripts de trabajos (ver cadena de suministro y secretos).
- Contenedores con demasiados privilegios.
Señales de detección
- Una GPU ocupada sin ningún trabajo planificado: compara la utilización de DCGM con el estado del planificador.
- Nombres de procesos desconocidos en las GPUs (
nvidia-smi), a menudo disfrazados de hilos del kernel. - Conexiones salientes a pools de minería (protocolo stratum, puertos como 3333/4444) en
ss -tnpo en los logs del firewall. - Entradas nuevas de cron o unidades de systemd de usuarios inesperados.
Respuesta: preservar evidencia → matar el proceso → eliminar la persistencia → cerrar la puerta de entrada → bloquear o rotar las identidades afectadas → buscar movimiento lateral → reportar. Matar el proceso nunca es suficiente. La misión Night Shift lo hace concreto.
6.6Cadena de suministro y secretos
Un trabajo de entrenamiento incorpora mucho código ajeno: imágenes base, paquetes de Python, kernels personalizados, pesos preentrenados y datasets. Cada uno es parte de tu cadena de suministro.
Riesgos
- Imágenes con secretos incrustados (claves de nube, tokens) que puede leer cualquiera que las descargue.
- Archivos de modelo basados en pickle que pueden ejecutar código al cargarse. Prefiere
safetensors. - Dependencias sin fijar que cambian sin que te enteres.
Controles
- Fija las imágenes por digest, escanéalas y constrúyelas desde bases confiables.
- Inyecta los secretos en tiempo de ejecución desde un gestor de secretos, acotados por trabajo. Nunca en scripts
#SBATCH, archivos env en repositorios ni capas de imagen. - Credenciales de corta duración y mínimo privilegio para el acceso al almacenamiento.
- Verifica checksums o firmas de pesos y datasets.
Estos controles protegen tu clúster y también a las personas cuyos datos y modelos están a tu cargo.
Turno de noche
Una GPU está ocupada sin ningún trabajo planificado. Investiga, contén y elimina la persistencia.