...

Node Exporter richtig konfigurieren: Praxisleitfaden für Prometheus Linux Server Monitoring

Node Exporter richtig konfigurieren heißt: Ich setze den Dienst so auf, dass Prometheus verlässliche Linux-Servermetriken mit klaren Ports, gezielten Collector-Einstellungen und sauberer Absicherung einsammelt. In diesem Praxisleitfaden zeige ich Installation, systemd-Setup, Collector-Tuning, Security, Prometheus-Integration, Performance-Tricks und nützliche Prüfungen für den Alltag.

Zentrale Punkte

  • Installation und Dienststart mit eigener systemd-Unit
  • Collector gezielt wählen, Metriklast senken
  • Sicherheit durch Port-Freigaben und Proxy
  • Prometheus Scrapes, Alerts und Aufbewahrung
  • Performance via Intervalle, Sharding, Cleanup

Was ist der Node Exporter?

Ich setze den Node Exporter auf jedem Linux-Host ein, um Systemmetriken im Prometheus-Format bereitzustellen. Der Daemon liefert CPU-Last, Load, Arbeitsspeicher, Swap, Dateisysteme, Netzwerk und optional systemd- sowie Prozessdaten. Ich greife über HTTP auf den Endpunkt /metrics zu und sehe lesbare Zeitreihen, die Prometheus zyklisch abholt. Dieser Ansatz passt zu heterogenen Serverflotten und bleibt durch das Pull-Modell transparent. Ich profitiere von einer klaren Trennung: Der Exporter sammelt, Prometheus speichert und wertet aus.

Architekturüberblick: So greifen Node Exporter und Prometheus ineinander

Ich starte den Exporter auf Port 9100, steuere die Collector und lasse Prometheus periodisch scrapen. Das Pull-Prinzip erleichtert Firewalls, weil ich nur den Zugriff von Prometheus zum Host öffne. Grafana oder ähnliche Visualisierungslösungen setzen anschließend auf Prometheus auf und zeigen die Werte übersichtlich an. In produktiven Umgebungen betreibe ich mehrere Prometheus-Server für getrennte Verantwortlichkeiten. So halte ich Pfade kurz, Rollen klar und die Verwaltung nachvollziehbar.

Installation unter Linux: sauber und wiederholbar

Ich lade die passende Binary für linux-amd64 oder die Zielarchitektur und lege sie nach /usr/local/bin/. Danach richte ich einen Systembenutzer ohne Login ein, zum Beispiel node_exporter, und setze Eigentümerrechte am Binary. Für den automatischen Start erstelle ich eine systemd-Unit im Verzeichnis /etc/systemd/system/ mit einem einfachen ExecStart und einer Restart-Policy. Nach systemctl daemon-reload aktiviere und starte ich den Dienst, prüfe den Status und rufe curl http://localhost:9100/metrics auf. So erkenne ich sofort, ob Metriken korrekt bereitstehen und der Service wie vorgesehen läuft.

Node Exporter als systemd-Service: die wichtigen Stellschrauben

Ich definiere in der Unit User und Group als dedizierten Account, setze Type=simple und einen klaren ExecStart. Eine Neustart-Strategie wie Restart=on-failure hilft gegen kurzfristige Ausfälle. Für Updates editiere ich die Unit oder lege eine Drop-In-Datei an, damit Änderungen nachvollziehbar bleiben. Nach jeder Anpassung führe ich einen daemon-reload aus und starte den Dienst neu. Ich halte die Unit kompakt, dokumentiert und wiederverwendbar für alle Serverklassen.

Port und Listen-Address: konsistent und sicher

Ich höre standardmäßig auf Port 9100, ändere den Port jedoch projektspezifisch, falls Überschneidungen bestehen. Die Option --web.listen-address erlaubt Host- und Port-Anpassungen, etwa 127.0.0.1:9200 bei lokalem Proxy-Offloading. Ein einheitliches Port-Schema reduziert Verwirrung in großen Teams. Ich trage Portänderungen zentral ein, damit Firewalls und Security-Listen stimmen. Der Port bleibt auf die Prometheus-Server eingeschränkt und geht nicht frei ins Internet.

Collector gezielt konfigurieren: nur was wirklich zählt

