Einen Host und seine Container mit node_exporter und cAdvisor überwachen
Betreibe Prometheus, node_exporter und cAdvisor zusammen, frage beide ab und bestätige, dass die Targets gesund sind.
Metriken auf Host-Ebene (CPU, Speicher, Disk, Netzwerk) und Metriken pro Container stammen aus zwei verschiedenen Exportern. Diese Anleitung betreibt Prometheus zusammen mit beiden per Docker Compose, konfiguriert Prometheus, beide abzufragen, und bestätigt, dass es funktioniert, bevor die Daten in der nächsten Anleitung an ein Dashboard übergeben werden.
Die drei Teile
- Prometheus selbst: fragt Targets nach Zeitplan ab und speichert die Ergebnisse.
- node_exporter: stellt die eigenen Metriken des Host-Betriebssystems bereit, CPU, Speicher, Disk, Netzwerk, unter
/metricsauf Port 9100. - cAdvisor (Container Advisor, von Google gepflegt): stellt die Ressourcennutzung pro Container bereit, CPU, Speicher, I/O, unter
/metricsauf Port 8080.
Beide Exporter brauchen Einblick in Dinge, die ein normaler Container nicht sehen kann: node_exporter braucht das Root-Dateisystem und den Prozess-Namespace des Hosts, um den Host korrekt zu melden und nicht nur seinen eigenen Container, und cAdvisor braucht Zugriff auf die eigenen Daten der Container-Runtime, um über jeden auf dem Host laufenden Container zu berichten, nicht nur über sich selbst.
Docker Compose für alle drei
version: "3"
volumes:
prometheus-data:
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.retention.time=15d"
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
pid: host
volumes:
- /:/host:ro,rslave
command:
- "--path.rootfs=/host"
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
pid: host und das schreibgeschützte Root-Mount von node-exporter sind es, die ihn über den Host berichten lassen statt über seine eigene isolierte Container-Sicht; --path.rootfs=/host sagt ihm, wo dieses gemountete Root im Container tatsächlich gelandet ist. cadvisor braucht aus demselben Grund seinen eigenen Satz schreibgeschützter Mounts in den Runtime-Zustand des Hosts: Ohne sie sieht er nur sich selbst, nicht die anderen Container auf dem Host. Nichts davon braucht Schreibzugriff auf den Host, jeder Mount ist schreibgeschützt, was du im Kopf behalten solltest, wenn ein Security-Review fragt, was diese Container tatsächlich tun können.
Prometheus so konfigurieren, dass es beide abfragt
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "node-exporter"
static_configs:
- targets: ["node-exporter:9100"]
- job_name: "cadvisor"
static_configs:
- targets: ["cadvisor:8080"]
global.scrape_interval ist nicht Prometheus’ eingebauter Standard (der ist eine Minute); ihn ausdrücklich auf 15 Sekunden zu setzen, wie es die meisten Einstiegsbeispiele tun, ist eine Konvention, der man folgen sollte, da es häufig genug ist, um reaktionsschnelle Dashboards zu liefern, ohne übermäßiges Abfragevolumen zu erzeugen. Jeder job_name ist ein beliebiges Label, das du wählst und das an jede Serie gehängt wird, die dieser Job abfragt, wodurch du später in einer Query „diese Metrik kam von node-exporter“ von „diese Metrik kam von cadvisor“ unterscheiden kannst. Targets werden über ihren Compose-Service-Namen adressiert (node-exporter, cadvisor), weil Container im selben Compose-Netzwerk einander automatisch über den Service-Namen auflösen; Container-IP-Adressen oder localhost sind hier nicht nötig.
Hochfahren und bestätigen, dass die Targets gesund sind
docker compose up -d
Öffne http://localhost:9090/targets in einem Browser. Jeder konfigurierte Job sollte als UP erscheinen. Tut er das nicht, prüfe zuerst die eigenen Logs dieses Containers und bestätige, dass du seinen /metrics-Endpunkt direkt erreichen kannst (curl http://localhost:9100/metrics vom Host oder docker exec in den Prometheus-Container und curl auf den Compose-Service-Namen des Targets), bevor du annimmst, dass das Problem in Prometheus’ Konfiguration statt im Target selbst liegt.
Probiere auf Prometheus’ eigener Graph-Seite einen schnellen Plausibilitätscheck:
up{job="node-exporter"}
up ist eine synthetische Metrik, die Prometheus selbst für jedes Target erzeugt, 1, wenn der letzte Abruf erfolgreich war, 0, wenn nicht, was sie zu einem schnellen Weg macht, die Gesundheit eines Targets direkt über PromQL zu prüfen statt über die Targets-Seite.
Ein Hinweis, bevor du weitermachst
Weder die UI von Prometheus noch die von cAdvisor wird standardmäßig mit Authentifizierung oder TLS ausgeliefert. Das ist ein vernünftiger Standard für etwas, das aus einem vertrauenswürdigen Netzwerk heraus abgefragt werden soll, bedeutet aber, dass diese Ports nicht direkt ins öffentliche Internet exponiert werden sollten, ohne Zugriffskontrolle hinzuzufügen, sei es ein Reverse Proxy mit Authentifizierung davor oder schlicht, sie von vornherein nur aus einem internen Netzwerk erreichbar zu halten.
Wenn beide Exporter in Prometheus berichten, behandelt die nächste Anleitung, daraus mit Grafana ein echtes Dashboard zu machen.
Beliebte Anleitungen
-
Prometheus-Architektur und das Pull-Modell Warum Prometheus abfragt statt zu empfangen und wie Targets, Exporter und Service Discovery zusammenpassen. -
Das Prometheus-Datenmodell: Metriken, Labels und Metriktypen Was eine Zeitreihe in Prometheus tatsächlich ist und das Klartextformat, in dem Targets sie bereitstellen. -
Einstieg in PromQL: Auswählen, Raten und Aggregieren Baue von einem einfachen Metrik-Selektor zu einer echten Abfrage auf: Fehlerrate pro Pfad, live berechnet.