Stack de monitorización: Prometheus, Grafana, DCGM y Loki para servidores de IA
Un servidor de IA que nadie vigila es un servidor que se limita térmicamente en silencio, pierde VRAM, acumula errores de ECC o muere a manos del OOM killer a las 03:00, y usted se entera tres días después, cuando alguien pregunta por qué su ajuste fino ha devuelto basura. Los peores modos de fallo de una máquina con GPU son invisibles desde la aplicación: el throttling térmico no escribe en stderr, las correcciones de ECC no provocan ningún fallo inmediato, el OOM killer se come un proceso y el orquestador lo reinicia limpiamente. Sin métricas del propio hardware no verá nada de esto hasta que ya le haya costado una semana.
El kit estándar de administración de sistemas (htop, df, uptime, syslog) no basta. La GPU es el componente más caro del chasis y el más propenso a fallar, y dispone de su propia pila de telemetría, que hay que conectar de forma explícita. Este artículo es nuestra propuesta razonada para esa pila —Prometheus, Grafana, DCGM-exporter, node_exporter, Loki y Alertmanager— empaquetada como un único despliegue docker-compose que ejecutamos en todos los servidores de IA de Kentino que entregamos.
Está dirigido a quien pone en marcha un servidor de IA de 4 u 8 GPU, sabe escribir un fichero docker-compose y quiere la respuesta a «qué debo monitorizar realmente y con qué umbral debo alarmar».
La pila estándar en 2026
Cinco componentes hacen casi todo el trabajo. Todo lo demás es un añadido.
| Componente | Función | Huella en reposo |
|---|---|---|
| Prometheus | Base de datos de series temporales + orquestador de scrape | ~150 MB RAM, ~3 MB/s |
| Grafana | Cuadros de mando, interfaz de alertas | ~120 MB RAM |
| DCGM-exporter | Métricas de GPU (temperatura, uso, potencia, memoria, ECC, XID) | ~30 MB RAM, <0.1% CPU |
| node_exporter | Métricas del sistema (CPU, RAM, disco, red, hwmon) | ~15 MB RAM |
| Loki + Promtail | Agregación de logs y agente de envío | ~100 MB RAM |
| Alertmanager | Enrutado de alertas (correo, Slack, PagerDuty, webhook) | ~25 MB RAM |
En total, muy por debajo del 0.5% de un núcleo de CPU en un EPYC de 96 núcleos y unos 700 MB de RAM. En un servidor de 256 GB y 8 GPU eso es un error de redondeo. El argumento de que «la monitorización roba ciclos al entrenamiento» dejó de ser cierto hacia 2019.
La única decisión de arquitectura que conviene tomar desde el principio: ejecute la pila en una VM de gestión aparte o en una máquina pequeña, no en el propio servidor GPU. Un mini-PC dedicado, un NUC, un nodo de servicio EPYC o una VM en el hipervisor del laboratorio: cualquier cosa que no sea la máquina con GPU. Por dos razones: cuando el servidor GPU se cae (kernel panic por falta de memoria, disparo de la fuente, apagado térmico) usted sigue queriendo el histórico de métricas para diagnosticar qué ocurrió, y no quiere que un entrenamiento desbocado compita con Prometheus por la memoria y dispare su propia alerta. DCGM-exporter y node_exporter se ejecutan en el host GPU (no queda otra: leen dispositivos locales); Prometheus, Grafana, Loki y Alertmanager se ejecutan en la VM de gestión y hacen scrape hacia dentro.
DCGM-exporter: lo único que no puede saltarse
El Data Center GPU Manager (DCGM) de NVIDIA es la fuente oficial y autorizada de telemetría de GPU. El contenedor dcgm-exporter expone las métricas de DCGM en formato Prometheus en el puerto 9400. Es el componente más importante de toda la pila y es justo lo que el sondeo con nvidia-smi nunca podrá sustituir.
Instálelo con el contenedor de NGC (nvcr.io/nvidia/k8s/dcgm-exporter, actualmente 4.x a mediados de 2026) o con el chart de Helm oficial para Kubernetes. Con Docker a secas basta un docker run --gpus all --rm; el demonio publica entonces unas 80 métricas en :9400/metrics. Las que de verdad importan, ordenadas por la frecuencia con que detectan problemas reales:
| Métrica | Qué le indica | Umbral de alarma |
|---|---|---|
DCGM_FI_DEV_GPU_TEMP |
Temperatura del núcleo de la GPU (°C) | > 80 °C aviso, 87 °C crítico |
DCGM_FI_DEV_MEMORY_TEMP |
Temperatura de la unión de memoria / VRAM (°C) | > 95 °C aviso, 105 °C crítico |
DCGM_FI_DEV_GPU_UTIL |
Uso de cómputo de los SM (%) | < 5% con VRAM asignada → proceso colgado |
DCGM_FI_DEV_FB_USED |
Frame buffer (VRAM) usado en MiB | > 95% del total |
DCGM_FI_DEV_POWER_USAGE |
Consumo instantáneo (W) | > TDP × 0.98 de forma sostenida |
DCGM_FI_DEV_PCIE_TX_THROUGHPUT |
Ancho de banda PCIe TX (KiB/s) | techo sostenido = regresión de riser o de líneas |
DCGM_FI_DEV_ECC_SBE_VOL_TOTAL |
Recuento de errores ECC corregibles | aumento de la tasa > 10× respecto a la base |
DCGM_FI_DEV_ECC_DBE_VOL_TOTAL |
Recuento de errores ECC no corregibles | cualquiera |
DCGM_FI_DEV_THERMAL_VIOLATION |
ns acumulados en throttling térmico | tasa > 0 |
DCGM_FI_DEV_POWER_VIOLATION |
ns acumulados en throttling por potencia | tasa > 0 |
DCGM_FI_DEV_XID_ERRORS |
Recuento de errores XID (fallos de driver / hardware) | cualquiera |
Los contadores de throttling son la gran baza. DCGM_FI_DEV_THERMAL_VIOLATION es un contador monótono de los nanosegundos que la GPU ha pasado limitada. Calcule su tasa en una ventana de 5 minutos y tendrá una respuesta exacta a «¿está mi servidor limitado térmicamente ahora mismo?». Sin él solo puede deducirlo de la temperatura, que engaña: una 4090 hará throttling a 83 °C con una carga sostenida, diga lo que diga el panel de temperatura.
Dos rarezas conocidas de DCGM-exporter que conviene tener presentes en 2026: algunos códigos XID (en especial el XID 62) no siempre se exponen a través de DCGM_FI_DEV_XID_ERRORS, y la métrica es un gauge del último XID visto, por lo que puede no reiniciarse tras una recuperación si no se reinicia el exporter. La mitigación consiste en vigilar además el búfer del kernel con Loki en busca de la cadena literal NVRM: Xid (más abajo lo vemos). Cinturón y tirantes.
En tarjetas puramente de consumo (RTX 4090, 5090) algunas funciones de centro de datos de DCGM están incompletas: no hay MIG, NVLink no existe en las Blackwell de consumo y ciertos contadores de ECC devuelven cero. DCGM sigue funcionando e informa de lo que está expuesto; la alternativa ligera de la comunidad nvidia_gpu_exporter (que consulta nvidia-smi) es un recambio viable si no quiere la cadena de dependencias de DCGM. Para las Pro 6000 Blackwell, L40 y L4 —cualquier producto de la línea profesional o de centro de datos— use DCGM, no el envoltorio.
node_exporter: la mitad del sistema
Las métricas de GPU solo cuentan la mitad de la historia. node_exporter cubre el resto:
| Familia de métricas | Por qué importa en una máquina de IA |
|---|---|
node_cpu_seconds_total |
Saturación de CPU: a los tokenizadores y dataloaders de vLLM les encanta la CPU |
node_memory_MemAvailable_bytes |
RAM del sistema: los flujos de entrenamiento e inferencia tienen fugas |
node_disk_io_time_seconds_total |
Saturación del NVMe: carga de datasets, escritura de checkpoints |
node_filesystem_avail_bytes |
Espacio en disco: cada juego de pesos ocupa entre 50 y 150 GB (ref. cruzada L04) |
node_network_receive_bytes_total |
Rendimiento de red: entrenamiento multinodo, clientes de inferencia |
node_load_average |
Indicador rápido de salud |
node_hwmon_temp_celsius |
Temperaturas de CPU y chipset, y de la fuente en algunas placas |
node_vmstat_oom_kill |
El OOM killer ha actuado: la alerta que más se olvida en cualquier despliegue |
El modo de fallo «se agota la RAM del sistema, el OOM killer se lleva vLLM, el contenedor se reinicia limpiamente» se detecta aquí, no con DCGM. Vigile node_memory_MemAvailable_bytes y alarme cuando baje del 5% del total. En Linux el killer actúa cerca del 0% por defecto, pero para entonces su proceso ya está muerto.
Prometheus: configuración, retención y dimensionado
Prometheus es la base de datos de series temporales y el orquestador de scrape. Sus valores por defecto son razonables; los dos ajustes que conviene cambiar el primer día son el intervalo de scrape y la retención.
Un intervalo de scrape de 15 segundos es el punto de partida correcto para un servidor de IA: lo bastante rápido para captar un pico térmico antes de que se convierta en throttling sostenido y lo bastante lento para que el coste en series temporales siga siendo modesto. La retención por defecto es de 15 días; 30 días es mejor cifra en el contexto de una guía de montaje, donde quizá quiera comparar el comportamiento de hoy con el cambio de ajuste del mes pasado.
Presupuesto de almacenamiento con scrape de 15 s, ~80 métricas DCGM × N GPU + ~400 métricas de node_exporter + ~50 métricas de vLLM: en torno a 1.5–2 GB por semana, de modo que 30 días quedan en 6–10 GB en una máquina de 8 GPU. Fije la retención por tiempo y por tamaño como salvaguarda:
command:
- "--storage.tsdb.retention.time=30d"
- "--storage.tsdb.retention.size=20GB"
Cualquiera de los dos límites dispara la compactación; manda el que se alcance primero. Con 100 GB asignados tendrá más de un año de margen sin pensarlo.
Cuadros de mando de Grafana: empiece por los prefabricados
No construya cuadros de mando desde cero. La comunidad ya lo ha hecho.
| Cuadro de mando | Grafana.com ID | Qué cubre |
|---|---|---|
| NVIDIA DCGM Exporter Dashboard | 12239 | El oficial de NVIDIA: todas las métricas de GPU |
| Node Exporter Full | 1860 | CPU / RAM / disco / red |
| Logs de Loki / Promtail | 13639 | Búsqueda y exploración de logs |
| Servicio con vLLM (comunidad) | varía | TTFT, TPOT, profundidad de cola, caché KV |
Importe primero el 12239 y el 1860. Cubren alrededor del 90% de lo que de verdad querrá mirar y llevan años puliéndose. Cree los suyos solo al cabo de un mes, cuando sepa qué paneles abre realmente. Las pequeñas modificaciones que merecen la pena para el hardware de IA de Kentino son: ajustar los paneles de umbral de temperatura de GPU a rangos apropiados para Blackwell (la 5090 hace throttling cerca de 87 °C y la RTX Pro 6000 más bien a 90 °C) y añadir un panel por ranura PCIe que muestre DCGM_FI_DEV_PCIE_LINK_GEN y DCGM_FI_DEV_PCIE_LINK_WIDTH para ver de un vistazo si un riser ha bajado de x16 a x8.
Loki: los logs que explican lo que muestran las métricas
Las métricas le dicen qué ha cambiado; los logs le dicen por qué. Loki es la base de datos de logs de Grafana; Promtail es el agente que sigue los ficheros y los envía. Apunte Promtail a:
-
/var/log/syslogyjournalctl -k— mensajes OOM del kernel, quejas del driver de NVIDIA, volcados XID -
/var/log/nvidia-installer.log— estado de la instalación del driver - La salida estándar del contenedor de vLLM (a través del driver de logs JSON de Docker)
- Los logs de aplicación de cualquier cosa que ejecute el cliente
La consulta más valiosa de la pestaña Explore de Grafana es:
{job="syslog"} |= "NVRM:"
Esto saca a la luz todos los mensajes del driver de NVIDIA en el búfer del kernel: errores XID, fallos de ventilador, eventos de tarjeta caída del bus, timeouts de RPC de GSP. Combínelo con la alerta de Prometheus sobre DCGM_FI_DEV_XID_ERRORS y tendrá la métrica estructurada y el detalle sin estructurar en el mismo panel.
Por defecto no enviamos los logs fuera del host. Loki los guarda en local con 30 días de retención; quien esté de guardia abre un túnel SSH hasta Grafana cuando hace falta. Los clientes que quieran logs centralizados de varios servidores pueden apuntar Loki a S3 o levantar una instancia regional: eso es una cuestión de despliegue, no de arquitectura.
Métricas de vLLM y SGLang: instrumente la aplicación, no solo el hierro
DCGM le dice que la GPU está ocupada. No le dice si las peticiones de inferencia responden en 200 ms o en 2 s. Para eso hay que instrumentar la capa de servicio.
vLLM expone /metrics de forma nativa en el mismo puerto que la API de OpenAI. Con la configuración por defecto, el endpoint :8000/metrics publica métricas de Prometheus con el prefijo vllm: (que pasa a ser vllm_ tras el scrape de Prometheus). Las que merece la pena recoger:
| Métrica de vLLM | Significado |
|---|---|
vllm:e2e_request_latency_seconds |
Latencia de la petición de extremo a extremo (histograma) |
vllm:time_to_first_token_seconds |
TTFT: la cifra que los usuarios realmente notan |
vllm:time_per_output_token_seconds |
Velocidad de generación de tokens (histograma) |
vllm:num_requests_running |
Peticiones activas en curso |
vllm:num_requests_waiting |
Profundidad de la cola |
vllm:gpu_cache_usage_perc |
Uso de la caché KV (0–1) |
vllm:request_prompt_tokens |
Distribución de la longitud del prompt |
La combinación de vllm:num_requests_waiting > 0 y DCGM_FI_DEV_GPU_UTIL < 90% significa que la cola se acumula mientras la GPU está ociosa: normalmente es un cuello de botella del tokenizador o del planificador, no de cómputo. Eso solo se ve con ambas métricas en el mismo cuadro de mando, que es justo el sentido de unificar la telemetría de aplicación y de hardware en un único Prometheus.
NVIDIA NIM expone las mismas métricas de vLLM en /v1/metrics sin renombrarlas, así que sus cuadros de mando y sus reglas de alerta de vLLM se trasladan sin cambios a un despliegue servido con NIM. SGLang publica un conjunto parecido en su propio puerto (30000 por defecto); el servidor HTTP de llama.cpp expone un subconjunto menor. Triton publica su propia taxonomía. Sirva lo que sirva, recoja métricas de la aplicación, no solo del hardware.
Reglas de Alertmanager: las que realmente entregamos
Los cuadros de mando son bonitos. Las alertas son útiles. Las reglas de abajo son las que han detectado problemas reales en hardware real de clientes.
groups:
- name: gpu
interval: 30s
rules:
- alert: GPUTempCritical
expr: DCGM_FI_DEV_GPU_TEMP > 87
for: 30s
labels: { severity: critical }
annotations:
summary: "GPU {{ $labels.gpu }} thermal critical ({{ $value }} °C)"
- alert: GPUThermalThrottling
expr: rate(DCGM_FI_DEV_THERMAL_VIOLATION[5m]) > 0
for: 1m
labels: { severity: warning }
- alert: GPUECCUncorrectable
expr: increase(DCGM_FI_DEV_ECC_DBE_VOL_TOTAL[10m]) > 0
labels: { severity: critical }
annotations:
summary: "GPU {{ $labels.gpu }} uncorrectable ECC — schedule replacement"
- alert: GPUXIDError
expr: increase(DCGM_FI_DEV_XID_ERRORS[5m]) > 0
labels: { severity: critical }
- alert: GPUPowerEnvelopeExceeded
expr: DCGM_FI_DEV_POWER_USAGE > 590 # 5090 nominal 575 W; alarma por encima del techo sostenido
for: 5m
labels: { severity: warning }
- alert: GPUIdleDuringWork
expr: DCGM_FI_DEV_GPU_UTIL < 5 and DCGM_FI_DEV_FB_USED > 1024
for: 10m
labels: { severity: warning }
annotations:
summary: "GPU {{ $labels.gpu }} idle with VRAM allocated — likely hung"
- name: system
interval: 30s
rules:
- alert: HostMemoryLow
expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) < 0.05
for: 2m
labels: { severity: critical }
- alert: OOMKillerFired
expr: increase(node_vmstat_oom_kill[5m]) > 0
labels: { severity: critical }
- alert: ContainerRestartLoop
expr: rate(container_start_time_seconds[15m]) > 3
for: 10m
labels: { severity: warning }
- name: serving
interval: 30s
rules:
- alert: vLLMQueueBacklog
expr: vllm:num_requests_waiting > 10
for: 5m
labels: { severity: warning }
- alert: vLLMHighLatency
expr: histogram_quantile(0.95, rate(vllm:e2e_request_latency_seconds_bucket[5m])) > 10
for: 5m
labels: { severity: warning }
Decisiones deliberadas de esas reglas:
- 87 °C como crítico para la temperatura de GPU. Una 5090 hace throttling en la franja alta de los 80 °C en la mayoría de los modelos. Si su sala no consigue mantener las tarjetas por debajo de 80 °C con carga sostenida, tiene un problema de climatización, no de software.
- Cualquier ECC no corregible avisa a quien está de guardia. Un solo evento ECC de doble bit invalida lo que hubiera en esa página de VRAM: un paso de entrenamiento queda mal, un resultado de inferencia queda mal. La tarjeta hay que sustituirla, no reiniciarla.
-
GPUIdleDuringWorkes el detector de bloqueos. > 1 GiB asignado y < 5% de uso durante 10 minutos significa que algo está atascado. Detecta cuelgues del lado de CUDA que la aplicación ignora tan tranquila. - La alerta del OOM killer es la regla que más se olvida en cualquier despliegue. Que Linux mate en silencio su trabajo de entrenamiento y que Docker lo reinicie limpiamente es el modo de fallo que más horas de ingeniería desperdicia al año. Hágala sonar fuerte.
- El bucle de reinicio de contenedores detecta los ciclos de reinicio de NIM y vLLM que desde fuera parecen sanos (el contenedor está «running») pero en realidad fallan en cada carga del modelo.
Chasis y almacenamiento: IPMI y SMART
DCGM se detiene en la GPU. node_exporter se detiene en el sistema operativo. El resto del chasis —ventiladores, fuentes, temperatura ambiente, salud del almacenamiento— necesita dos exporters más.
ipmi_exporter (prometheus-community) habla con el BMC por IPMI/RMCP y expone telemetría del chasis: rpm de cada ventilador, tensión y corriente de entrada de las fuentes, entradas del registro de eventos del sistema, temperatura ambiente de entrada y estado del watchdog del BMC. En un chasis Supermicro o Bone64c con un BMC operativo, esto es medio día de trabajo y detecta cosas que DCGM literalmente no puede ver: una fuente que falla en el montaje de 8 GPU con doble PSU aparece como una caída de tensión en los datos del sensor IPMI minutos antes de que una GPU salte con un XID 79. Ejecútelo en el host (necesita /dev/ipmi0) o en remoto con credenciales del BMC almacenadas, siguiendo el patrón de exporter multidestino.
smartctl_exporter (o el más antiguo smart_exporter) lee los atributos SMART de NVMe y SATA: indicador de desgaste del medio, reserva disponible, temperatura y recuentos de errores. Las cargas de trabajo de IA son brutales con los NVMe: los cargadores de datasets, las escrituras de checkpoints y las cachés de HuggingFace alcanzan en meses los objetivos de desgaste de nivel empresarial en unidades de consumo. Las métricas que hay que alarmar son nvme_available_spare cuando baja del 20% y nvme_percentage_used (el indicador de desgaste) cuando sube del 80%. El fallo de disco es el segundo fallo de hardware más común en un servidor de IA cargado de trabajo, tras la familia riser/PSU.
Un despliegue completo de monitorización de IA de Kentino incluye los dos. El coste marginal son minutos; el valor, la primera vez que un ventilador falla en silencio o que un Samsung 990 Pro alcanza su techo de DWPD, son horas.
Un docker-compose real para la VM de gestión
Lo que realmente desplegamos en la máquina de gestión. Ajuste host.docker.internal (o use el nombre de host o la IP del servidor GPU) para apuntar Prometheus a los puertos de los exporters del host GPU.
version: "3.8"
networks:
monitoring: { driver: bridge }
volumes:
prometheus_data:
grafana_data:
loki_data:
services:
prometheus:
image: prom/prometheus:v3.0.0
restart: unless-stopped
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./rules:/etc/prometheus/rules:ro
- prometheus_data:/prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention.time=30d"
- "--storage.tsdb.retention.size=20GB"
- "--web.enable-lifecycle"
ports: ["9090:9090"]
networks: [monitoring]
grafana:
image: grafana/grafana:11.4.0
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_PASSWORD__FILE=/run/secrets/grafana_pw
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning:ro
secrets: [grafana_pw]
ports: ["3000:3000"]
networks: [monitoring]
alertmanager:
image: prom/alertmanager:v0.28.0
restart: unless-stopped
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
ports: ["9093:9093"]
networks: [monitoring]
loki:
image: grafana/loki:3.3.0
restart: unless-stopped
command: -config.file=/etc/loki/loki.yml
volumes:
- ./loki.yml:/etc/loki/loki.yml:ro
- loki_data:/loki
ports: ["3100:3100"]
networks: [monitoring]
secrets:
grafana_pw: { file: ./secrets/grafana_pw.txt }
En el propio host GPU (compose aparte, en el servidor GPU):
services:
dcgm-exporter:
image: nvcr.io/nvidia/k8s/dcgm-exporter:4.5.1-4.8.0-ubuntu22.04
restart: unless-stopped
runtime: nvidia
environment: [NVIDIA_VISIBLE_DEVICES=all]
cap_add: [SYS_ADMIN]
ports: ["9400:9400"]
node-exporter:
image: prom/node-exporter:v1.9.0
restart: unless-stopped
pid: host
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- "--path.procfs=/host/proc"
- "--path.sysfs=/host/sys"
- "--path.rootfs=/rootfs"
ports: ["9100:9100"]
ipmi-exporter:
image: prometheuscommunity/ipmi-exporter:v1.10.0
restart: unless-stopped
privileged: true
volumes: ["/dev/ipmi0:/dev/ipmi0"]
ports: ["9290:9290"]
smartctl-exporter:
image: prometheuscommunity/smartctl-exporter:v0.13.0
restart: unless-stopped
privileged: true
ports: ["9633:9633"]
promtail:
image: grafana/promtail:3.3.0
restart: unless-stopped
volumes:
- /var/log:/var/log:ro
- ./promtail.yml:/etc/promtail/promtail.yml:ro
command: -config.file=/etc/promtail/promtail.yml
La configuración de scrape de Prometheus en la VM de gestión:
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- /etc/prometheus/rules/*.yml
alerting:
alertmanagers:
- static_configs:
- targets: ["alertmanager:9093"]
scrape_configs:
- job_name: dcgm
static_configs:
- targets: ["k-ai-01.lan:9400", "k-ai-02.lan:9400"]
- job_name: node
static_configs:
- targets: ["k-ai-01.lan:9100", "k-ai-02.lan:9100"]
- job_name: ipmi
static_configs:
- targets: ["k-ai-01.lan:9290", "k-ai-02.lan:9290"]
- job_name: smart
static_configs:
- targets: ["k-ai-01.lan:9633", "k-ai-02.lan:9633"]
- job_name: vllm
metrics_path: /metrics
static_configs:
- targets: ["k-ai-01.lan:8000"]
Esa es una pila funcional para un laboratorio de uno a tres servidores. Pasados cuatro o cinco servidores, cambie la configuración de scrape de Prometheus a descubrimiento de servicios basado en ficheros o —si está en Kubernetes— al chart de Helm de DCGM-exporter incluido en el GPU Operator y a los CRD ServiceMonitor del Prometheus Operator.
OpenTelemetry, Pixie, eBPF: el panorama en 2026
Una nota sobre las piezas en movimiento, porque la pregunta siempre sale.
OpenTelemetry es el estándar de la CNCF para la instrumentación de observabilidad y, desde principios de 2026, los tres tipos de señal (métricas, trazas y logs) son estables. El pipeline del OTel Collector está sustituyendo a los agentes propietarios en muchas organizaciones como enrutador universal de telemetría. Para un servidor de IA, la respuesta pragmática en 2026 es: conserve Prometheus para las métricas (DCGM-exporter y node_exporter hablan Prometheus de forma nativa y sus reglas de alerta están escritas en PromQL) y añada un OTel Collector si llega a necesitar trazas distribuidas a lo largo de un grafo de servicio de inferencia (petición → pasarela de API → vLLM → llamada a herramienta → base de datos vectorial → respuesta). En una instalación de un solo servidor con un modelo detrás de nginx, OTel añade coste sin aportar valor. El 71% de organizaciones que «usan ambos» utilizan Prometheus para el hierro y OTel para las trazas de aplicación: un reparto sensato.
Pixie es una herramienta de observabilidad nativa de Kubernetes que usa eBPF para recoger métricas, trazas y logs a nivel de kernel sin tocar el código. El avance de 2026 que merece seguimiento es el trabajo de eBPF sobre GPU (bpftime, eGPU, los módulos de kernel abiertos de NVIDIA), que extiende la instrumentación eBPF a los kernels de GPU mediante inyección de PTX en tiempo de ejecución. Hoy está en fase de investigación y no forma parte de ninguna pila de producción que entreguemos. Por ahora, DCGM es la respuesta soportada.
El perfilado continuo (Grafana Phlare, Pyroscope) es un tercer añadido que conviene conocer. En cargas de inferencia en las que usted controla el código del framework (parches propios de vLLM, optimizaciones del tokenizador) le dice qué funciones queman la CPU. Para servir modelos sin más con contenedores estándar, es excesivo.
Qué se rompe (edición monitorización)
Modos de fallo previsibles de la propia pila, ordenados por la frecuencia con que muerden:
- El disco de Prometheus se llena. La retención por defecto es de 15 días; nosotros ponemos 30 con un techo de 20 GB. A partir de 60 días en una máquina cargada, cuente con decenas de GB. Fije la retención por tiempo y por tamaño.
-
DCGM-exporter pierde las GPU tras actualizar el driver. Síntoma: todos los paneles de GPU se quedan en blanco. Solución: reinicie el contenedor y vuelva a ejecutar
nvidia-ctk runtime configuresi el runtime ha cambiado de sitio. -
Alertmanager no está configurado con el receptor que de verdad usa. La gente levanta Prometheus y Grafana, se olvida de apuntar Alertmanager al correo o a Slack y descubre seis meses después que nunca saltó ninguna alerta. Pruébelo disparando a propósito
GPUTempCriticalcon una carga de estrés, o useamtool alert addpara lanzar una alerta sintética el primer día. -
Explosión de cardinalidad por etiquetas por petición. No etiquete las métricas de vLLM con
user_idnirequest_id. Prometheus no está diseñado para eso: agotará la memoria de la base de datos. -
Fuga de la contraseña de Grafana por el entorno de compose. Use secretos de Docker, no
GF_SECURITY_ADMIN_PASSWORDen el bloque de entorno.docker inspecty los logs filtran los valores del entorno. -
El gauge de XID que no se reinicia. Como se ha dicho, el gauge de XID de DCGM-exporter puede quedarse con el último valor visto tras una recuperación. Combine la métrica con el seguimiento de
NVRM:en syslog desde Loki para evitar una falsa confianza.
La valoración honesta
La mayoría de los laboratorios instalan Grafana una vez, construyen un cuadro de mando que el equipo admira durante una semana y no vuelven a mirarlo. El cuadro de mando es un artefacto satisfactorio; no es lo que detecta sus problemas. Lo que detecta sus problemas son las alertas. Configure Alertmanager con un receptor real (correo, Slack, PagerDuty) y un pequeño conjunto de reglas de alta precisión —temperatura de GPU, ECC de doble bit, XID, OOM killer, bucle de reinicio de contenedores— y ajústelas hasta que solo salten cuando algo va realmente mal. Haga esto primero. Después construya cuadros de mando para la investigación posterior al incidente.
La otra mitad de la valoración honesta: a escala de un solo servidor Kentino, esta pila le dará una alerta quizá una vez al mes y la mayoría de los meses será un falso positivo que acabará ignorando. Eso es el sistema funcionando. El valor está en la alerta que salta el día en que un riser empieza a cocerse, dos días antes de que la tarjeta salte con un XID 79, cuando todavía hay tiempo de reasentar un cable en lugar de tramitar el RMA de una GPU. Ese único suceso paga todo el esfuerzo de monitorización, y lo paga con creces.
Qué hacer a continuación
Para un servidor construido por Kentino que entra en producción esta semana:
-
Levante la VM de gestión o el nodo de servicio. Con una máquina de 4 núcleos y 8 GB sobra. Instale Docker. Despliegue el compose de
prometheus + grafana + alertmanager + lokide más arriba. -
En el host GPU, instale
nvidia-container-toolkit(según L02) y compruebe quedocker run --rm --gpus all nvidia/cuda:13.0.0-base-ubuntu24.04 nvidia-smifunciona. -
Despliegue
dcgm-exporter,node-exporter,ipmi-exporter,smartctl-exporterypromtailen el host GPU. Compruebe que cada endpoint/metricsdevuelve datos. -
Apunte Prometheus a los cinco targets de exporter y a su endpoint
/metricsde vLLM. Recargue (curl -X POST :9090/-/reload). - Importe los cuadros de mando 12239 y 1860 de Grafana. Compruebe que los paneles de GPU y de sistema se rellenan.
-
Conecte Alertmanager a su receptor de correo o de Slack. Lance una alerta sintética con
amtool. Si la alerta de prueba no llega, tampoco llegará ninguna real. -
Ejecute una carga de estrés (
gpu-burndurante una hora, o un entrenamiento real) y vigile los cuadros de mando. Aquí es donde descubrirá que su sala no consigue mantener las GPU por debajo de 80 °C, que su NVMe es el cuello de botella o que su caché KV se queda corta: todo ello más fácil de arreglar el primer día que en la tercera semana.
Artículos complementarios: L01 sobre la fijación de versiones del driver, L02 sobre CUDA y el runtime de contenedores, L03 sobre el ajuste del kernel, L04 sobre la elección del sistema de ficheros.
Primero monitorizar. Después ajustar. Todo lo demás es adivinar.
Esto forma parte de la Kentino Wiki, una serie de referencia sobre computación de IA, robótica y los sistemas que los conectan. Comentarios y correcciones son bienvenidos en info@kentino.com.