Ich wähle die Collector bewusst, um Datenmenge und Rechenzeit zu steuern. Standardmodule für CPU, Speicher, Dateisysteme und Netzwerk bleiben meist aktiv. Falls nötig aktiviere ich spezielle Module wie --collector.systemd oder --collector.processes, um Services und Prozesse genauer zu beobachten. Unerwünschte Module deaktiviere ich mit --no-collector.X, damit Prometheus weniger Zeitreihen verarbeiten muss. Die getroffene Auswahl dokumentiere ich pro Serverrolle, damit das Team konsistent bleibt.

Textfile Collector: eigene Metriken sauber einspeisen

Ich nutze den Textfile Collector für individuelle Kennzahlen, die Standardmodule nicht liefern. Ein Verzeichnis wie /var/lib/node_exporter/textfile_collector sammelt .prom-Dateien im Prometheus-Format. Skripte schreiben atomar, indem sie temporäre Dateien erzeugen und am Ende ersetzen, damit keine halbfertigen Werte erscheinen. So bringe ich Business-Statistiken, Batch-Status oder Queue-Längen direkt in Prometheus. Ich halte Namenskonventionen ein, um Auswertungen und Dashboards lesbar zu gestalten.

Sicherheit im Produktivbetrieb: Zugriff nur für Berechtigte

Ich beschränke den Portzugriff per Firewall konsequent auf die Scrape-Quellen. Ein vorgeschalteter Reverse Proxy kümmert sich bei Bedarf um TLS oder mTLS und übernimmt Authentisierung. Den Dienst lasse ich ohne Root-Rechte laufen und vergebe minimale Dateirechte für Log- und Textfile-Pfade. In getrennten Netzen sichere ich zusätzlich über VPN oder private Subnetze ab. So bleiben detaillierte Systeminformationen geschützt und nur für Monitoring-Infrastruktur sichtbar.

Integration in Prometheus: Scrapes, Labels, Alerts

Ich lege in der prometheus.yml einen Job wie job_name: node an, setze ein sinnvolles scrape_interval (oft 15s) und pflege Targets oder Service Discovery ein. Einheitliche Labels (z. B. Umgebung, Rolle, Standort) erleichtern Filter und Dashboards. Für häufige Auswertungen definiere ich Recording Rules und entlaste damit Ad-hoc-Abfragen. Alerts segeln auf aggregierten Metriken, etwa für CPU-Last, RAM, Swap, Plattenbelegung und Netzwerkfehler. Für den Einstieg in Auslastung und Lastspitzen verweise ich auf meine kompakte CPU- und Load-Analyse, die typische Kennzahlen praxisnah erklärt.

Monitoring des Node Exporter selbst: Vertrauen ist gut, Kontrolle besser

Ich beobachte den Jobstatus in Prometheus und lasse Alarme auslösen, wenn ein Host längere Zeit nicht scraped. Versionen der Exporter prüfe ich regelmäßig, um Fehlerbehebungen und neue Module zeitnah zu nutzen. Zusätzlich messe ich die Anzahl der Time Series pro Host, um früh zu erkennen, wenn eine Collector-Änderung die Last hochtreibt. Dashboards erhalten Panel-Hinweise zur zuletzt erfolgreichen Abholung. So erkenne ich Störungen schnell und reagiere ohne Umwege.

Performance-Optimierung und Skalierung: Last im Griff behalten

Ich steuere die Intervalle nach Größe und Zweck der Umgebung: 15s für Kernsysteme, 30–60s für weniger kritische Server. Durch selektive Collector-Auswahl reduziere ich Metriken und Abfragezeiten. Eigene Textfile-Metriken halte ich schlank, lösche Altes und benenne konsistent. Wächst die Flotte stark, verteile ich die Last über mehrere Prometheus-Instanzen und trenne Verantwortlichkeiten. Die folgende Tabelle zeigt bewährte Stellschrauben und ihre Wirkung im Betrieb.

Thema Einstellung Wirkung Hinweis
Scrape-Intervall 15s / 30s / 60s Weniger Scrapes senken Last Kritikalität je Hostklasse berücksichtigen
Collector-Auswahl nur benötigte Module Reduziert Zeitreihen Liste je Rolle dokumentieren
Textfile Collector schlanke .prom-Dateien Weniger Parsing-Kosten Atomar schreiben, klar benennen
Label-Kardinalität Labels prüfen Verhindert Explosion der Serien IDs und hochvariable Werte vermeiden
Sharding Prometheus aufteilen Skaliert Scrapes und Queries Verantwortlichkeiten trennen

