Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Monitoring 15.06.2026 · 9 min Lesezeit

Prometheus node_exporter nativ installieren und als systemd-Dienst betreiben

Den Prometheus-Linux-Agenten als Binary mit eigenem Systembenutzer und gehärteter systemd-Unit direkt auf dem Host einrichten, ohne Docker, damit Kernel- und Hardware-Metriken ungefiltert erfasst werden.

Geprüft am 30.09.2026 · für node_exporter 1.12.1

WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Rack-Server mit leuchtenden Status-LEDs und gebündelten Netzwerkkabeln in einem Serverschrank

Der Prometheus-node_exporter liefert CPU-Last, RAM, Disk-I/O, Netzwerkdurchsatz, Temperaturen und viele weitere Kennzahlen direkt aus dem Linux-Kernel. Für den Produktivbetrieb eignet sich die native Binary-Installation mit eigenem Systembenutzer und gehärteter systemd-Unit: Der Exporter sieht /proc und /sys ungefiltert, der Overhead bleibt minimal. Diese Anleitung führt Sie von der SHA256-Prüfung des Downloads über die Absicherung bis zum Prometheus-Scraping-Job und zur Firewall-Regel.

Voraussetzungen

  1. Linux-Server mit systemd (Debian/Ubuntu, RHEL/CentOS/Fedora, SUSE und kompatible Distributionen)
  2. Root- oder sudo-Zugriff für Installation und Dienstkonfiguration
  3. Internetverbindung zum Herunterladen des Binaries von GitHub (alternativ: manueller Transfer)
  4. wget oder curl sowie sha256sum im PATH vorhanden
  5. Optional: laufender Prometheus-Server (Version 3.x) im gleichen Netz oder mit Firewall-Freigabe auf Port 9100
  6. Optional: Grafana-Instanz für Dashboards (Dashboard-ID 1860 „Node Exporter Full“)
  7. Ressourcen: node_exporter selbst braucht unter 50 MB RAM; jeder kleine Server (1 Kern, 512 MB RAM, x86_64 oder ARM64) genügt

Warum nativ statt Docker?

Der node_exporter ist absichtlich als reiner Pull-Exporter gebaut: Er schreibt selbst keine Daten, braucht keine Root-Rechte im Betrieb und liest ausschließlich /proc, /sys, Syscalls und lokale Sockets. In einem Docker-Container müssen diese Pfade explizit eingehängt werden – und selbst dann fehlen manche Kernel-Metriken, weil das Container-Namespacing sie abschirmt. Auf dem nackten Host hingegen sieht der Exporter alles, was der Kernel bereitstellt: NUMA-Topologien, Hardware-Temperatures über hwmon, NVMe-Gesundheitsdaten und Linux PSI (Pressure Stall Information). Der Overhead eines einzelnen statisch gelinkten Binarys ist gering.

MethodeRoot nötigKernel-ZugriffOverheadHärtbarEmpfehlung
Nativ (Binary + systemd)nur SetupvollständigminimaljaProduktion
Dockerja (Daemon)eingeschränktmoderatbedingtDev/Test
Paketmanager (apt/yum)javollständigminimaljaDistro-spezifisch

Schritt 1: Systembenutzer anlegen

Der node_exporter braucht im laufenden Betrieb keine root-Rechte. Legen Sie einen Systembenutzer ohne Home-Verzeichnis und ohne Login-Shell an; die systemd-Unit verweist darauf:

sudo useradd --system --no-create-home --shell /sbin/nologin node_exporter

Das Flag --system legt einen Benutzer mit einer UID unterhalb von 1000 an, --no-create-home verhindert ein Home-Verzeichnis und --shell /sbin/nologin sperrt interaktive Logins dauerhaft. Auf Systemen ohne /sbin/nologin verwenden Sie /usr/sbin/nologin.

Verifizieren: id node_exporter zeigt eine UID unter 1000, getent passwd node_exporter endet auf nologin.

Schritt 2: Binary herunterladen und SHA256 verifizieren

Laden Sie das Tarball und die offizielle Prüfsummendatei von GitHub herunter. Die Prüfsumme belegt, dass die Datei unverändert ist. Auf ARM-Servern setzen Sie ARCH="linux-arm64".

VERSION="1.12.1"
ARCH="linux-amd64"

wget "https://github.com/prometheus/node_exporter/releases/download/v${VERSION}/node_exporter-${VERSION}.${ARCH}.tar.gz"
wget "https://github.com/prometheus/node_exporter/releases/download/v${VERSION}/sha256sums.txt"

# Prüfsumme verifizieren
sha256sum --check --ignore-missing sha256sums.txt

Verifizieren: Die Ausgabe muss lauten: node_exporter-1.12.1.linux-amd64.tar.gz: OK. Bei FAILED laden Sie erneut herunter. Die SHA256 des AMD64-Tarballs lautet: b51d8a76aa2a9156a55d501aca6276fae09e262259a5e4e831d2c2222f084e63.

