
Heute möchte ich euch zeigen, wie ich endlich ein sicheres Monitoring für meine Docker-Container aufgesetzt habe. Nach einigem Hin und Her mit verschiedenen Exportern bin ich bei einer eleganten Lösung gelandet, die ich euch nicht vorenthalten möchte.
Die Ausgangssituation
Ich hatte bereits einen Node Exporter mit TLS und Basic Auth am Laufen und wollte nun auch meine Docker-Container überwachen. Meine Anforderung war klar: Das Ganze sollte genauso sicher sein wie mein Node Exporter – also mit HTTPS und Authentifizierung.
Warum Docker Daemon statt cAdvisor?
Zuerst hatte ich mir cAdvisor angeschaut, den "Standard" für Container-Monitoring. Aber ehrlich gesagt – warum einen zusätzlichen Container starten, wenn Docker selbst Prometheus-Metriken exportieren kann?
Der Docker Daemon kann nämlich seit einiger Zeit direkt Prometheus-Metriken bereitstellen. Das ist:
- Ressourcenschonender
- Eine Abhängigkeit weniger
- Einfacher zu warten
Klar, cAdvisor liefert detailliertere Metriken pro Container, aber für die meisten Anwendungsfälle reichen die Docker Daemon Metrics vollkommen aus.
Das Problem: Keine native Sicherheit
Docker kann zwar Metriken exportieren, aber leider ohne TLS oder Authentifizierung. Der Metrics-Endpoint ist einfach nur ein ungesicherter HTTP-Port. Das will man natürlich nicht öffentlich ins Internet stellen.
Die Lösung: Nginx als Reverse Proxy
Meine Lösung war simpel: Nginx als Sicherheitsschicht vor die Docker Metrics setzen. Da ich Nginx ohnehin schon für andere Services nutze, war das die naheliegendste Wahl.
Schritt 1: Docker Daemon konfigurieren
Zuerst habe ich den Docker Daemon so konfiguriert, dass er Metriken nur auf localhost bereitstellt:
{
"metrics-addr": "127.0.0.1:9323",
"experimental": true
}
Diese Konfiguration kommt in /etc/docker/daemon.json
. Wichtig ist hier die 127.0.0.1
– so ist der Port nur lokal erreichbar und nicht von außen.
Nach einem sudo systemctl restart docker
laufen die Metriken auf Port 9323.
Schritt 2: SSL-Zertifikate erstellen
Für die verschlüsselte Verbindung brauchen wir ein Zertifikat. Für interne Zwecke reicht ein selbstsigniertes völlig aus:
sudo mkdir -p /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/docker_metrics.key \
-out /etc/nginx/ssl/docker_metrics.crt \
-subj "/CN=docker-metrics"
Schritt 3: Basic Auth einrichten
Damit nicht jeder die Metriken abrufen kann, habe ich Basic Authentication aktiviert:
sudo apt-get install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd admin
Das Tool fragt nach einem Passwort – dieses brauchen wir später für Prometheus.
Schritt 4: Nginx konfigurieren
Hier die eigentliche Magie – die Nginx-Konfiguration:
server {
listen 9324 ssl;
server_name _;
ssl_certificate /etc/nginx/ssl/docker_metrics.crt;
ssl_certificate_key /etc/nginx/ssl/docker_metrics.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
auth_basic "Docker Metrics";
auth_basic_user_file /etc/nginx/.htpasswd;
location /metrics {
proxy_pass http://127.0.0.1:9323/metrics;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location / {
return 404;
}
}
Ein paar wichtige Details:
- Port 9324 für Nginx (9323 ist ja schon von Docker belegt)
- TLS 1.2 und 1.3 für moderne Verschlüsselung
- Basic Auth vor allen Zugriffen
- Nur
/metrics
ist erreichbar, alles andere gibt 404
Diese Datei habe ich unter /etc/nginx/sites-available/docker-metrics
gespeichert und verlinkt:
sudo ln -s /etc/nginx/sites-available/docker-metrics /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Stolperfalle: Der richtige Port!
Ich hatte anfangs in der Nginx-Config versehentlich listen 9323
stehen – also den gleichen Port wie Docker. Das funktioniert natürlich nicht! Also aufpassen: Nginx auf 9324, Docker auf 9323.
Schritt 5: Prometheus konfigurieren
Jetzt nur noch Prometheus beibringen, die Metriken abzuholen:
- job_name: 'docker-daemon'
scheme: https
tls_config:
insecure_skip_verify: true # Wegen selbstsigniertem Zertifikat
static_configs:
- targets: ['DEINE.IP.ADRESSE.HIER:9324']
labels:
instance: 'DEINE_INSTANZ'
basic_auth:
username: "admin"
password: "dein_passwort"
Nach einem Neustart von Prometheus sollte unter Status → Targets der neue Job mit Status "UP" erscheinen.
Grafana Dashboard
Das Tolle: Es gibt fertige Dashboards für Docker Metrics! Ich nutze das Dashboard mit der ID 1229 – einfach in Grafana unter "Import Dashboard" die Nummer eingeben und schon hat man eine schöne Übersicht.
Fazit
Das Setup ist zwar ein paar Schritte mehr als einfach nur cAdvisor zu starten, aber dafür habe ich jetzt:
- ✅ Verschlüsselte Verbindung via HTTPS
- ✅ Authentifizierung via Basic Auth
- ✅ Nur localhost-Zugriff für Docker Daemon
- ✅ Keine zusätzlichen Container
- ✅ Weniger Ressourcenverbrauch
Und das Beste: Das Prinzip lässt sich auf alle möglichen internen Services anwenden, die keine eigene Authentifizierung mitbringen. Nginx als Sicherheitsschicht vor unsichere Endpoints zu setzen, ist ein Pattern, das ich mittlerweile öfter verwende.
Falls ihr das nachbaut und irgendwo hängen bleibt – schreibt mir gerne! Ich bin beim Einrichten auch über ein paar Stolperfallen gestolpert (siehe der Port-Konflikt oben), aber am Ende läuft jetzt alles stabil.
Happy Monitoring! 🐳📊