Für Speichersysteme achte ich besonders auf IO-Werte und Latenzen pro Gerät sowie Dateisystem. Einen guten Startpunkt bietet mein Leitfaden Disk-Latenzen überwachen, der typische Symptomketten und Metriken zusammenfasst. Ich verknüpfe diese Werte mit CPU-Wait und Load, um Engpässe sicher einzugrenzen. Abfragen kapsle ich in Recording Rules, damit Dashboards schnell laden. So bleiben Analyse und Betrieb zügig und übersichtlich.

Visualisierung mit Grafana: klar sehen, schnell handeln

Ich nutze fertige Dashboards für CPU, RAM, Disk, Netzwerk und systemd, passe sie aber an meine Labels an. Ein Übersichtsdashboard zeigt Status, Auslastung und auffällige Hosts, während Detailseiten tiefer einsteigen. Panels beschreibe ich kurz, damit jeder die Bedeutung der Kennzahl versteht. Variable-Selector beschleunigen den Wechsel zwischen Hosts oder Rollen. Wer einen Komplettüberblick anstrebt, findet unter Monitoring-Stack mit Grafana Hinweise zum Zusammenbau eines performanten Stacks.

Saubere Paketierung und Versionspflege: reproduzierbar bleiben

Ich halte Installationen reproduzierbar, indem ich Versionen explizit pinne und Checksummen prüfe. Für Fleet-Setups packe ich den Node Exporter als internes Paket (z. B. DEB/RPM) mit fester Pfadstruktur und Systemnutzer. Updates rolle ich gestaffelt aus und dokumentiere die eingesetzte Version pro Umgebung. Wo es passt, hinterlege ich die Startparameter in einer EnvironmentFile, damit Änderungen nicht direkt an der Unit-Datei erfolgen und sauber versioniert bleiben. Ich teste neue Releases erst in Staging, bevor ich sie breit verteile.

Beispielkonfiguration: systemd-Unit und Hardening

Ich nutze eine einfache, aber tragfähige Unit und ergänze bei Bedarf Härtungseinstellungen:

[Unit]
Description=Prometheus Node Exporter
After=network-online.target
Wants=network-online.target

[Service]
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter \
  --web.listen-address=0.0.0.0:9100 \
  --collector.systemd \
  --collector.processes \
  --collector.filesystem.fs-types-exclude='^(tmpfs|devtmpfs|overlay|squashfs)$' \
  --collector.filesystem.mount-points-exclude='^/(sys|proc|dev|run)($|/)'
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Für produktive Hosts härte ich den Dienst zusätzlich, ohne seine Leserechte auf /proc und /sys zu brechen. Das setze ich als Drop-In (/etc/systemd/system/node_exporter.service.d/hardening.conf) um:

[Service]
NoNewPrivileges=true
PrivateTmp=true
PrivateDevices=true
ProtectSystem=strict
ProtectHome=true
ProtectControlGroups=true
ProtectKernelTunables=true
ProtectKernelModules=true
LockPersonality=true
MemoryDenyWriteExecute=true
CapabilityBoundingSet=
AmbientCapabilities=
RestrictNamespaces=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
SystemCallFilter=@system-service

Nach jeder Änderung: systemctl daemon-reload und ein sauberer Neustart. Für Debug-Zwecke schalte ich temporär ein höheres Loglevel über --log.level=debug, um Sammler- und Parserdetails zu sehen.

Collector-Feinschliff für Praxisumgebungen

Ich balanciere Sichtbarkeit und Last mit gezielten Filtern:

  • Dateisysteme: Ich schließe Pseudo-FS und vergängliche Mounts aus (--collector.filesystem.fs-types-exclude und --collector.filesystem.mount-points-exclude), um unsinnige Serien zu vermeiden.
  • Prozesse: --collector.processes liefert nützliche Summen, erzeugt aber zusätzliche Serien. Ich aktiviere ihn nur auf Hosts, wo Prozesszahlen ein Signal liefern (z. B. Batch- oder Worker-Knoten).
  • Netzwerk: Der netstat-Collector kann je nach Kernel und Verbindungen viele Labels erzeugen. Ich prüfe die Kardinalität in Staging und schalte ihn sonst gezielt ab.
  • Pressure/PSI: Moderne Kernel liefern Druckmetriken (--collector.pressure, oft per Default aktiv). Ich nutze sie, um Engpässe bei CPU, IO und Speicher früh zu erkennen.
  • NVMe/RAID: Spezifische Collector (z. B. nvme) aktiviere ich nur dort, wo die Hardware vorhanden ist – so bleiben Dashboards aussagekräftig.