Schritt 3: Binary installieren

Entpacken Sie das Archiv und kopieren Sie das Binary nach /usr/sbin/; die systemd-Unit verweist exakt auf diesen Pfad.

tar xvfz "node_exporter-${VERSION}.${ARCH}.tar.gz"

sudo cp "node_exporter-${VERSION}.${ARCH}/node_exporter" /usr/sbin/node_exporter
sudo chown root:root /usr/sbin/node_exporter
sudo chmod 755 /usr/sbin/node_exporter

Das Binary gehört root:root und ist für alle ausführbar – so kann der Systembenutzer node_exporter es starten, ohne Eigentümer zu sein. Tarball-Verzeichnis und Prüfsummendatei können Sie danach löschen.

Verifizieren: /usr/sbin/node_exporter --version meldet node_exporter, version 1.12.1.

Schritt 4: Verzeichnis für den Textfile Collector

Über den Textfile Collector speisen Sie eigene Metriken aus Skripten oder Cron-Jobs ein: Eine Datei mit der Endung .prom im festgelegten Verzeichnis liest der Exporter beim nächsten Scrape.

sudo mkdir -p /var/lib/node_exporter/textfile_collector
sudo chown -R node_exporter:node_exporter /var/lib/node_exporter

Aktiviert wird das Verzeichnis in Schritt 5 über die Sysconfig-Datei. Ohne Bedarf können Sie diesen Schritt überspringen.

Verifizieren: ls -ld /var/lib/node_exporter/textfile_collector zeigt Eigentümer node_exporter.

Schritt 5: Optionale Flags in der Sysconfig-Datei

Legen Sie eine Datei für Startparameter an, damit die systemd-Unit unverändert bleibt. systemd liest sie zeilenweise und ersetzt keine Variablen: Tragen Sie alle Flags in eine OPTIONS-Zeile ein, eine spätere OPTIONS-Zeile überschreibt die frühere.

sudo mkdir -p /etc/sysconfig
sudo tee /etc/sysconfig/node_exporter <<'EOF'
# Startparameter fuer node_exporter
# Leer lassen fuer Default-Verhalten (Port 9100, alle Standard-Collector)
OPTIONS="--collector.textfile.directory=/var/lib/node_exporter/textfile_collector"

# Beispiel mit Loopback-Binding (Prometheus auf demselben Host), statt der Zeile oben:
# OPTIONS="--collector.textfile.directory=/var/lib/node_exporter/textfile_collector --web.listen-address=127.0.0.1:9100"
EOF

Debian/Ubuntu nutzen für solche Dateien üblicherweise /etc/default/. Wählen Sie dort /etc/default/node_exporter, passen Sie den EnvironmentFile-Pfad in der Unit an.

Verifizieren: grep -c '^OPTIONS=' /etc/sysconfig/node_exporter liefert 1.

Schritt 6: Gehärtete systemd-Unit anlegen

Die Härtungs-Direktiven der systemd-Unit beschränken den Prozess auf Lesezugriff; mehr als /proc und /sys braucht der Exporter nicht:

sudo tee /etc/systemd/system/node_exporter.service <<'EOF'
[Unit]
Description=Prometheus Node Exporter
Documentation=https://prometheus.io/docs/guides/node-exporter/
Wants=network-online.target
After=network-online.target

[Service]
User=node_exporter
Group=node_exporter
EnvironmentFile=-/etc/sysconfig/node_exporter
ExecStart=/usr/sbin/node_exporter $OPTIONS
Restart=on-failure
RestartSec=5s

# Haertungs-Direktiven
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectControlGroups=yes
CapabilityBoundingSet=
ReadOnlyPaths=/proc /sys
ReadWritePaths=/var/lib/node_exporter

[Install]
WantedBy=multi-user.target
EOF

Das Minus-Zeichen vor dem EnvironmentFile-Pfad bewirkt, dass systemd den Start nicht abbricht, wenn die Datei nicht existiert. CapabilityBoundingSet= (leer) entzieht dem Prozess alle Linux-Capabilities – falls dabei Collector-Metriken fehlen, hilft ein Blick ins Journal (siehe Troubleshooting).

Läuft Prometheus auf demselben Host, binden Sie den Exporter nur an Loopback (Beispielzeile in Schritt 5); Port 9100 ist dann von außen nicht erreichbar.

Verifizieren: systemd-analyze verify /etc/systemd/system/node_exporter.service gibt keine Fehler aus; systemd-analyze security node_exporter zeigt nach dem Start in Schritt 7 eine niedrige Expositionsbewertung.

Schritt 7: Dienst aktivieren und starten

sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter

