Monitoring-Stack: Prometheus, Grafana, DCGM, Loki für KI-Server
Ein KI-Server, den niemand beobachtet, ist ein Server, der still und leise drosselt, VRAM verliert, ECC-Fehler ansammelt oder um 03:00 Uhr vom OOM-Killer erwischt wird – und Sie erfahren davon drei Tage später, wenn jemand fragt, warum sein Fine-Tuning Unsinn produziert hat. Die schlimmsten Fehlerbilder einer GPU-Maschine sind aus der Anwendung heraus unsichtbar: Thermisches Drosseln landet nicht auf stderr, korrigierte ECC-Fehler lassen nichts sofort abstürzen, der OOM-Killer frisst einen Prozess und der Orchestrator startet ihn sauber neu. Ohne Metriken von der Hardware selbst sehen Sie nichts davon – bis es Sie bereits eine Woche gekostet hat.
Das übliche Sysadmin-Besteck (htop, df, uptime, syslog) reicht dafür nicht. Die GPU ist die teuerste Komponente im Gehäuse und zugleich die ausfallanfälligste, und sie bringt einen eigenen Telemetrie-Stack mit, der bewusst verkabelt werden will. Dieser Artikel beschreibt den Aufbau, den wir dafür empfehlen – Prometheus, Grafana, DCGM-Exporter, node_exporter, Loki und Alertmanager – gebündelt als ein einziges docker-compose-Deployment, das auf jedem von uns ausgelieferten Kentino KI-Server läuft.
Geschrieben ist er für alle, die einen KI-Server mit 4 oder 8 GPUs in Betrieb nehmen, eine docker-compose-Datei schreiben können und eine Antwort auf die Frage suchen: „Was sollte ich tatsächlich überwachen – und ab welchem Schwellenwert alarmieren?“
Der Standard-Stack im Jahr 2026
Fünf Komponenten erledigen praktisch die gesamte Arbeit. Alles Weitere ist Beiwerk.
| Komponente | Aufgabe | Bedarf im Leerlauf |
|---|---|---|
| Prometheus | Zeitreihendatenbank + Scrape-Orchestrierung | ~150 MB RAM, ~3 MB/s |
| Grafana | Dashboards, Alarm-Oberfläche | ~120 MB RAM |
| DCGM-exporter | GPU-Metriken (Temperatur, Auslastung, Leistung, Speicher, ECC, XID) | ~30 MB RAM, <0.1% CPU |
| node_exporter | Systemmetriken (CPU, RAM, Datenträger, Netzwerk, hwmon) | ~15 MB RAM |
| Loki + Promtail | Log-Aggregation und -Versand | ~100 MB RAM |
| Alertmanager | Alarmverteilung (E-Mail, Slack, PagerDuty, Webhook) | ~25 MB RAM |
In Summe deutlich unter 0.5 % eines CPU-Kerns auf einem 96-Kern-EPYC und rund 700 MB RAM. Auf einem Server mit 256 GB und 8 GPUs ist das ein Rundungsfehler. Das Argument „Monitoring stiehlt dem Training Rechenzeit“ hat etwa 2019 aufgehört zu stimmen.
Eine architektonische Entscheidung lohnt sich gleich zu Beginn: Betreiben Sie den Stack auf einer separaten Management-VM oder einem kleinen Rechner, nicht auf dem GPU-Server selbst. Ein dedizierter Mini-PC, ein NUC, ein EPYC-Service-Knoten oder eine VM auf dem Labor-Hypervisor – Hauptsache nicht die GPU-Maschine. Dafür gibt es zwei Gründe: Wenn der GPU-Server abstürzt (Kernel-Panic wegen Speichermangel, ausgelöstes Netzteil, thermische Abschaltung), wollen Sie die Metrik-Historie noch haben, um die Ursache zu finden – und Sie wollen nicht, dass ein außer Kontrolle geratener Trainingsjob mit Prometheus um den Arbeitsspeicher konkurriert und dadurch selbst einen Alarm auslöst. DCGM-Exporter und node_exporter laufen auf dem GPU-Host (anders geht es nicht, sie lesen lokale Geräte aus); Prometheus, Grafana, Loki und Alertmanager laufen auf der Management-VM und greifen von dort zu.
DCGM-Exporter – die eine Komponente, auf die Sie nicht verzichten können
Der Data Center GPU Manager (DCGM) von NVIDIA ist die offiziell unterstützte, maßgebliche Quelle für GPU-Telemetrie. Der Container dcgm-exporter stellt DCGM-Metriken im Prometheus-Format auf Port 9400 bereit. Er ist die mit Abstand wichtigste Komponente des Stacks – und genau das, was sich durch periodisches Abfragen von nvidia-smi niemals ersetzen lässt.
Installieren Sie ihn über den NGC-Container (nvcr.io/nvidia/k8s/dcgm-exporter, Stand Mitte 2026 in Version 4.x) oder über das offizielle Helm-Chart für Kubernetes. Unter reinem Docker genügt ein docker run --gpus all --rm ; der Daemon veröffentlicht dann rund 80 Metriken unter :9400/metrics. Die Metriken, auf die es wirklich ankommt – sortiert danach, wie oft sie echte Probleme aufdecken:
| Metrik | Was sie Ihnen sagt | Alarmschwelle |
|---|---|---|
DCGM_FI_DEV_GPU_TEMP |
GPU-Kerntemperatur (°C) | > 80 °C Warnung, 87 °C kritisch |
DCGM_FI_DEV_MEMORY_TEMP |
Temperatur am VRAM / Memory Junction (°C) | > 95 °C Warnung, 105 °C kritisch |
DCGM_FI_DEV_GPU_UTIL |
Auslastung der Recheneinheiten (%) | < 5 % bei belegtem VRAM → hängender Prozess |
DCGM_FI_DEV_FB_USED |
Belegter Framebuffer (VRAM) in MiB | > 95 % der Gesamtkapazität |
DCGM_FI_DEV_POWER_USAGE |
Aktuelle Leistungsaufnahme (W) | dauerhaft > TDP × 0.98 |
DCGM_FI_DEV_PCIE_TX_THROUGHPUT |
PCIe-Sendebandbreite (KiB/s) | dauerhaft am Limit = Rückstufung von Riser oder Lanes |
DCGM_FI_DEV_ECC_SBE_VOL_TOTAL |
Zahl der korrigierbaren ECC-Fehler | Anstieg der Rate > 10× über Normalwert |
DCGM_FI_DEV_ECC_DBE_VOL_TOTAL |
Zahl der nicht korrigierbaren ECC-Fehler | jeder Wert |
DCGM_FI_DEV_THERMAL_VIOLATION |
Kumulierte Nanosekunden im thermischen Drosselbetrieb | Rate > 0 |
DCGM_FI_DEV_POWER_VIOLATION |
Kumulierte Nanosekunden im leistungsbedingten Drosselbetrieb | Rate > 0 |
DCGM_FI_DEV_XID_ERRORS |
Zahl der XID-Fehler (Treiber- bzw. Hardwarefehler) | jeder Wert |
Die Drossel-Zähler sind das eigentliche Highlight. DCGM_FI_DEV_THERMAL_VIOLATION ist ein monoton steigender Zähler der Nanosekunden, die die GPU im Drosselbetrieb verbracht hat. Berechnen Sie dessen Rate über ein Fünf-Minuten-Fenster, und Sie haben eine exakte Antwort auf die Frage „Ist mein Server gerade thermisch limitiert?“ Ohne diesen Wert raten Sie anhand der Temperatur allein – und die trügt: Eine 4090 drosselt unter Dauerlast bei 83 °C, ganz gleich, was das Temperatur-Panel anzeigt.
Zwei bekannte Eigenheiten des DCGM-Exporters sollten Sie 2026 kennen: Manche XID-Codes (vor allem XID 62) tauchen nicht zuverlässig in DCGM_FI_DEV_XID_ERRORSauf, und die Metrik ist ein Gauge des zuletzt gesehenen XID – sie setzt sich nach einer Erholung also unter Umständen erst zurück, wenn Sie den Exporter neu starten. Als Gegenmittel beobachten Sie zusätzlich über Loki den Kernel-Ringpuffer auf die Zeichenfolge NVRM: Xid (dazu gleich mehr). Doppelt gesichert hält besser.
Bei reinen Consumer-Karten (RTX 4090, 5090) stehen manche Data-Center-Funktionen von DCGM nur teilweise zur Verfügung – MIG fehlt, NVLink gibt es bei Blackwell-Consumer-Modellen nicht, bestimmte ECC-Zähler liefern null. DCGM funktioniert trotzdem und meldet, was die Karte offenlegt; die schlanke Community-Alternative nvidia_gpu_exporter (die nvidia-smiausliest) ist ein brauchbarer Rückfallplan, wenn Sie sich die Abhängigkeitskette von DCGM sparen möchten. Für Pro 6000 Blackwell, L40 und L4 – also alles aus der Data-Center- und Pro-Linie – nehmen Sie DCGM, nicht den Wrapper.
node_exporter – die Systemhälfte
GPU-Metriken erzählen nur die halbe Geschichte. node_exporter deckt den Rest ab:
| Metrikfamilie | Warum sie auf einer KI-Maschine zählt |
|---|---|
node_cpu_seconds_total |
CPU-Sättigung – vLLM-Tokenizer und Dataloader lieben CPU-Zeit |
node_memory_MemAvailable_bytes |
System-RAM – Trainings- und Inferenz-Workflows verlieren Speicher |
node_disk_io_time_seconds_total |
NVMe-Sättigung – Dataset-Loader, Checkpoint-Schreibvorgänge |
node_filesystem_avail_bytes |
Speicherplatz – Modellgewichte belegen je 50–150 GB (siehe auch L04) |
node_network_receive_bytes_total |
Netzwerkdurchsatz – Multi-Node-Training, Inferenz-Clients |
node_load_average |
Schneller Indikator für den Allgemeinzustand |
node_hwmon_temp_celsius |
CPU- und Chipsatztemperaturen, auf manchen Boards auch Netzteiltemperaturen |
node_vmstat_oom_kill |
OOM-Killer hat zugeschlagen – der am häufigsten übersehene Alarm überhaupt |
Das Fehlerbild „System-RAM erschöpft, OOM-Killer holt sich vLLM, Container startet sauber neu“ fangen Sie hier ab, nicht mit DCGM. Beobachten Sie node_memory_MemAvailable_bytes und alarmieren Sie, sobald der Wert unter 5 % der Gesamtkapazität fällt. Unter Linux greift der Killer standardmäßig erst nahe 0 % – dann ist Ihr Prozess aber längst tot.
Prometheus – Konfiguration, Aufbewahrung, Dimensionierung
Prometheus ist die Zeitreihendatenbank und zugleich die Scrape-Orchestrierung. Die Voreinstellungen sind vernünftig; die beiden Einstellungen, die Sie am ersten Tag ändern sollten, sind Scrape-Intervall und Aufbewahrungsdauer.
Ein Scrape-Intervall von 15 Sekunden ist für einen KI-Server der richtige Ausgangspunkt: schnell genug, um eine Temperaturspitze zu erwischen, bevor daraus dauerhaftes Drosseln wird, und langsam genug, dass der Aufwand für die Zeitreihen überschaubar bleibt. Die Aufbewahrung steht standardmäßig auf 15 Tage; 30 Tage sind die bessere Zahl, wenn Sie das Verhalten von heute mit der Tuning-Änderung vom Vormonat vergleichen wollen.
Speicherbedarf bei 15 s Scrape-Intervall, rund 80 DCGM-Metriken × N GPUs + rund 400 node_exporter-Metriken + rund 50 vLLM-Metriken: etwa 1.5–2 GB pro Woche, 30 Tage landen also bei 6–10 GB auf einer Maschine mit 8 GPUs. Setzen Sie die Aufbewahrung zur Sicherheit sowohl zeitlich als auch nach Größe:
command:
- "--storage.tsdb.retention.time=30d"
- "--storage.tsdb.retention.size=20GB"
Beide Grenzen lösen eine Verdichtung aus; es gilt, was zuerst erreicht wird. Mit 100 GB Zuweisung haben Sie über ein Jahr Reserve, ohne weiter darüber nachzudenken.
Grafana-Dashboards – fangen Sie mit den fertigen an
Bauen Sie Dashboards nicht von Grund auf neu. Die Community hat das längst erledigt.
| Dashboard | ID auf Grafana.com | Was es abdeckt |
|---|---|---|
| NVIDIA DCGM Exporter Dashboard | 12239 | Das offizielle von NVIDIA – sämtliche GPU-Metriken |
| Node Exporter Full | 1860 | CPU / RAM / Datenträger / Netzwerk |
| Loki / Promtail Logs | 13639 | Logsuche und -analyse |
| vLLM-Serving (Community) | unterschiedlich | TTFT, TPOT, Queue-Tiefe, KV-Cache |
Importieren Sie zuerst 12239 und 1860. Sie decken rund 90 % dessen ab, was Sie tatsächlich ansehen wollen, und sind über Jahre verfeinert worden. Bauen Sie Eigenes erst nach einem Monat, wenn Sie wissen, welche Panels Sie wirklich öffnen. Für Kentino KI-Hardware lohnen sich zwei kleine Anpassungen: die Schwellenwert-Panels für die GPU-Temperatur auf Blackwell-typische Bereiche setzen (5090 drosselt nahe 87 °C, RTX Pro 6000 eher bei 90 °C) und ein Panel je PCIe-Steckplatz ergänzen, das DCGM_FI_DEV_PCIE_LINK_GEN und DCGM_FI_DEV_PCIE_LINK_WIDTH zeigt – so sehen Sie auf einen Blick, ob ein Riser von x16 auf x8 zurückgefallen ist.
Loki – Logs, die erklären, was die Metriken zeigen
Metriken sagen Ihnen, was sich geändert hat; Logs sagen Ihnen, warum. Loki ist die Log-Datenbank von Grafana, Promtail der Agent, der Dateien mitliest und weiterschickt. Richten Sie Promtail auf:
-
/var/log/syslogundjournalctl -k– Kernel-OOM-Meldungen, Meldungen des NVIDIA-Treibers, XID-Dumps -
/var/log/nvidia-installer.log– Status der Treiberinstallation - stdout des vLLM-Containers (über den JSON-Log-Treiber von Docker)
- Anwendungslogs von allem, was der Kunde betreibt
Die wertvollste einzelne Abfrage im Explore-Tab von Grafana lautet:
{job="syslog"} |= "NVRM:"
Damit holen Sie jede Meldung des NVIDIA-Treibers aus dem Kernel-Ringpuffer hervor – XID-Fehler, Lüfterausfälle, vom Bus gefallene Karten, GSP-RPC-Timeouts. Kombiniert mit dem Prometheus-Alarm auf DCGM_FI_DEV_XID_ERRORS haben Sie die strukturierte Metrik und das unstrukturierte Detail in einer Ansicht.
Standardmäßig versenden wir Logs nicht außer Haus. Loki hält sie lokal mit 30 Tagen Aufbewahrung vor; wer Bereitschaft hat, baut bei Bedarf einen SSH-Tunnel zu Grafana auf. Wer zentrale Logs über mehrere Server hinweg möchte, richtet Loki auf S3 aus oder betreibt eine regionale Instanz – das ist eine Frage des Deployments, nicht der Architektur.
vLLM- und SGLang-Metriken – instrumentieren Sie die Anwendung, nicht nur das Blech
DCGM sagt Ihnen, dass die GPU beschäftigt ist. Es sagt Ihnen nicht, ob Inferenzanfragen in 200 ms oder in 2 s zurückkommen. Dafür instrumentieren Sie die Serving-Schicht.
vLLM stellt /metrics von Haus aus auf demselben Port bereit wie die OpenAI-API. Mit den Standardeinstellungen veröffentlicht der Endpunkt unter :8000/metrics Prometheus-Metriken mit dem Präfix vllm: (das nach dem Prometheus-Scrape zu vllm_ wird). Diese lohnen sich:
| vLLM-Metrik | Bedeutung |
|---|---|
vllm:e2e_request_latency_seconds |
Ende-zu-Ende-Latenz je Anfrage (Histogramm) |
vllm:time_to_first_token_seconds |
TTFT – die Zahl, die Nutzer tatsächlich spüren |
vllm:time_per_output_token_seconds |
Geschwindigkeit der Token-Generierung (Histogramm) |
vllm:num_requests_running |
Aktuell laufende Anfragen |
vllm:num_requests_waiting |
Tiefe der Warteschlange |
vllm:gpu_cache_usage_perc |
Auslastung des KV-Cache (0–1) |
vllm:request_prompt_tokens |
Verteilung der Prompt-Längen |
Die Kombination aus vllm:num_requests_waiting > 0 und DCGM_FI_DEV_GPU_UTIL < 90% bedeutet: Die Warteschlange staut sich, während die GPU leer läuft – meist ein Engpass beim Tokenizer oder Scheduler, nicht bei der Rechenleistung. Sichtbar wird das nur, wenn beide Metriken im selben Dashboard liegen; genau darum führt man App- und Hardware-Telemetrie in einem Prometheus zusammen.
NVIDIA NIM stellt dieselben vLLM-Metriken unter /v1/metrics bereit, ohne sie umzubenennen – Ihre vorhandenen vLLM-Dashboards und Alarmregeln funktionieren also unverändert auch in einem NIM-Deployment. SGLang veröffentlicht einen ähnlichen Satz auf einem eigenen Port (standardmäßig 30000), der HTTP-Server von llama.cpp eine kleinere Teilmenge. Triton bringt eine eigene Systematik mit. Was immer Sie betreiben: Erfassen Sie die Anwendung, nicht nur die Hardware.
Alertmanager-Regeln – genau die, die wir ausliefern
Dashboards sind hübsch. Alarme sind nützlich. Die folgenden Regeln haben auf echter Kundenhardware echte Probleme aufgedeckt.
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; alarm above sustained ceiling
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 }
Die bewussten Entscheidungen in diesen Regeln:
- 87 °C als kritische GPU-Temperatur. Eine 5090 drosselt auf den meisten Boards im oberen 80er-Bereich. Wenn Ihr Raum die Karten unter Dauerlast nicht unter 80 °C hält, haben Sie ein Klimaproblem, kein Softwareproblem.
- Jeder nicht korrigierbare ECC-Fehler weckt die Bereitschaft. Ein einziges Doppelbit-ECC-Ereignis entwertet den Inhalt dieser VRAM-Seite – ein Trainingsschritt ist falsch, ein Inferenzergebnis ist falsch. Die Karte gehört getauscht, nicht neu gestartet.
-
GPUIdleDuringWorkist der Deadlock-Detektor. Mehr als > 1 GiB belegt bei < 5 % Auslastung über 10 Minuten heißt: Irgendwo hängt etwas. Damit erwischen Sie CUDA-seitige Hänger, über die die Anwendung fröhlich hinwegsieht. - Der Alarm auf den OOM-Killer ist die am häufigsten vergessene Regel überhaupt. Dass Linux still und leise Ihren Trainingsjob abräumt und Docker ihn sauber neu startet, ist der Fehlerfall, der pro Jahr die meisten Entwicklerstunden verbrennt. Machen Sie ihn laut.
- Der Alarm auf Container-Neustartschleifen erwischt NIM- und vLLM-Zyklen, die von außen gesund aussehen (der Container „läuft“ ja), in Wahrheit aber bei jedem Laden des Modells abstürzen.
Gehäuse und Datenträger – IPMI und SMART
DCGM endet an der GPU. node_exporter endet am Betriebssystem. Für den Rest des Gehäuses – Lüfter, Netzteile, Umgebungstemperatur, Zustand der Datenträger – brauchen Sie zwei weitere Exporter.
ipmi_exporter (prometheus-community) spricht über IPMI/RMCP mit dem BMC und liefert Telemetrie auf Gehäuseebene: Drehzahl je Lüfter, Eingangsspannung und -strom der Netzteile, Einträge aus dem System Event Log, Zulufttemperatur, Status des BMC-Watchdogs. Auf einem Supermicro- oder Bone64c-Gehäuse mit funktionierendem BMC ist das ein halber Arbeitstag – und es erwischt Dinge, die DCGM schlicht nicht sehen kann: Ein sterbendes Netzteil im Aufbau mit zwei Netzteilen und acht GPUs zeigt sich in den IPMI-Sensordaten als Spannungseinbruch, Minuten bevor eine GPU mit XID 79 aussteigt. Betreiben Sie ihn auf dem Host (er braucht /dev/ipmi0) oder aus der Ferne mit hinterlegten BMC-Zugangsdaten nach dem Multi-Target-Muster.
smartctl_exporter (oder das ältere smart_exporter) liest SMART-Attribute von NVMe- und SATA-Datenträgern aus: Verschleißanzeige, verfügbare Reservezellen, Temperatur, Fehlerzähler. KI-Workloads sind brutal zu NVMe-Laufwerken – Dataset-Loader, Checkpoint-Schreibvorgänge und HuggingFace-Caches treiben Consumer-Laufwerke binnen Monaten an Verschleißwerte, die für Enterprise-Einsatz gedacht sind. Alarmieren sollten Sie, wenn nvme_available_spare unter 20 % fällt und nvme_percentage_used (die Verschleißanzeige) über 80 % steigt. Laufwerksausfälle sind auf einem stark genutzten KI-Server der zweithäufigste Hardwarefehler nach der Kategorie Riser und Netzteil.
Ein vollständiges Monitoring-Setup für Kentino KI-Server enthält beides. Der Mehraufwand sind Minuten; der Nutzen beim ersten still ausgefallenen Lüfter oder beim ersten Samsung 990 Pro am Ende seiner Schreiblast sind Stunden.
Ein echtes docker-compose für die Management-VM
Das setzen wir auf der Management-Maschine tatsächlich ein. Passen Sie host.docker.internal an (oder tragen Sie Hostname bzw. IP des GPU-Servers ein), damit Prometheus die Exporter-Ports des GPU-Hosts erreicht.
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 }
Auf dem GPU-Host selbst (eigenes Compose, auf dem GPU-Server):
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
Die Prometheus-Scrape-Konfiguration auf der Management-VM:
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"]
Das ist ein funktionierender Stack für ein Labor mit einem bis drei Servern. Ab vier oder fünf Servern stellen Sie die Prometheus-Scrape-Konfiguration auf dateibasierte Service Discovery um – oder, falls Sie auf Kubernetes arbeiten, auf das mitgelieferte DCGM-Exporter-Helm-Chart des GPU Operators und die ServiceMonitor -CRDs des Prometheus Operators.
OpenTelemetry, Pixie, eBPF – der Stand 2026
Eine Anmerkung zu den Dingen, die gerade in Bewegung sind, denn die Frage kommt immer.
OpenTelemetry ist der CNCF-Standard für Observability-Instrumentierung; seit Anfang 2026 sind alle drei Signaltypen (Metriken, Traces, Logs) stabil. Die Pipeline des OTel Collectors löst in vielen Organisationen herstellerspezifische Agenten als universellen Telemetrie-Router ab. Für einen KI-Server lautet die pragmatische Antwort 2026: Behalten Sie Prometheus für Metriken (DCGM-Exporter und node_exporter sprechen Prometheus nativ, und Ihre Alarmregeln sind ohnehin in PromQL geschrieben), und ergänzen Sie einen OTel Collector dann, wenn Sie verteiltes Tracing über einen Inferenz-Serving-Graphen brauchen (Anfrage → API-Gateway → vLLM → Tool-Aufruf → Vektordatenbank → Antwort). Bei einer Einzelserver-Installation mit einem Modell hinter nginx verursacht OTel Aufwand ohne Nutzen. Die 71 % der Organisationen, die „beides nutzen“, setzen Prometheus für das Blech und OTel für App-Traces ein – eine sinnvolle Aufteilung.
Pixie ist ein Kubernetes-natives Observability-Werkzeug, das Metriken, Traces und Logs auf Kernel-Ebene per eBPF erhebt, ohne dass Code angepasst werden muss. Bemerkenswert ist 2026 die Arbeit an eBPF auf der GPU (bpftime, eGPU, NVIDIAs offene Kernelmodule), die eBPF-Instrumentierung per PTX-Injektion zur Laufzeit bis in GPU-Kernel hinein ausdehnt. Das hat heute Forschungscharakter und ist in keinem von uns ausgelieferten Produktionsstack enthalten. Für den Moment ist DCGM die unterstützte Antwort.
Kontinuierliches Profiling (Grafana Phlare, Pyroscope) ist ein drittes Add-on, das man kennen sollte. Bei Inferenz-Workloads, deren Framework-Code Sie selbst in der Hand haben (eigene vLLM-Patches, optimierte Tokenizer), zeigt es Ihnen, welche Funktionen die CPU verbrennen. Beim reinen Ausliefern von Modellen mit Standardcontainern ist es überdimensioniert.
Was kaputtgeht (Monitoring-Edition)
Die vorhersehbaren Fehlerbilder des Stacks selbst, sortiert danach, wie oft sie zubeißen:
- Die Prometheus-Platte läuft voll. Standardmäßig sind 15 Tage Aufbewahrung eingestellt; wir setzen 30 Tage mit einer Obergrenze von 20 GB. Ab 60 Tagen auf einer stark genutzten Maschine planen Sie mit mehreren zehn GB. Begrenzen Sie die Aufbewahrung nach Zeit und nach Größe.
-
Der DCGM-Exporter verliert nach einem Treiber-Update die GPUs. Symptom: Alle GPU-Panels bleiben leer. Abhilfe: Container neu starten; falls sich die Runtime verschoben hat,
nvidia-ctk runtime configureerneut ausführen. -
Alertmanager ist nicht auf den Empfänger konfiguriert, den Sie tatsächlich nutzen. Man stellt Prometheus und Grafana auf, vergisst, Alertmanager auf E-Mail oder Slack zu richten – und stellt ein halbes Jahr später fest, dass nie ein Alarm ausgelöst wurde. Testen Sie es, indem Sie
GPUTempCriticalmit einer Stresslast bewusst auslösen, oder feuern Sie am ersten Tag mitamtool alert addeinen synthetischen Alarm ab. -
Kardinalitätsexplosion durch Labels je Anfrage. Versehen Sie vLLM-Metriken nicht mit Labels wie
user_idoderrequest_id. Dafür ist Prometheus nicht gebaut – Sie schießen die Datenbank in den Speichermangel. -
Das Grafana-Passwort tritt über die Compose-Umgebung aus. Nutzen Sie Docker Secrets statt
GF_SECURITY_ADMIN_PASSWORDim Environment-Block.docker inspectund Logs geben Umgebungswerte preis. -
Der XID-Gauge setzt sich nicht zurück. Wie erwähnt kann der XID-Gauge des DCGM-Exporters nach einer Erholung auf dem zuletzt gesehenen Wert hängen bleiben. Kombinieren Sie die Metrik mit dem Syslog-Tail auf
NVRM:in Loki, damit Sie sich nicht in falscher Sicherheit wiegen.
Die ehrliche Einschätzung
Die meisten Labore installieren Grafana einmal, bauen ein Dashboard, das das Team eine Woche lang bewundert – und sehen nie wieder hin. Das Dashboard ist ein befriedigendes Artefakt; Ihre Probleme fängt es nicht ab. Alarme fangen Ihre Probleme ab. Richten Sie Alertmanager mit einem echten Empfänger ein (E-Mail, Slack, PagerDuty) und mit einem kleinen Satz treffsicherer Regeln – GPU-Temperatur, ECC-Doppelbit, XID, OOM-Killer, Container-Neustartschleife – und justieren Sie sie so lange, bis sie nur noch bei echten Problemen auslösen. Tun Sie das zuerst. Dashboards bauen Sie danach, für die Fehlersuche nach dem Vorfall.
Die andere Hälfte der ehrlichen Einschätzung: In einer Kentino-Installation mit einem Server bekommen Sie von diesem Stack vielleicht einmal im Monat einen Alarm, und in den meisten Monaten ist es ein Fehlalarm, den Sie ausblenden. Genau so soll das System arbeiten. Der Wert liegt in dem einen Alarm, der an dem Tag auslöst, an dem ein Riser zu kochen beginnt – zwei Tage bevor die Karte mit XID 79 aussteigt, solange noch Zeit bleibt, ein Kabel neu zu stecken, statt eine GPU einzuschicken. Dieses eine Ereignis bezahlt den gesamten Monitoring-Aufwand, und zwar um ein Vielfaches.
Was Sie als Nächstes tun sollten
Für einen von Kentino gebauten Server, der diese Woche in Betrieb geht:
-
Richten Sie die Management-VM oder den Service-Knoten ein. Ein System mit 4 Kernen und 8 GB reicht völlig. Docker installieren. Das oben gezeigte Compose für
prometheus + grafana + alertmanager + lokieinspielen. -
Installieren Sie auf dem GPU-Host das
nvidia-container-toolkit(siehe L02) und prüfen Sie, obdocker run --rm --gpus all nvidia/cuda:13.0.0-base-ubuntu24.04 nvidia-smifunktioniert. -
Nehmen Sie
dcgm-exporter,node-exporter,ipmi-exporter,smartctl-exporterundpromtailauf dem GPU-Host in Betrieb. Prüfen Sie, ob jeder/metrics-Endpunkt Daten liefert. -
Richten Sie Prometheus auf alle fünf Exporter-Ziele aus, dazu auf den
/metrics-Endpunkt Ihres vLLM. Neu laden (curl -X POST :9090/-/reload). - Importieren Sie die Grafana-Dashboards 12239 und 1860. Prüfen Sie, ob sich die GPU- und System-Panels füllen.
-
Verbinden Sie Alertmanager mit Ihrem E-Mail- oder Slack-Empfänger. Lösen Sie mit
amtooleinen Testalarm aus. Kommt der Testalarm nicht an, kommt auch kein echter an. -
Fahren Sie eine Stresslast (
gpu-burneine Stunde lang, oder einen echten Trainingslauf) und beobachten Sie dabei die Dashboards. Hier stellt sich heraus, ob Ihr Raum die GPUs nicht unter 80 °C hält, ob Ihre NVMe der Engpass ist oder ob Ihr KV-Cache zu klein dimensioniert ist – alles Dinge, die sich am ersten Tag leichter beheben lassen als in Woche drei.
Passende Beiträge: L01 zum Pinnen von Treiberversionen, L02 zu CUDA und der Container-Runtime, L03 zum Kernel-Tuning, L04 zur Wahl des Dateisystems.
Zuerst messen. Dann optimieren. Alles andere ist Raten.
Dieser Beitrag ist Teil des Kentino Wiki, einer Referenzreihe zu KI-Compute, Robotik und den Systemen, die beides verbinden. Anmerkungen und Korrekturen gern an info@kentino.com.