Prometheus node_exporter nativ installieren und als systemd-Dienst betreiben
Den Prometheus-Linux-Agenten als Binary mit dediziertem Systembenutzer und gehärtetem systemd-Unit direkt auf dem Host aufsetzen – ohne Docker, damit Kernel- und Hardware-Metriken ungefiltert erfasst werden.

Wer Server-Metriken mit Prometheus erfassen will, kommt am node_exporter nicht vorbei: Er liefert CPU-Last, RAM-Auslastung, Disk-I/O, Netzwerkdurchsatz, Temperaturen und Dutzende weitere Kennzahlen direkt aus dem Linux-Kernel – ohne eigene Datenbank, ohne Cloud-Abhängigkeit. Die eleganteste Variante für den Produktionseinsatz ist die native Binary-Installation mit einem dedizierten Systembenutzerkonto und einer gehärteten systemd-Unit. Im Vergleich zu einem Docker-Container erhält der Exporter so ungefilterten Zugriff auf /proc und /sys, während der Overhead minimal bleibt. Diese Anleitung führt dich Schritt für Schritt durch Installation, Absicherung und Integration in einen Prometheus-Scraping-Job – von der SHA256-Prüfung des Downloads bis zur Firewall-Regel.
Voraussetzungen
- Linux-Server mit systemd (Debian/Ubuntu, RHEL/CentOS/Fedora, SUSE und kompatible Distributionen)
- Root- oder sudo-Zugriff für Installation und Dienstkonfiguration
- Internetverbindung zum Herunterladen des Binaries von GitHub (alternativ: manueller Transfer)
- wget oder curl sowie sha256sum im PATH vorhanden
- Optional: laufender Prometheus-Server (empfohlen: Version 3.12.0) im gleichen Netz oder mit Firewall-Freigabe auf Port 9100
- Optional: Grafana-Instanz für Dashboards (Dashboard-ID 1860 „Node Exporter Full")
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 ist mit einem einzigen statisch gelinkten Binary verschwindend gering.
| Methode | Root nötig | Kernel-Zugriff | Overhead | Härtbar | Empfehlung |
|---|---|---|---|---|---|
| Nativ (Binary + systemd) | nur Setup | vollständig | minimal | ja | Produktion |
| Docker | ja (Daemon) | eingeschränkt | moderat | bedingt | Dev/Test |
| Paketmanager (apt/yum) | ja | vollständig | minimal | ja | Distro-spezifisch |
Schritt 1: Systembenutzer anlegen
Der node_exporter braucht im laufenden Betrieb keine root-Rechte. Ein dedizierter Systembenutzer ohne Home-Verzeichnis und ohne Login-Shell ist Pflicht – sowohl aus Sicherheitsgründen als auch weil die systemd-Unit direkt darauf verweist:
sudo useradd --system --no-create-home --shell /sbin/nologin node_exporterDas 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 kann alternativ /usr/sbin/nologin verwendet werden.
Schritt 2: Binary herunterladen und SHA256 verifizieren
Lade das Tarball und die offizielle Prüfsummendatei direkt von GitHub herunter. Die Verifikation ist kein optionaler Schritt – sie stellt sicher, dass das Binary auf dem Transportweg nicht verändert wurde:
VERSION="1.11.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.txtVerifizieren: Die Ausgabe muss lauten: node_exporter-1.11.1.linux-amd64.tar.gz: OK. Erscheint stattdessen FAILED, den Download wiederholen und die Netzwerkverbindung prüfen. Die SHA256 des AMD64-Tarballs lautet: 9f5ea48e5bc7b656f8a91a32e7d7deb89f70f73dabd0d974418aca15f37d6810.
Schritt 3: Binary installieren
Entpacke das Archiv und kopiere das Binary nach /usr/sbin/. Der Pfad ist wichtig: Die systemd-Unit verweist später exakt auf diesen Ort.
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_exporterDas 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. Das Tarball-Verzeichnis und die Prüfsummendatei können danach gelöscht werden.
Schritt 4: Verzeichnis für den Textfile Collector
Der Textfile Collector ermöglicht es, eigene Metriken aus Shell-Skripten oder Cron-Jobs in Prometheus einzuspeisen. Dazu legt man eine Datei mit der Endung .prom in einem festgelegten Verzeichnis ab – der Exporter liest sie beim nächsten Scrape ein:
sudo mkdir -p /var/lib/node_exporter/textfile_collector
sudo chown -R node_exporter:node_exporter /var/lib/node_exporterDieses Verzeichnis wird erst in Schritt 6 über die Sysconfig-Datei aktiviert. Falls du den Textfile Collector nicht benötigst, kannst du diesen Schritt überspringen – das Verzeichnis schadet aber nicht.
Schritt 5: Optionale Flags in der Sysconfig-Datei
Lege eine Konfigurationsdatei an, über die du dem node_exporter Startparameter übergeben kannst, ohne die systemd-Unit selbst zu ändern:
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"
# Loopback-Binding, wenn Prometheus lokal laeuft:
# OPTIONS="$OPTIONS --web.listen-address=127.0.0.1:9100"
# Ressourcenintensive Collector gezielt aktivieren:
# OPTIONS="$OPTIONS --collector.ethtool"
EOFAuf Debian/Ubuntu liegt die Sysconfig-Datei üblicherweise unter /etc/default/node_exporter statt /etc/sysconfig/. Passe den EnvironmentFile-Pfad in der Unit-Datei entsprechend an.
Schritt 6: Gehärtete systemd-Unit anlegen
Das Herzstück der nativen Installation ist die systemd-Unit. Die Härtungs-Direktiven beschränken den Prozess auf das absolute Minimum an Systemzugriff – mehr als /proc und /sys lesen braucht der Exporter ohnehin 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
EOFDas 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).
Wenn der Prometheus-Server auf demselben Host läuft, ist es sinnvoll, den Exporter nur auf Loopback lauschen zu lassen. Füge dazu in /etc/sysconfig/node_exporter die Option --web.listen-address=127.0.0.1:9100 hinzu – so ist Port 9100 von außen nicht erreichbar.
Schritt 7: Dienst aktivieren und starten
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporterVerifizieren: Der Status sollte active (running) zeigen:
sudo systemctl status node_exporterAnschließend den Metriken-Endpunkt direkt abfragen:
curl http://localhost:9100/metrics | head -20Die Ausgabe beginnt mit Kommentarzeilen wie # HELP go_gc_duration_seconds ... gefolgt von Metrik-Werten. Erscheint die Ausgabe, ist der Exporter betriebsbereit.
Verfügbare Collector-Module
Über 40 Collector sind standardmäßig aktiv. Die wichtigsten auf einen Blick:
| Collector | Beschreibung | Default |
|---|---|---|
| cpu | CPU-Auslastung (user/system/idle/iowait) | aktiv |
| meminfo | RAM und Swap | aktiv |
| diskstats | Disk-I/O, Latenz, IOPS | aktiv |
| filesystem | Füllstand, Inodes | aktiv |
| netdev | Netzwerk-Bytes/Pakete je Interface | aktiv |
| loadavg | 1/5/15-Minuten-Lastdurchschnitt | aktiv |
| hwmon | Temperaturen, Lüfter, Spannungen | aktiv |
| nvme | NVMe-SSD-Gesundheitsdaten | aktiv |
| pressure | Linux PSI (CPU/IO/Memory-Druck) | aktiv |
| vmstat | Kernel VM-Statistiken | aktiv |
| rapl | CPU-Energieverbrauch (Intel RAPL) | aktiv |
| ethtool | NIC-Detailstatistiken (hohe Kardinalität) | deaktiviert |
| interrupts | IRQ-Statistiken (sehr hohe Kardinalität) | deaktiviert |
| systemd | systemd-Unit-Metriken | deaktiviert |
| wifi | WLAN-Signaldaten | deaktiviert |
Ressourcenintensive Collector wie ethtool oder interrupts erzeugen eine sehr hohe Anzahl an Zeitreihenwerten und können die Prometheus-TSDB merklich belasten. Aktiviere sie nur, wenn du konkrete Diagnosegründe hast.
Schritt 8: Prometheus scrape_config einrichten
Füge in der prometheus.yml deines Prometheus-Servers einen neuen Scraping-Job hinzu:
scrape_configs:
- job_name: node
scrape_interval: 30s
scrape_timeout: 10s
static_configs:
- targets: ['localhost:9100']
labels:
instance: 'mein-server-01'Bei mehreren Hosts ersetze localhost:9100 durch eine Liste aller Ziele oder nutze file_sd_configs für dynamische Service Discovery. Nach einem Reload des Prometheus-Servers (systemctl reload prometheus oder HTTP-Trigger auf /-/reload) 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
Port 9100 sollte nur für den Prometheus-Server erreichbar sein – niemals offen ins gesamte Netz oder gar ins Internet. Wenn Prometheus auf einem anderen Host läuft:
# 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 --reloadErsetze <prometheus-server-ip> durch die tatsächliche IP-Adresse deines Prometheus-Servers. Wenn beide Dienste auf demselben Host laufen und du --web.listen-address=127.0.0.1:9100 gesetzt hast, ist keine Firewall-Regel erforderlich.
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. Importiere es in Grafana über Dashboards → Import → Dashboard-ID 1860 eingeben → Prometheus als Datenquelle wählen. Innerhalb weniger Sekunden hast du CPU-, RAM-, Disk- und Netzwerk-Panels für jeden gescrapeten Host.
Troubleshooting / Typische Fehler
Dienst startet nicht – „Permission denied" im Journal
Prüfe zunächst das Journal:
journalctl -u node_exporter -fWenn ProtectSystem=strict den Schreibzugriff auf den Textfile-Collector-Pfad blockiert, stelle sicher, dass 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, teste mit CapabilityBoundingSet=CAP_NET_ADMIN und beobachte, 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. Immer in dieser Reihenfolge vorgehen: Dienst stoppen → Binary ersetzen → systemctl daemon-reload → Dienst starten:
sudo systemctl stop node_exporter
sudo cp "node_exporter-${NEUE_VERSION}.${ARCH}/node_exporter" /usr/sbin/node_exporter
sudo systemctl daemon-reload
sudo systemctl start node_exporterPort 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
Wenn du das Binary nach /usr/local/bin/ statt /usr/sbin/ kopiert hast, passe die ExecStart-Zeile in der Unit-Datei entsprechend an und führe systemctl daemon-reload aus.
Häufige Fragen
Brauche ich Root-Rechte für den Betrieb?
Nein. Root-Rechte sind nur für die einmalige Installation notwendig: Binary nach /usr/sbin/ kopieren, Systembenutzer anlegen und die systemd-Unit einrichten. Der laufende Prozess läuft danach dauerhaft als unprivilegierter Benutzer node_exporter und liest ausschließlich /proc, /sys, Syscalls und lokale Sockets.
Wie aktualisiere ich node_exporter auf eine neue Version?
Neues Tarball von GitHub herunterladen, SHA256 verifizieren, Dienst stoppen, Binary ersetzen, systemctl daemon-reload ausführen, Dienst neu starten. Die systemd-Unit und die Sysconfig-Datei bleiben in der Regel unverändert – außer neue Versionen bringen inkompatible Flags mit sich.
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 ist der direkte Ansatz ausreichend und einfacher zu verstehen.
Kann ich node_exporter auf mehrere Server ausrollen?
Ja – das Binary und die Unit-Datei sind auf allen Linux-Hosts mit systemd identisch. Für größere Umgebungen bieten sich Ansible, Salt oder Puppet zur automatisierten Verteilung an. 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?
Das offiziell empfohlene „Node Exporter Full" (Dashboard-ID 1860 auf grafana.com) deckt alle Standard-Collector vollständig ab und wird aktiv gepflegt. Es enthält Panels für CPU, RAM, Disk-I/O, Netzwerk, Dateisystem, Kernel-VM-Statistiken und bei kompatibler Hardware auch Temperaturen und Energieverbrauch.
Fazit
Die native Binary-Installation des node_exporters ist in etwa 20 Minuten erledigt und bringt gegenüber einem Docker-Container echte Vorteile: vollständiger, ungefilteter Kernel-Zugriff, minimaler Overhead und eine sauber gehärtete systemd-Unit, die den Prozess auf das Nötigste beschränkt. Der dedizierte Systembenutzer ohne Login-Shell, ProtectSystem=strict und ein leeres CapabilityBoundingSet ergeben zusammen eine Sicherheitskonfiguration, die auch für KMU-Produktionsserver geeignet ist. Wer Prometheus und Grafana bereits betreibt, schließt mit dieser Anleitung die letzte Lücke im Monitoring-Stack und bekommt mit dem Dashboard 1860 sofort einen vollständigen Überblick über seine Server-Infrastruktur.
Weiterführende Anleitungen und Quellen
- Prometheus Alerts an Telegram und Discord senden: Alertmanager konfigurieren
- cAdvisor mit Prometheus: Docker-Container-Metriken sammeln und in Grafana visualisieren
- Logs zentralisieren mit Grafana Loki
- systemd-Service selbst erstellen und verwalten
- Zabbix-Proxy nativ aufsetzen – APT-Installation und aktiver/passiver Modus
- Prometheus – Node Exporter Installation Guide (offiziell)
- GitHub – prometheus/node_exporter (Repo + README)
- GitHub – node_exporter/examples/systemd (offizielle Unit-Dateien)
- Prometheus Downloads – aktuelle Versionen und SHA256