Verifizieren: Der Status sollte active (running) zeigen:

sudo systemctl status node_exporter

Anschließend den Metriken-Endpunkt direkt abfragen:

curl http://localhost:9100/metrics | head -20

Die Ausgabe beginnt mit Zeilen wie # HELP go_gc_duration_seconds ... und Metrik-Werten. ss -tlnp | grep 9100 zeigt die gebundene Adresse.

Verfügbare Collector-Module

Über 40 Collector sind standardmäßig aktiv. Die wichtigsten auf einen Blick:

CollectorBeschreibungDefault
cpuCPU-Auslastung (user/system/idle/iowait)aktiv
meminfoRAM und Swapaktiv
diskstatsDisk-I/O, Latenz, IOPSaktiv
filesystemFüllstand, Inodesaktiv
netdevNetzwerk-Bytes/Pakete je Interfaceaktiv
loadavg1/5/15-Minuten-Lastdurchschnittaktiv
hwmonTemperaturen, Lüfter, Spannungenaktiv
nvmeNVMe-SSD-Gesundheitsdatenaktiv
pressureLinux PSI (CPU/IO/Memory-Druck)aktiv
vmstatKernel VM-Statistikenaktiv
raplCPU-Energieverbrauch (Intel RAPL)aktiv
ethtoolNIC-Detailstatistiken (hohe Kardinalität)deaktiviert
interruptsIRQ-Statistiken (sehr hohe Kardinalität)deaktiviert
systemdsystemd-Unit-Metrikendeaktiviert
wifiWLAN-Signaldatendeaktiviert

Ressourcenintensive Collector wie ethtool oder interrupts erzeugen eine sehr hohe Anzahl an Zeitreihenwerten und können die Prometheus-TSDB merklich belasten. Aktivieren Sie sie nur für eine konkrete Diagnose.

Schritt 8: Prometheus scrape_config einrichten

Ergänzen Sie in der prometheus.yml Ihres Prometheus-Servers einen Scraping-Job:

scrape_configs:
  - job_name: node
    scrape_interval: 30s
    scrape_timeout: 10s
    static_configs:
      - targets: ['localhost:9100']
        labels:
          instance: 'mein-server-01'

Bei mehreren Hosts ersetzen Sie localhost:9100 durch eine Liste aller Ziele oder nutzen file_sd_configs. Nach einem Reload (systemctl reload prometheus, oder /-/reload bei gesetztem --web.enable-lifecycle) erscheint der Job in der Prometheus-Oberfläche unter „Targets“.

Verifizieren: In der Prometheus-Web-UI unter http://<prometheus>:9090/targets muss der node-Job mit Status UP erscheinen.

Schritt 9: Firewall-Regel setzen

Der Metriken-Endpunkt hat keine Authentifizierung. Geben Sie Port 9100 nur für den Prometheus-Server frei, nie ins ganze Netz oder Internet. Läuft Prometheus auf einem anderen Host:

# ufw (Debian/Ubuntu)
sudo ufw allow from <prometheus-server-ip> to any port 9100 proto tcp

# firewalld (RHEL/Fedora/SUSE)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="<prometheus-server-ip>" port protocol="tcp" port="9100" accept'
sudo firewall-cmd --reload

Ersetzen Sie <prometheus-server-ip> durch die IP Ihres Prometheus-Servers. Bei Loopback-Binding ist keine Regel nötig.

Verifizieren: Von einem dritten Rechner liefert curl -m 5 http://<server>:9100/metrics einen Timeout, vom Prometheus-Server aus Metriken.

Schritt 10: Grafana-Dashboard einrichten

Das offiziell empfohlene Dashboard „Node Exporter Full“ (Grafana.com Dashboard-ID 1860) bietet umfassende Panels für alle Standard-Collector. Importieren Sie es über Dashboards → New → Import → ID 1860 → Prometheus als Datenquelle.

Verifizieren: Im Dashboard zeigt die Auswahl „Host“ Ihren Server, und die Panels für CPU, RAM und Disk enthalten Werte.

Troubleshooting / Typische Fehler

Dienst startet nicht – „Permission denied“ im Journal

Prüfen Sie zunächst das Journal:

journalctl -u node_exporter -f

Wenn ProtectSystem=strict den Zugriff auf den Textfile-Collector-Pfad blockiert, prüfen Sie, ob ReadWritePaths=/var/lib/node_exporter in der Unit-Datei enthalten ist. Nach jeder Änderung an der Unit-Datei: sudo systemctl daemon-reload && sudo systemctl restart node_exporter.

Bestimmte Metriken fehlen nach CapabilityBoundingSet= leer