Ich teste Sammler selektiv über den Abfrageparameter collect[], ohne die Startparameter zu ändern. Ein Beispiel: curl 'http://localhost:9100/metrics?collect[]=systemd&collect[]=processes'. So sehe ich sofort, welchen Einfluss einzelne Collector haben.

Textfile Collector: Best Practices aus dem Betrieb

Ich schreibe Metriken atomar: Skripte erzeugen zuerst .tmp-Dateien und ersetzen diese am Ende per mv. Jede Datei enthält nur eine logische Gruppe und ist maximal wenige Kilobyte groß. Timestamp-Handling überlasse ich Prometheus; die Dateien selbst brauchen keine Zeitstempel. Entferne ich eine .prom-Datei, verschwinden die zugehörigen Serien nach dem nächsten Scrape. Ich dokumentiere Namensräume (z. B. business_*) und halte Labelwerte stabil, um Kardinalität zu kontrollieren. Wo Werte stark schwanken, glätte ich sie bereits in Skripten (z. B. per Durchschnitt), damit Dashboards ruhiger laufen.

Sicherheit: Firewall- und Proxy-Varianten

Ich setze zuerst auf Netzwerksegmentierung: Der Exporter lauscht nur intern, und die Firewall erlaubt ausschließlich die Prometheus-IPs. Ein Beispiel mit nftables auf einem Host:

table inet filter {
  chain input {
    type filter hook input priority 0;
    ct state established,related accept
    iif lo accept
    tcp dport 9100 ip saddr { 10.0.0.10, 10.0.0.11 } accept
    tcp dport 9100 drop
  }
}

Wo Verschlüsselung nötig ist, setze ich einen lokalen Reverse Proxy davor, der TLS oder mTLS übernimmt und nur zu 127.0.0.1:9100 weiterleitet. Alternativ nutze ich – sofern die Version es unterstützt – die native Web-Konfiguration des Exporters über eine --web.config.file, damit Authentisierung und Zertifikate zentral verwaltet bleiben. Grundsätzlich läuft der Dienst unprivilegiert, mit minimalen Rechten auf sein Verzeichnis und schreibend nur dort, wo es wirklich notwendig ist (z. B. Textfile-Pfad).

Prometheus-Integration im Detail: Relabeling, Limits, Alerts

Ich halte Jobs schlank und einheitlich. Ein praxistauglicher Job mit Limits und Label-Pflege sieht so aus:

scrape_configs:
- job_name: node
  scrape_interval: 30s
  scrape_timeout: 10s
  sample_limit: 10000
  static_configs:
  - targets: ['host1:9100','host2:9100']
    labels:
      env: prod
      role: web
  relabel_configs:
  - source_labels: [__address__]
    target_label: instance
    regex: '([^:]+)(?::\d+)?'
    replacement: '$1'
  metric_relabel_configs:
  - source_labels: [device]
    regex: '^(ram|loop|zram|dm-).*'
    action: drop

Mit metric_relabel_configs entschärfe ich Kardinalität, indem ich wenig aussagekräftige Geräte verwerfe. Für Alarme nutze ich einfache, aber robuste Regeln:

groups:
- name: node_basic
  rules:
  - alert: NodeDown
    expr: up{job="node"} == 0
    for: 5m
    labels: {severity: critical}
  - alert: HighCPU
    expr: 1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) > 0.9
    for: 10m
    labels: {severity: warning}

Zur Lastbeobachtung nutze ich scrape_duration_seconds und scrape_samples_scraped pro Target. So erkenne ich, wenn ein zusätzlich aktivierter Collector die Abholzeit oder Serienzahl unverhältnismäßig erhöht.

Betrieb in Containern und Kubernetes

