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/syslog y journalctl -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.
  • GPUIdleDuringWork es 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 configure si 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 GPUTempCritical con una carga de estrés, o use amtool alert add para 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_id ni request_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_PASSWORD en el bloque de entorno. docker inspect y 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:

  1. 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 + loki de más arriba.
  2. En el host GPU, instale nvidia-container-toolkit (según L02) y compruebe que docker run --rm --gpus all nvidia/cuda:13.0.0-base-ubuntu24.04 nvidia-smi funciona.
  3. Despliegue dcgm-exporter, node-exporter, ipmi-exporter, smartctl-exporter y promtail en el host GPU. Compruebe que cada endpoint /metrics devuelve datos.
  4. Apunte Prometheus a los cinco targets de exporter y a su endpoint /metrics de vLLM. Recargue (curl -X POST :9090/-/reload).
  5. Importe los cuadros de mando 12239 y 1860 de Grafana. Compruebe que los paneles de GPU y de sistema se rellenan.
  6. 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.
  7. Ejecute una carga de estrés (gpu-burn durante 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.