Ein leeres CapabilityBoundingSet= entzieht alle Linux-Capabilities. Manche Netzwerkstatistiken benötigen AF_NETLINK, das ohne spezielle Capabilities funktioniert – erscheinen dennoch Fehler, testen Sie mit CapabilityBoundingSet=CAP_NET_ADMIN, ob die Metriken zurückkehren. Im Zweifel die Härtungsdirektive auf ProtectSystem=full zurückstufen, das weniger restriktiv ist.

Binary-Update schlägt fehl oder produziert inkonsistente Metriken

Beim Update niemals das laufende Binary direkt überschreiben – das führt zu einem „Text file busy“-Fehler. Reihenfolge: Dienst stoppen, Binary ersetzen, Dienst starten:

sudo systemctl stop node_exporter
sudo cp "node_exporter-${NEUE_VERSION}.${ARCH}/node_exporter" /usr/sbin/node_exporter
sudo systemctl start node_exporter

Port 9100 von außen erreichbar, obwohl nicht gewollt

Der Exporter lauscht standardmäßig auf 0.0.0.0:9100. Ohne Firewall-Regel ist der Metriken-Endpunkt ohne jede Authentifizierung von außen erreichbar. Entweder die Firewall-Regel aus Schritt 9 setzen oder --web.listen-address=127.0.0.1:9100 in die Sysconfig-Datei eintragen und den Dienst neu starten.

Falscher Binary-Pfad in der Unit-Datei

Liegt das Binary in /usr/local/bin/ statt /usr/sbin/, passen Sie die ExecStart-Zeile in der Unit-Datei entsprechend an an und führen systemctl daemon-reload aus.

Häufige Fragen

Brauche ich Root-Rechte für den Betrieb?

Nein. Root-Rechte brauchen Sie nur für die Installation; der Prozess läuft als unprivilegierter Benutzer node_exporter.

Wie aktualisiere ich node_exporter auf eine neue Version?

Wie im Troubleshooting beschrieben: neues Tarball laden, SHA256 prüfen, Dienst stoppen, Binary ersetzen, starten. Vorher das CHANGELOG auf geänderte Flags prüfen.

Was ist der Unterschied zwischen direktem Lauschen und Socket Activation?

Beim direkten Lauschen (Standard dieser Anleitung) öffnet der node_exporter selbst den TCP-Port 9100. Bei Socket Activation – dem offiziellen Ansatz aus dem GitHub-Repo unter examples/systemd – verwaltet systemd den Socket und übergibt ihn per --web.systemd-socket-Flag. Das ermöglicht feinere Berechtigungssteuerung und einen Neustart des Dienstes ohne verlorene TCP-Verbindungen. Für die meisten KMU-Setups genügt der direkte Ansatz.

Kann ich node_exporter auf mehrere Server ausrollen?

Ja, Binary und Unit sind auf allen systemd-Hosts gleich (bei gleicher Architektur). Für viele Hosts eignen sich Ansible, Salt oder Puppet. Prometheus kann alle Server über static_configs mit einer Liste von Targets oder über dynamische Service Discovery (file_sd_configs, consul_sd_configs) scrapen.

Was tun, wenn nach ProtectSystem=strict bestimmte Metriken fehlen?

Im Journal (journalctl -u node_exporter -f) nach Permission-Fehlern suchen. Mit ReadWritePaths= oder ReadOnlyPaths= gezielt Ausnahmen definieren. Alternativ auf ProtectSystem=full wechseln – das schützt /etc und /usr, lässt aber /var schreibbar, was die meisten Permission-Probleme löst ohne die Härtung vollständig aufzugeben.

Welches Grafana-Dashboard eignet sich am besten?

„Node Exporter Full“ (ID 1860 auf grafana.com) deckt alle Standard-Collector ab, inklusive Temperaturen und Energieverbrauch bei passender Hardware.

Fazit

Die native Installation dauert etwa 20 Minuten und bietet gegenüber Docker ungefilterten Kernel-Zugriff bei minimalem Overhead. Systembenutzer ohne Login-Shell, ProtectSystem=strict und leeres CapabilityBoundingSet beschränken den Prozess auf das Nötige. Entscheidend für die Sicherheit bleibt, Port 9100 nur für Prometheus freizugeben.

Weiterführende Anleitungen und Quellen

  1. Prometheus Alerts an Telegram und Discord senden: Alertmanager konfigurieren
  2. cAdvisor mit Prometheus: Docker-Container-Metriken sammeln und in Grafana visualisieren
  3. Logs zentralisieren mit Grafana Loki
  4. systemd-Service selbst erstellen und verwalten
  5. Zabbix-Proxy nativ aufsetzen – APT-Installation und aktiver/passiver Modus
  6. Prometheus – Node Exporter Installation Guide (offiziell)
  7. GitHub – prometheus/node_exporter (Repo + README)
  8. GitHub – node_exporter/examples/systemd (offizielle Unit-Dateien)
  9. Prometheus Downloads – aktuelle Versionen und SHA256