Ich setze den Node Exporter in Containern hostnah auf, damit /proc und /sys aus dem Host sichtbar bleiben. Dazu mounte ich diese Pfade read-only in den Container und nutze hostNetwork für konsistente Ports. In Kubernetes betreibe ich den Exporter als DaemonSet je Node und halte Sicherheitskontexte restriktiv (keine unnötigen Privilegien). Cgroup-v2-Umgebungen berücksichtige ich bei der Collector-Wahl; wichtige Sammler wie meminfo, pressure, filesystem und cpu bleiben die Basis. Ich prüfe nach Deployments mit einem direkten curl gegen den Pod, ob die erwarteten Hostmetrik-Pfade wirklich gelesen werden.

Troubleshooting und Qualitätssicherung

  • Connectivity: Ich prüfe curl -s http://localhost:9100/metrics | head auf dem Zielhost und aus Sicht von Prometheus die Erreichbarkeit über den offenen Port.
  • Sammlertest: Über collect[] teste ich einzelne Collector, ohne die globale Konfiguration zu verändern.
  • Logs: Temporär erhöhe ich das Loglevel (--log.level=debug), um Parsingfehler oder Rechteprobleme an /proc//sys sichtbar zu machen.
  • Versionskontrolle: Mit node_exporter_build_info vergleiche ich Versionen und plane Upgrades gezielt.
  • Serien im Blick: Die Metrik scrape_samples_scraped{job="node"} nutze ich als Näherung für die Serienzahl je Host. Ein Sprung nach oben weist auf neue Collector oder eine Label-Explosion hin.
  • Timeouts: Ich halte scrape_timeout unterhalb von scrape_interval und beobachte scrape_timeout_seconds, um Engpässe rechtzeitig zu entdecken.

Kapazität und Aufbewahrung: Planung statt Überraschung

Ich setze die Datenaufbewahrung in Prometheus nach Use Case: kurze Intervalle für Kernsysteme, längere Aufbewahrung für Trends. Wächst die Flotte, skaliere ich horizontal per Sharding (z. B. nach Standort oder Team) und entkopple Query- und Ingest-Last. Bei Bedarf schreibe ich Metriken zusätzlich an eine Langzeitkomponente per Remote-Write. Ich behalte die Kardinalität aktiv im Blick und räume ungenutzte Metriken oder Labels konsequent auf – besonders bei Textfile-Metriken, die schnell anwachsen können.

Praxis-Tipps für heterogene Flotten

  • IPv6-Only-Hosts: Ich höre mit [::]:9100 und sorge für passende Firewall-Regeln.
  • Spezialhardware: Ich aktiviere Hardware-spezifische Collector nur dort, wo sie Sinn ergeben, und dokumentiere die Unterschiede in Rollenprofilen.
  • Rollierende Updates: Ich aktualisiere in Batches und beobachte dabei up, scrape_duration_seconds und scrape_samples_scraped, um Regressionen sofort zu erkennen.
  • Dokumentation: Ich halte die effektiven Startparameter je Rolle fest. Das spart Diskussionen und erleichtert Fehleranalysen.

Kurz zusammengefasst: mein Praxis-Fahrplan

Ich installiere den Node Exporter als eigenen systemd-Service, lege Port und Listen-Address fest und sichere den Zugriff strikt ein. Die Collector wähle ich bewusst, ergänze nötige Werte über den Textfile Collector und halte die Anzahl der Metriken klein. In Prometheus setze ich sinnvolle Intervalle, pflege Labels, definiere Recording Rules und Alarme für CPU, RAM, Platten und Netzwerk. Ich überwache den Exporter selbst, plane Updates ein und prüfe regelmäßig die Serienanzahl pro Host. Mit einer klaren Visualisierung reagiere ich schneller, erkenne Trends früh und halte mein Linux-Server-Monitoring belastbar im Alltag.

Aktuelle Artikel

Serverracks mit symbolisch isolierten Websites in CloudLinux Umgebung
Sicherheit

CloudLinux Site Isolation: Mehr Sicherheit als CageFS im Shared Hosting

CloudLinux Site Isolation bietet im shared hosting zusätzlichen Schutz gegenüber CageFS, indem einzelne Websites innerhalb eines Accounts isoliert werden. Die Domain‑basierte Trennung erhöht die cloudlinux security deutlich und schützt Multi‑Site‑Installationen effektiv.