Grafana & Prometheus – Monitoring Stack für Docker und Proxmox
Wie spielen die Akteure zusammen?
Monitoring in diesem Stack basiert auf einem klaren Pull-Prinzip: Prometheus fragt aktiv bei den Datenquellen an – nicht umgekehrt. Jede Komponente hat eine klar definierte Rolle.
┌─────────────────────────────────────────────────────────────────┐
│ monitoring network │
│ │
│ ┌──────────────┐ scrape ┌─────────────────────────┐ │
│ │ Prometheus │◄────────────────│ cAdvisor :8080 │ │
│ │ :9090 │◄────────────────│ pve-exporter :9221 │ │
│ │ │◄────────────────│ traefik :8899 │ │
│ │ │◄────────────────│ prometheus :9090 │ │
│ └──────┬───────┘ └─────────────────────────┘ │
│ │ query (PromQL) │
│ ┌──────▼───────┐ ┌─────────────────────────┐ │
│ │ Grafana │ │ Redis │ │
│ │ :3000 │ │ (cAdvisor session) │ │
│ └──────────────┘ └─────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
│ proxy network
┌────▼─────┐
│ Traefik │ → grafana.example.com (Authentik-geschützt)
└──────────┘
Außerhalb des monitoring network:
┌─────────────────────────────────┐
│ Proxmox VE 192.168.100.21 │
│ pve-exporter liest PVE API │
└─────────────────────────────────┘
Prometheus ist die Zentrale. Es scraped alle Datenquellen in regelmäßigen Intervallen, speichert die Zeitreihendaten in seiner eigenen TSDB und beantwortet PromQL-Abfragen von Grafana.
Grafana ist das Visualisierungslayer. Es stellt keine eigenen Metriken bereit und speichert keine Zeitreihendaten – es fragt Prometheus per PromQL ab und rendert Dashboards.
cAdvisor (Container Advisor) läuft auf dem Docker-Host und exportiert Ressourcenmetriken aller laufenden Container: CPU, RAM, Netzwerk, Disk-I/O – pro Container, in Echtzeit. Prometheus scraped cAdvisor alle 5 Sekunden.
pve-exporter übersetzt die Proxmox VE API in Prometheus-Metriken. Er läuft als Container im monitoring-Netzwerk und wird von Prometheus über einen Umweg gescraped – mehr dazu im Abschnitt zur prometheus.yml.
Redis wird von cAdvisor als Session-Store genutzt.
Vorbereitung
mkdir -p /opt/monitoring
cd /opt/monitoring
Drei Dateien werden neben der compose.yml benötigt:
/opt/monitoring/
├── compose.yml
├── prometheus.yml # Scrape-Konfiguration
└── pve.yml # Proxmox-Zugangsdaten
docker-compose.yml
Grafana
grafana:
image: grafana/grafana:latest
container_name: grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-data:/var/lib/grafana
networks:
- monitoring
- proxy
Grafana hängt in zwei Netzwerken: monitoring für die Prometheus-Verbindung und proxy für Traefik. Das Admin-Passwort sollte nicht im Compose-File stehen – besser in einer .env-Datei.
Grafana ist der einzige Container im Stack der nach außen exponiert wird – über Traefik mit Authentik-Middleware. Prometheus, cAdvisor und pve-exporter sind ausschließlich intern erreichbar.
Prometheus
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
networks:
- monitoring
Die prometheus.yml wird als Bind-Mount eingebunden – Änderungen an der Scrape-Konfiguration sind ohne Image-Rebuild möglich. Das prometheus-data-Volume persistiert die TSDB. Standardmäßig hält Prometheus Daten 15 Tage vor.
cAdvisor
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
cpus: 0.1
command:
- '-housekeeping_interval=10s'
- '-docker_only=true'
- '-store_container_labels=false'
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
networks:
- monitoring
cAdvisor braucht direkten Zugriff auf den Host-Kernel um Container-Metriken zu lesen – daher die umfangreichen Volume-Mounts:
| Mount | Zweck |
|---|---|
/:/rootfs:ro |
Filesystem-Statistiken |
/var/run:/var/run:rw |
Docker-Socket für Container-Metadaten |
/sys:/sys:ro |
Kernel-Subsysteme (cgroups, Netzwerk) |
/var/lib/docker:/var/lib/docker:ro |
Docker-interne Metriken |
-docker_only=true schränkt cAdvisor auf Docker-Container ein – ohne dieses Flag werden auch systemd-Services und andere cgroup-Prozesse erfasst, was Rauschen erzeugt. -store_container_labels=false verhindert dass alle Container-Labels als Prometheus-Labels landen – reduziert die Kardinalität der Zeitreihen erheblich.
cpus: 0.1 begrenzt cAdvisor auf 10% eines CPU-Kerns – cAdvisor kann ohne Limit überraschend ressourcenhungrig werden.
pve-exporter
pve-exporter:
image: prompve/prometheus-pve-exporter:latest
container_name: pve-exporter
command: "--config.file=/etc/prometheus/pve.yml"
volumes:
- ./pve.yml:/etc/prometheus/pve.yml:ro
networks:
- monitoring
Der pve-exporter übersetzt Proxmox-API-Daten in Prometheus-Metriken. Er liest seine Zugangsdaten aus pve.yml – API-Token statt Passwort ist die empfohlene Authentifizierungsmethode.
prometheus.yml – Scrape-Konfiguration
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'traefik'
static_configs:
- targets: ['traefik:8899']
- job_name: cadvisor
scrape_interval: 5s
static_configs:
- targets:
- cadvisor:8080
- job_name: 'pve'
static_configs:
- targets:
- 192.168.100.21
metrics_path: /pve
params:
module: [default]
cluster: ['1']
node: ['1']
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: pve-exporter:9221
Scrape-Intervalle
cadvisor wird mit scrape_interval: 5s häufiger gescraped als der globale Standard von 15 Sekunden – Container-Metriken ändern sich schnell und 15 Sekunden wären für CPU-Spikes zu grob. Prometheus, Traefik und pve-exporter reichen mit 15 Sekunden aus.
Das pve-Relabeling
Der Proxmox-Scrape-Job ist das komplexeste Stück der Konfiguration und verdient eine Erklärung:
Prometheus will scrapen: 192.168.100.21 (der Proxmox-Host)
Aber der Exporter läuft: pve-exporter:9221 (im monitoring-Netzwerk)
Der pve-exporter funktioniert als Proxy: Prometheus schickt eine Anfrage an pve-exporter:9221/pve?target=192.168.100.21, der Exporter holt die Daten von der Proxmox-API und gibt sie als Prometheus-Metriken zurück.
Das Relabeling bewerkstelligt genau diese Umleitung:
1. source_labels: [__address__] → nimmt "192.168.100.21"
target_label: __param_target → setzt ?target=192.168.100.21
2. source_labels: [__param_target] → nimmt "192.168.100.21"
target_label: instance → setzt instance-Label für Grafana
3. target_label: __address__ → überschreibt Zieladresse
replacement: pve-exporter:9221 → Prometheus fragt jetzt den Exporter
Das Muster ist Standard für alle Prometheus-Exporter die als HTTP-Proxy fungieren (Blackbox Exporter, SNMP Exporter, PVE Exporter).
Traefik-Metrics
Traefik exponiert Prometheus-Metriken auf dem dedizierten metrics-EntryPoint (Port 8899). Da Traefik und Prometheus im selben monitoring-Netzwerk hängen, ist traefik:8899 direkt auflösbar – kein Port nach außen nötig.
pve.yml – Proxmox-Zugangsdaten
default:
verify_ssl: false
user: 'monitoring@pve'
token_name: 'prometheus'
token_value: '<token>'
verify_ssl: false ist nötig wenn Proxmox ein selbstsigniertes Zertifikat verwendet – üblich in Heimlabor-Umgebungen. In produktiven Umgebungen sollte ein gültiges Zertifikat und verify_ssl: true verwendet werden.
API-Token in Proxmox erstellen
Im Proxmox-Webinterface: Datacenter → Permissions → API Tokens → Add
Benötigte Berechtigungen für den monitoring-User:
| Pfad | Rolle | Propagate |
|---|---|---|
/ |
PVEAuditor |
✅ |
PVEAuditor erlaubt Lesezugriff auf alle Nodes, VMs und Container – ausreichend für Monitoring, keine Schreibrechte.
Start
docker compose up -d
# Prometheus Targets prüfen
# http://server-ip:9090/targets
# Alle Targets sollten "UP" sein
docker compose logs -f prometheus
docker compose logs -f pve-exporter
Grafana ist nach dem Start unter http://server-ip:3000 oder via Traefik erreichbar.
Prometheus als Datenquelle einrichten
In Grafana: Connections → Data Sources → Add → Prometheus
URL: http://prometheus:9090
Da Grafana und Prometheus im selben monitoring-Netzwerk sind, funktioniert der Container-Name direkt.
Empfohlene Dashboards
Fertige Dashboards lassen sich in Grafana über Dashboards → Import per ID laden:
| Dashboard | ID | Quelle |
|---|---|---|
| Node Exporter Full | 1860 | grafana.com |
| cAdvisor Docker | 14282 | grafana.com |
| Proxmox VE | 10347 | grafana.com |
| Traefik 2/3 Official Dashboard | 17346 | grafana.com |
Updates & Wartung
docker compose pull
docker compose up -d
# Prometheus Retention anpassen (Standard: 15 Tage)
# In compose.yml unter prometheus command:
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=30d'
- '--storage.tsdb.retention.size=10GB'
Fazit
Der Stack folgt dem Unix-Prinzip: jedes Tool macht genau eine Sache. Prometheus sammelt und speichert, cAdvisor exportiert Container-Metriken, pve-exporter überbrückt die Proxmox-API, Grafana visualisiert. Die Kopplung ist lose – jede Komponente ist austauschbar, jede Konfiguration liegt als Datei vor. Das Relabeling-Pattern im pve-Job ist dabei das einzige nicht-offensichtliche Konzept – wer es einmal verstanden hat, kann jeden Proxy-Exporter im Prometheus-Ökosystem damit ansprechen.