Wer mehrere Docker-Container auf einem Server betreibt, möchte früher oder später wissen, was auf dem System eigentlich passiert: Wie hoch ist die CPU-Auslastung? Welcher Container benötigt besonders viel Arbeitsspeicher? Sind wichtige Dienste erreichbar? Und was steht eigentlich in den Logs der einzelnen Container?
Für diese Aufgaben eignet sich ein zentraler Monitoring-Stack hervorragend.
In diesem Beitrag stelle ich meinen Grafana Monitoring Stack mit Docker vor. Er kombiniert Grafana mit Prometheus, Loki, Grafana Alloy, Node Exporter, cAdvisor und Blackbox Exporter. Zusätzlich kommt ein Docker Socket Proxy zum Einsatz, damit Grafana Alloy keinen uneingeschränkten Zugriff auf den Docker Socket benötigt.
Das komplette Projekt ist auf GitHub verfügbar:
GitHub Repository:
https://github.com/happylippo/grafana-stack
Was kann der Grafana Monitoring Stack?
Der Stack kombiniert mehrere spezialisierte Anwendungen:
- Grafana für Dashboards und Visualisierung
- Prometheus für Metriken und Zeitreihendaten
- Loki für zentrale Log-Speicherung
- Grafana Alloy zum Einsammeln der Docker-Logs
- Node Exporter für Linux-Host-Metriken
- cAdvisor für Docker-Container-Metriken
- Blackbox Exporter für HTTP- und ICMP-Monitoring
- Docker Socket Proxy für einen eingeschränkten Zugriff auf die Docker API
Dadurch werden sowohl der Docker-Host als auch die darauf laufenden Container zentral überwacht.
Grafana bildet dabei die gemeinsame Oberfläche für Metriken und Logs.
Grafana als zentrale Oberfläche
Grafana ist das Frontend des Monitoring-Stacks.
Prometheus und Loki werden beim ersten Start automatisch als Datenquellen provisioniert. Eine manuelle Einrichtung der beiden Datenquellen über die Grafana-Oberfläche ist deshalb nicht erforderlich.
Prometheus liefert beispielsweise:
- CPU-Auslastung
- RAM-Verbrauch
- Festplattenbelegung
- Netzwerkverkehr
- Container-Auslastung
- Uptime
- HTTP- und ICMP-Status
Loki übernimmt dagegen die Logdaten.
Damit können Metriken und Logs innerhalb derselben Grafana-Installation analysiert werden.
Prometheus für die Metriken
Prometheus fragt die verschiedenen Exporter regelmäßig ab und speichert deren Messwerte als Zeitreihen.
Im Stack werden standardmäßig folgende Targets abgefragt:
Prometheus
Node Exporter
cAdvisor
Blackbox Exporter
Das globale Scrape-Intervall ist auf 30 Sekunden eingestellt:
global:
scrape_interval: 30s
evaluation_interval: 30s
Für einen privaten Server oder VPS ist eine Auflösung von 30 Sekunden normalerweise mehr als ausreichend.
Gegenüber einem sehr kurzen Intervall reduziert dies außerdem die Anzahl der gespeicherten Datenpunkte und den Monitoring-Overhead.
Linux-Server mit Node Exporter überwachen
Der Node Exporter stellt die Systemmetriken des Docker-Hosts für Prometheus bereit.
Damit können beispielsweise folgende Werte überwacht werden:
- CPU-Auslastung
- verfügbarer und belegter RAM
- System Load
- Netzwerkverkehr
- Festplattenbelegung
- System-Uptime
Das mitgelieferte Host / System Overview Dashboard stellt die wichtigsten Werte übersichtlich dar.
Dadurch lässt sich schnell erkennen, ob beispielsweise RAM knapp wird oder ungewöhnlich viel CPU-Leistung benötigt wird.
Docker-Container mit cAdvisor überwachen
Für die Container-Metriken kommt cAdvisor zum Einsatz.
cAdvisor kann unter anderem erfassen:
- CPU-Verbrauch pro Container
- RAM-Verbrauch
- Netzwerkverkehr
- Disk-I/O
- erkannte Container
Diese Informationen landen ebenfalls in Prometheus und können anschließend in Grafana dargestellt werden.
CPU-Verbrauch von cAdvisor reduzieren
Bei einer Standardkonfiguration kann cAdvisor selbst überraschend viel CPU-Leistung benötigen. Insbesondere bei vielen Containern können während der Datenerfassung deutliche CPU-Spitzen auftreten.
Deshalb wurde cAdvisor im Stack etwas optimiert.
Unter anderem wird das Housekeeping-Intervall auf 30 Sekunden gesetzt:
command:
- --housekeeping_interval=30s
- --docker_only=true
Da ausschließlich Docker überwacht werden soll, wird zusätzlich:
--docker_only=true
verwendet.
Außerdem werden Metriken deaktiviert, die für die vorhandenen Dashboards nicht benötigt werden:
- --disable_metrics=advtcp,cpu_topology,cpuset,hugetlb,memory_numa,process,referenced_memory,resctrl,sched,tcp,udp
Die wichtigen Werte für CPU, RAM, Netzwerk und Disk-I/O bleiben weiterhin verfügbar.
Dadurch lässt sich der Ressourcenverbrauch des Monitorings reduzieren, ohne auf die für das Docker-Dashboard relevanten Informationen verzichten zu müssen.
Blackbox Exporter für Uptime-Monitoring
Der Blackbox Exporter verfolgt einen anderen Ansatz.
Anstatt interne Systemmetriken zu erfassen, prüft er aktiv die Erreichbarkeit bestimmter Ziele.
Der Stack unterstützt sowohl HTTP- als auch ICMP-Probes.
Beispielsweise können Webseiten überprüft werden:
- https://www.google.com
- https://www.heise.de
Für ICMP können beispielsweise öffentliche DNS-Dienste als externe Referenzziele dienen:
- 1.1.1.1
- 8.8.8.8
- 9.9.9.9
Das zugehörige Grafana-Dashboard zeigt unter anderem die Erreichbarkeit und Dauer der Probes.
Eigene Domains und Dienste können selbstverständlich in der Prometheus-Konfiguration ergänzt werden.
Loki für zentrale Docker-Logs
Metriken alleine reichen bei der Fehlersuche häufig nicht aus.
Deshalb enthält der Stack zusätzlich Loki.
Loki übernimmt die Speicherung der Logdaten und integriert sich direkt in Grafana.
Damit können die Logs verschiedener Docker-Container zentral durchsucht werden, ohne für jeden Dienst einzeln:
docker logs container
aufrufen zu müssen.
Grafana Alloy sammelt die Docker-Logs
Zum Einsammeln der Logs kommt Grafana Alloy zum Einsatz.
Alloy erkennt die laufenden Docker-Container und überträgt deren Logs an Loki.
Eine Abfrage aller Docker-Logs kann anschließend beispielsweise mit LogQL erfolgen:
{job="docker"}
Durch Labels lassen sich die Ergebnisse anschließend weiter eingrenzen.
Grafana Alloy übernimmt damit eine Aufgabe, für die bei älteren Installationen häufig Promtail eingesetzt wurde.
Für einen neuen Monitoring-Stack ist Alloy die deutlich zukunftssicherere Lösung.
Docker Socket Proxy für Alloy
Die Docker API liefert Alloy die Informationen über die vorhandenen Container.
Ein direkter Zugriff eines Containers auf:
/var/run/docker.sock
ist allerdings sicherheitstechnisch problematisch, da der Docker Socket weitreichende Kontrolle über den Docker-Daemon ermöglichen kann.
Deshalb befindet sich zwischen Alloy und Docker ein Docker Socket Proxy.
Dieser stellt nur explizit freigegebene Bereiche der Docker API bereit.
Im Stack werden unter anderem folgende Berechtigungen verwendet:
environment:
CONTAINERS: "1"
INFO: "1"
NETWORKS: "1"
POST: "0"
Besonders wichtig ist:
POST: "0"
Damit werden schreibende API-Aufrufe über den Proxy deaktiviert.
Alloy und der Fehler „403 Forbidden“
Bei der Einrichtung des Stacks gab es einen interessanten Stolperstein.
Alloy konnte zunächst keine Docker-Logs einsammeln und meldete:
Unable to refresh target groups
error while computing network labels:
403 Forbidden
Request forbidden by administrative rules.
Die Ursache war nicht Loki und auch nicht Grafana.
Der Docker Socket Proxy erlaubte zwar den Zugriff auf die Containerinformationen, nicht aber auf die Docker-Netzwerke.
Alloy benötigt diese Informationen jedoch während der Docker-Discovery.
Die Lösung war die zusätzliche Freigabe:
NETWORKS: "1"
Die relevante Konfiguration sieht damit folgendermaßen aus:
environment:
CONTAINERS: "1"
INFO: "1"
NETWORKS: "1"
POST: "0"
Anschließend müssen Socket Proxy und Alloy neu erstellt werden:
docker compose up -d --force-recreate docker-socket-proxy alloy
Danach funktionierte die Docker-Erkennung und die Logs erschienen in Loki.
Vorgefertigte Grafana-Dashboards
Der Stack enthält bereits mehrere automatisch provisionierte Dashboards.
Host / System Overview
Das System-Dashboard zeigt unter anderem:
- CPU-Auslastung
- Arbeitsspeicher
- Festplattenbelegung
- System-Uptime
- Netzwerkverkehr
- Load Average
Docker / Containers
Hier werden die von cAdvisor gesammelten Container-Metriken dargestellt:
- Containeranzahl
- CPU-Auslastung
- RAM-Verbrauch
- Netzwerktraffic
- Disk-I/O
Uptime / Blackbox
Das Blackbox-Dashboard zeigt:
- HTTP-Erreichbarkeit
- ICMP-Erreichbarkeit
- Antwortzeiten
- Verfügbarkeit
Docker / Loki Logs
Hier werden die von Alloy an Loki übertragenen Docker-Logs zentral dargestellt.
Damit stehen nach der Installation bereits die wichtigsten Übersichten zur Verfügung.
Grafana mit Traefik bereitstellen
Grafana kann über einen vorhandenen Traefik Reverse Proxy veröffentlicht werden.
Die entsprechenden Einstellungen befinden sich in der .env-Datei.
Beispielsweise:
TRAEFIK_DOCKER_NETWORK=proxy
TRAEFIK_ENTRYPOINTS=websecure
TRAEFIK_HOST_RULE=Host(`grafana.example.com`)
TRAEFIK_MIDDLEWARES=default@file
TRAEFIK_TLS=true
TRAEFIK_CERTRESOLVER=cloudflare_resolver
Nur Grafana befindet sich zusätzlich im externen Proxy-Netzwerk.
Prometheus, Loki und die Exporter müssen nicht direkt aus dem Internet erreichbar sein und verbleiben deshalb im internen Monitoring-Netzwerk.
Single Sign-on mit Authentik
Optional unterstützt der Stack auch eine Anmeldung über Authentik mittels OAuth2/OpenID Connect.
Die Konfiguration erfolgt über die .env-Datei:
AUTHENTIK_ENABLED=true
AUTHENTIK_URL=https://auth.example.com
AUTHENTIK_APP_SLUG=grafana
AUTHENTIK_OAUTH_NAME=Authentik
AUTHENTIK_CLIENT_ID=CLIENT_ID
AUTHENTIK_CLIENT_SECRET=CLIENT_SECRET
AUTHENTIK_ALLOW_SIGN_UP=true
AUTHENTIK_AUTO_LOGIN=false
Grafana verwendet anschließend Authentik als Identity Provider.
Auch Grafana-Rollen können über Authentik-Gruppen zugewiesen werden.
Der Stack unterscheidet beispielsweise:
Grafana Admins → Admin
Grafana Editors → Editor
alle anderen → Viewer
Damit lässt sich die Benutzerverwaltung zentral über Authentik steuern.
Während der Einrichtung empfiehlt es sich, den automatischen Login zunächst deaktiviert zu lassen:
AUTHENTIK_AUTO_LOGIN=false
So bleibt der normale Grafana-Login als Fallback verfügbar.
Installation des Grafana Monitoring Stacks
Zunächst wird das GitHub-Repository geklont:
git clone https://github.com/happylippo/grafana-stack.git
cd grafana-stack
Anschließend wird das Installationsskript ausführbar gemacht:
chmod +x first_install.sh
Danach:
./first_install.sh
Das Skript erstellt die .env-Datei und fragt die grundlegenden Einstellungen ab.
Vor dem eigentlichen Start sollte die Compose-Konfiguration überprüft werden:
docker compose config
Anschließend kann der komplette Monitoring-Stack gestartet werden:
docker compose up -d
Container überprüfen
Den Status aller Dienste zeigt:
docker compose ps
Die Logs des kompletten Stacks können mit:
docker compose logs -f
beobachtet werden.
Für einzelne Komponenten beispielsweise:
docker compose logs -f grafana
oder:
docker compose logs -f alloy
Persistente Daten
Grafana, Prometheus, Loki und Alloy verwenden persistente Docker-Volumes:
grafana-data
prometheus-data
loki-data
alloy-data
Die Daten bleiben damit beim Aktualisieren oder Neuerstellen der Container erhalten.
Vorsicht ist deshalb bei:
docker compose down -v
geboten.
Die Option -v entfernt zusätzlich die Docker-Volumes und sollte nur verwendet werden, wenn die gespeicherten Monitoring-Daten tatsächlich gelöscht werden sollen.
Updates durchführen
Ein Update des Stacks ist unkompliziert.
Zunächst die aktuellen Änderungen aus dem Repository holen:
git pull
Danach neue Images laden:
docker compose pull
Und die Container aktualisieren:
docker compose up -d
Abschließend kann kontrolliert werden, ob alles ordnungsgemäß läuft:
docker compose ps
Fazit
Mit Grafana, Prometheus, Loki und Alloy entsteht eine leistungsfähige Monitoring-Lösung für Docker-Server.
Node Exporter überwacht das Host-System, während cAdvisor detaillierte Informationen über die einzelnen Docker-Container liefert. Blackbox Exporter ergänzt das Monitoring um aktive Verfügbarkeitsprüfungen.
Loki und Alloy sorgen zusätzlich dafür, dass auch die Docker-Logs zentral in Grafana zur Verfügung stehen.
Durch das automatische Provisioning sind die wichtigsten Datenquellen und Dashboards bereits nach dem Start vorhanden. Der Docker Socket Proxy reduziert gleichzeitig die Berechtigungen, die Alloy für die Container-Erkennung erhält.
Mit Traefik und optionalem Authentik-SSO lässt sich der Stack außerdem gut in eine bestehende Self-Hosting-Infrastruktur integrieren.
Wer seine Docker-Umgebung zentral überwachen möchte, erhält damit eine solide Grundlage, die später problemlos um weitere Exporter, Dashboards und Alarmierungen erweitert werden kann.
