Introducción
Esta guía describe cómo habilitar y utilizar GPUs NVIDIA en tres escenarios distintos: servidores físicos (bare metal), contenedores Docker y clústeres Kubernetes. El sistema operativo de referencia es Linux, pero los principios aplican a otros fabricantes de GPU con ajustes menores.
Resumen de componentes necesarios por entorno:
- Bare Metal: GPU Driver + CUDA Toolkit
- Docker: NVIDIA Container Toolkit + configuración del runtime
- Kubernetes: NVIDIA Device Plugin + opcionalmente DCGM Exporter para monitoreo
En entornos Kubernetes productivos se suele emplear gpu-operator, pero aquí se realiza la instalación manual para comprender el rol de cada componente.
- Configuración en Bare Metal
Para utilizar una GPU directamente en el sistema operativo, se requieren dos componentes fundamentales: el GPU Driver (que incluye el driver de dispositivo y el CUDA driver) y el CUDA Toolkit (que provee el CUDA Runtime y herramientas de desarrollo).
Verificación del hardware
La GPU es un dispositivo PCIe. Verifica su presencia con:
lspci | grep -i nvidia
Salida esperada (ejemplo con dos Tesla T4):
3b:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1)
86:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1)
Instalación del GPU Driver
Descarga el driver correspondiente desde el portal de NVIDIA. El archivo resultante tiene extensión .run. Ejecútalo directamente:
bash ./NVIDIA-Linux-x86_64-550.54.14.run
Sigue el asistente interactivo aceptando las opciones predeterminadas. Verifica la instalación con:
nvidia-smi
Si la salida muestra la tabla de GPUs con sus características (temperatura, memoria, versión de driver y CUDA soportada), la instalación fue exitosa. La versión de CUDA indicada en la parte superior representa la máxima versión compatible con el driver instalado.
Instalación del CUDA Toolkit
Descarga el instalador desde la página oficial de CUDA Toolkit. Selecciona tu sistema operativo y arquitectura. El archivo descargado también es un .run:
wget https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.run
sudo bash cuda_12.2.0_535.54.03_linux.run --toolkit --silent
Nota: Si ya instalaste el driver, omite su reinstalación usando el flag --toolkit.
Tras la instalación, configura las variables de entorno:
echo 'export PATH=/usr/local/cuda-12.2/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc
Confirma con:
nvcc --version
La salida debe mostrar la versión del compilador CUDA instalada.
Prueba funcional con PyTorch
Para validar que el stack GPU-CUDA funciona correctamente, usamos un script de prueba en Python:
import torch
def verificar_entorno_cuda():
disponibilidad = torch.cuda.is_available()
if not disponibilidad:
print("No se detectó CUDA disponible.")
return
version_cuda = torch.version.cuda
version_torch = torch.__version__
total_dispositivos = torch.cuda.device_count()
print(f"Versión de CUDA detectada: {version_cuda}")
print(f"Versión de PyTorch: {version_torch}")
print(f"GPUs accesibles: {total_dispositivos}")
for idx in range(total_dispositivos):
props = torch.cuda.get_device_properties(idx)
nombre_gpu = props.name
memoria_total_gb = props.total_memory / (1024 ** 3)
memoria_asignada_gb = torch.cuda.memory_allocated(idx) / (1024 ** 3)
memoria_reservada_gb = torch.cuda.memory_reserved(idx) / (1024 ** 3)
print(f"[GPU {idx}] Modelo: {nombre_gpu}")
print(f"[GPU {idx}] VRAM total: {memoria_total_gb:.2f} GB")
print(f"[GPU {idx}] VRAM en uso: {memoria_asignada_gb:.2f} GB")
print(f"[GPU {idx}] VRAM reservada: {memoria_reservada_gb:.2f} GB")
if __name__ == "__main__":
verificar_entorno_cuda()
Instala PyTorch y ejecuta el script:
pip install torch
python verificar_entorno_cuda.py
La salida confirmará que PyTorch reconoce las GPUs y puede acceder a la memoria de video.
- Acceso a GPU en Contenedores Docker
Para que un contenedor Docker pueda utilizar la GPU del host, se necesita el NVIDIA Container Toolkit, que actúa como intermediario entre el runtime de contenedores y los dispositivos GPU del host.
Instalación de NVIDIA Container Toolkit
En sistemas basados en Debian/Ubuntu:
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor -o /usr/share/keyrings/nvidia.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia.gpg] https://#g' \
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
Configuración del runtime de Docker
La herramienta nvidia-ctk genera automáticamente la configuración necesaria:
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
Esto modifica /etc/docker/daemon.json para registrar nvidia-container-runtime como runtime disponible.
Verificación en contenedor
Lanza un contenedor con soporte GPU usando el flag --gpus:
docker run --rm --gpus all nvidia/cuda:12.0.1-runtime-ubuntu22.04 nvidia-smi
Para asignar GPUs específicas por índice:
docker run --rm --gpus '"device=0,1"' nvidia/cuda:12.0.1-runtime-ubuntu22.04 nvidia-smi
La salida mostrará las GPUs visibles desde dentro del contenedor. No es necesario tener CUDA Toolkit instalado en el host, ya que se incluye dentro de la imagen del cnotenedor.
- GPUs en Kubernetes
En un clúster de Kubernetes, la gestión de GPUs requiere un componente adicional: el NVIDIA Device Plugin, que se ejecuta como DaemonSet en cada nodo con GPU y registra los dispositivos ante el kubelet local. Esto permite que el scheduler de Kubernetes conozca la capacidad GPU de cada nodo.
Flujo de asignación de GPU
- El kubelet de cada nodo reporta sus dispositivos GPU disponibles al API server.
- El scheduler selecciona un nodo con GPUs suficientes para el Pod.
- El kubelet asigna IDs de GPU específicos y los pasa al Device Plugin de NVIDIA.
- El Device Plugin inyecta la variable de entorno
NVIDIA_VISIBLE_DEVICESen el spec del contenedor. - Al iniciar el contenedor, NVIDIA Container Toolkit interpreta esta variable y monta únicamente las GPUs asignadas.
Despliegue del Device Plugin
Aplica el manifiesto oficial:
kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.15.0/deployments/static/nvidia-device-plugin.yml
Verifica que el DaemonSet esté activo:
kubectl get pods -l app=nvidia-device-plugin-daemonset -A
Tras su arranque, el nodo reportará el recurso extendido nvidia.com/gpu:
kubectl describe node <nombre-nodo> | grep -A10 "Capacity"
Entre los recursos listados aparecerá nvidia.com/gpu: 2 (o el número de GPUs presentes).
Monitoreo con DCGM Exporter
Para exponer métricas de GPU a Prometheus, instala dcgm-exporter mediante Helm:
helm repo add nvidia-dcgm https://nvidia.github.io/dcgm-exporter/helm-charts
helm repo update
helm install dcgm-exporter nvidia-dcgm/dcgm-exporter
Las métricas se publican en el puerto 8080 del Pod:
kubectl port-forward svc/dcgm-exporter 8080:8080
curl http://localhost:8080/metrics
Esto expone indicadores como DCGM_FI_DEV_SM_CLOCK, DCGM_FI_DEV_MEM_CLOCK y DCGM_FI_DEV_MEMORY_TEMP, etiquetados por GPU, namespace y Pod.
Pod de prueba solicitando GPU
Crea un Pod que solicite recursos GPU en resources.limits:
apiVersion: v1
kind: Pod
metadata:
name: prueba-vectoradd-gpu
labels:
app: test-cuda
spec:
restartPolicy: OnFailure
containers:
- name: contenedor-cuda
image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2
resources:
limits:
nvidia.com/gpu: 1
Aplica y consulta los logs:
kubectl apply -f prueba-gpu.yaml
kubectl logs pod/prueba-vectoradd-gpu
La salida esperada confirma que la operación vectorial en GPU se completó correctamente:
[Vector addition of 50000 elements]
Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Copy output data from the CUDA device to the host memory
Test PASSED
Done
Con esto, el clúster Kubernetes puede programar Pods que requieran GPUs de forma transparente, gestionando la asignación de dispositivos automáticamente mediante el Device Plugin.