Prometheus Prometheus

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.

14 min Anfänger

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 /metrics auf Port 9100.
  • cAdvisor (Container Advisor, von Google gepflegt): stellt die Ressourcennutzung pro Container bereit, CPU, Speicher, I/O, unter /metrics auf 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