TL;DR — Kurzzusammenfassung

Prometheus mit Node Exporter für Linux-Server-Monitoring einrichten. PromQL, Alarmregeln, Alertmanager, Speicher-Tuning und Sicherheit für die Produktion.

Prometheus ist der De-facto-Standard für Open-Source-Infrastruktur-Monitoring. In Kombination mit Node Exporter bietet es tiefe Einblicke in jeden Linux-Server Ihrer Flotte — CPU-Auslastung, Speicherdruck, Festplatten-Sättigung, Netzwerkdurchsatz und Lastwerte — alles abfragbar mit einer leistungsstarken Ausdruckssprache und über Alertmanager alarmierbar. Dieser Leitfaden führt von der Installation bis zu einem produktionsreifen Monitoring-Stack.

Voraussetzungen

  • Ubuntu 22.04 oder Debian 12 (identisch auf RHEL/Rocky mit dnf statt apt)
  • Root- oder sudo-Zugriff
  • Ports 9090 (Prometheus), 9100 (Node Exporter) und 9093 (Alertmanager) in der Firewall geöffnet
  • Grundkenntnisse in systemd und YAML

Architektur-Überblick

Prometheus verwendet ein Pull-Modell: Es scrapt HTTP-Endpunkte, sogenannte Targets, in konfigurierbaren Intervallen und speichert die Zeitreihendaten lokal in einer spaltenbasierten Datenbank (TSDB).

┌─────────────────────────────────────────────────────────┐
│                   Linux-Server                           │
│                                                          │
│   Node Exporter :9100  ←  Prometheus :9090  →  Grafana  │
│         ↑                      ↓                         │
│   /proc /sys              TSDB auf Disk                  │
│                                ↓                         │
│                          Alertmanager :9093              │
│                          (E-Mail/Slack/PD)               │
└─────────────────────────────────────────────────────────┘

Schlüsselkonzepte:

  • Scrape — Prometheus holt /metrics von jedem Target im scrape_interval
  • TSDB — Lokale Zeitreihendatenbank; jede Metrik ist ein float64-Wert mit Zeitstempel und Labels
  • PromQL — Abfragesprache zum Slicen, Aggregieren und Ratenberechnung über Zeitreihen
  • Alertmanager — Separater Prozess, der Alarme von Prometheus empfängt und Benachrichtigungen weiterleitet

Schritt 1: Prometheus installieren

Systembenutzer und Verzeichnisse erstellen

sudo useradd --system --no-create-home --shell /bin/false prometheus

sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus /var/lib/prometheus

Binary herunterladen und installieren

PROM_VERSION="2.51.2"
cd /tmp
wget "https://github.com/prometheus/prometheus/releases/download/v${PROM_VERSION}/prometheus-${PROM_VERSION}.linux-amd64.tar.gz"
tar xzf prometheus-${PROM_VERSION}.linux-amd64.tar.gz
cd prometheus-${PROM_VERSION}.linux-amd64

sudo cp prometheus promtool /usr/local/bin/
sudo chown prometheus:prometheus /usr/local/bin/prometheus /usr/local/bin/promtool
sudo cp -r consoles console_libraries /etc/prometheus/
sudo chown -R prometheus:prometheus /etc/prometheus/consoles /etc/prometheus/console_libraries

prometheus.yml schreiben

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    environment: "production"

rule_files:
  - /etc/prometheus/rules/*.yml

alerting:
  alertmanagers:
    - static_configs:
        - targets: ["localhost:9093"]

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]

  - job_name: "node"
    static_configs:
      - targets: ["localhost:9100"]
    labels:
      instance: "web-01"
sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml
promtool check config /etc/prometheus/prometheus.yml

systemd-Unit erstellen

[Unit]
Description=Prometheus Monitoring-System
After=network.target

[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --storage.tsdb.retention.time=30d \
  --web.listen-address=0.0.0.0:9090 \
  --web.enable-lifecycle

Restart=on-failure
RestartSec=5s
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/prometheus

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
sudo systemctl status prometheus

Schritt 2: Node Exporter installieren

Node Exporter exponiert Hardware- und OS-Metriken aus /proc und /sys auf Port 9100.

NODE_VERSION="1.7.0"
cd /tmp
wget "https://github.com/prometheus/node_exporter/releases/download/v${NODE_VERSION}/node_exporter-${NODE_VERSION}.linux-amd64.tar.gz"
tar xzf node_exporter-${NODE_VERSION}.linux-amd64.tar.gz

sudo useradd --system --no-create-home --shell /bin/false node_exporter
sudo cp node_exporter-${NODE_VERSION}.linux-amd64/node_exporter /usr/local/bin/
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
[Unit]
Description=Prometheus Node Exporter
After=network.target

[Service]
Type=simple
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter \
  --collector.systemd \
  --collector.processes

Restart=on-failure
NoNewPrivileges=true
ProtectSystem=strict

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
curl -s http://localhost:9100/metrics | head -20

Wichtige Node-Exporter-Metriken

MetrikBeschreibung
node_cpu_seconds_totalCPU-Zeit nach Modus (user, system, idle) — mit rate() verwenden
node_memory_MemAvailable_bytesVerfügbarer Speicher (inkl. rückforderbarem Cache)
node_memory_MemTotal_bytesGesamter physischer Speicher
node_filesystem_avail_bytesFreier Festplattenspeicher
node_network_receive_bytes_totalEmpfangene Bytes pro Netzwerkschnittstelle — mit rate() verwenden
node_load1 / node_load5 / node_load15System-Lastwerte
node_disk_io_time_seconds_totalZeit in I/O — rate() für Sättigung verwenden

PromQL-Grundlagen

Öffnen Sie die Prometheus-UI unter http://ihr-server:9090 zum Experimentieren.

CPU-Auslastung in Prozent

100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Speicherauslastung in Prozent

(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

Festplattenauslastung in Prozent

(1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs"} / node_filesystem_size_bytes)) * 100

Wichtige PromQL-Funktionen

FunktionZweck
rate()Durchschnittliche Rate pro Sekunde über ein Intervall
increase()Gesamter Anstieg über ein Intervall
histogram_quantile()P99-Latenz aus einer Histogramm-Metrik
avg by()Durchschnitt über eine Dimension
topk()Die N höchsten Zeitreihen nach Wert
predict_linear()Prognostiziert den Wert in N Sekunden

Alarmregeln

# /etc/prometheus/rules/alerts.yml
groups:
  - name: node_alerts
    interval: 30s
    rules:

      - alert: HoheCPUAuslastung
        expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Hohe CPU-Auslastung auf {{ $labels.instance }}"
          description: "CPU-Auslastung beträgt {{ $value | printf \"%.1f\" }}% seit mehr als 5 Minuten."

      - alert: WenigFestplattenspeicher
        expr: (node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs"} / node_filesystem_size_bytes) * 100 < 15
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Wenig Festplattenspeicher auf {{ $labels.instance }}"
          description: "Partition {{ $labels.mountpoint }} hat noch {{ $value | printf \"%.1f\" }}% frei."

      - alert: InstanzNichtErreichbar
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Instanz {{ $labels.instance }} nicht erreichbar"
          description: "{{ $labels.job }}/{{ $labels.instance }} ist seit 1 Minute nicht erreichbar."

      - alert: HoheSpeicherAuslastung
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Hohe Speicherauslastung auf {{ $labels.instance }}"
          description: "Speicherauslastung beträgt {{ $value | printf \"%.1f\" }}%."
sudo mkdir -p /etc/prometheus/rules
sudo chown -R prometheus:prometheus /etc/prometheus/rules
promtool check rules /etc/prometheus/rules/alerts.yml
sudo systemctl reload prometheus

Alertmanager einrichten

Alertmanager installieren

AM_VERSION="0.27.0"
cd /tmp
wget "https://github.com/prometheus/alertmanager/releases/download/v${AM_VERSION}/alertmanager-${AM_VERSION}.linux-amd64.tar.gz"
tar xzf alertmanager-${AM_VERSION}.linux-amd64.tar.gz

sudo useradd --system --no-create-home --shell /bin/false alertmanager
sudo mkdir -p /etc/alertmanager /var/lib/alertmanager
sudo cp alertmanager-${AM_VERSION}.linux-amd64/alertmanager /usr/local/bin/
sudo chown alertmanager:alertmanager /usr/local/bin/alertmanager /etc/alertmanager /var/lib/alertmanager

Benachrichtigungsrouten konfigurieren

# /etc/alertmanager/alertmanager.yml
global:
  slack_api_url: "https://hooks.slack.com/services/IHR/WEBHOOK/HIER"

route:
  group_by: ["alertname", "instance"]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: "ops-team"
  routes:
    - match:
        severity: critical
      receiver: "pagerduty"

receivers:
  - name: "ops-team"
    slack_configs:
      - channel: "#alarme"
        send_resolved: true

  - name: "pagerduty"
    pagerduty_configs:
      - routing_key: "IHR_PAGERDUTY_SCHLUESSEL"
        send_resolved: true

inhibit_rules:
  - source_match:
      severity: critical
    target_match:
      severity: warning
    equal: ["alertname", "instance"]
sudo systemctl daemon-reload
sudo systemctl enable --now alertmanager

Recording Rules

Recording Rules berechnen aufwändige PromQL-Ausdrücke vor und speichern das Ergebnis als neue Metrik — das beschleunigt Dashboards über viele Server erheblich.

# /etc/prometheus/rules/recording.yml
groups:
  - name: node_recording
    interval: 1m
    rules:
      - record: instance:node_cpu_usage:percent
        expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

      - record: instance:node_memory_usage:percent
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

      - record: instance:node_filesystem_usage:percent
        expr: (1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs"} / node_filesystem_size_bytes)) * 100

Speicher-Tuning

Prometheus TSDB komprimiert Daten effizient — ca. 1-2 Bytes pro Sample. Ein Server mit 1.000 Metriken alle 15 Sekunden erzeugt etwa 2 GB pro Monat.

# Flags in ExecStart des prometheus.service:
--storage.tsdb.retention.time=90d
--storage.tsdb.retention.size=20GB
--storage.tsdb.wal-compression
du -sh /var/lib/prometheus/

Sicherheit

Basic-Authentifizierung

# /etc/prometheus/web.yml
basic_auth_users:
  admin: "$2y$10$ihr-bcrypt-hash-hier"

Reverse Proxy mit nginx

server {
    listen 443 ssl;
    server_name prometheus.beispiel.com;
    ssl_certificate /etc/letsencrypt/live/prometheus.beispiel.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/prometheus.beispiel.com/privkey.pem;
    auth_basic "Prometheus";
    auth_basic_user_file /etc/nginx/.prometheus-htpasswd;
    location / {
        proxy_pass http://127.0.0.1:9090;
    }
}

Firewall-Regeln

sudo ufw deny 9090
sudo ufw deny 9093
sudo ufw allow from 10.0.0.5 to any port 9100

Vergleichstabelle

MerkmalPrometheusZabbixNagiosDatadogNetdata
ModellPull (Scrape)Push/PullPullPush (Agent)Push
SpeicherLokale TSDBPostgreSQL/MySQLFlache DateienSaaS CloudEigene DB
AbfragesprachePromQL (leistungsstark)Custom + SQLKeineDogStatsDCustom
DashboardsGrafana (extern)IntegriertNicht nativIntegriertIntegriert
KostenKostenlos / Open-SourceKostenlos (Enterprise kostenpflichtig)Kostenlos (Enterprise kostenpflichtig)SaaSKostenlos (Cloud kostenpflichtig)
LernkurveModerat (PromQL)SteilSteilNiedrigSehr niedrig

Produktions-Stack-Rezept

Prometheus-Server (2 vCPUs / 4 GB RAM):
  - /var/lib/prometheus → separates Datenvolume (100 GB+)
  - Aufbewahrung: 30 Tage ODER 20 GB Größe

Node Exporter (auf jedem Server):
  - systemd-Dienst, Port 9100
  - Firewall: Port 9100 nur von Prometheus-Server-IP erlauben

Alertmanager:
  - Slack für Warnings, PagerDuty für Critical
  - Inhibierungsregeln: Warnings unterdrücken, wenn Critical aktiv

Grafana (empfohlen):
  - docker run -d -p 3000:3000 grafana/grafana
  - Dashboard-ID 1860 (Node Exporter Full) importieren

Fallstricke und Sonderfälle

rate() benötigt mindestens zwei Samples. Bei Counter-Reset (Prozessneustart) wird dies von rate() korrekt behandelt. Verwenden Sie für Alarmregeln immer rate(), nicht irate().

Kardinalitäts-Explosion verlangsamt Prometheus. Verwenden Sie niemals hochkardinale Labels wie user_id oder request_url. Jede eindeutige Label-Kombination erzeugt eine separate Zeitreihe.

Die for-Klausel verhindert flatterende Alarme. Ein Alarm mit for: 5m muss 5 Minuten durchgehend feuern, bevor eine Benachrichtigung gesendet wird.

Recording Rules haben keine historischen Daten. Nach dem Hinzufügen einer Recording Rule existiert die neue Metrik nur ab diesem Zeitpunkt.

Scrape-Timeout muss kleiner als Scrape-Intervall sein. Überschreitet scrape_timeout das scrape_interval, protokolliert Prometheus Fehler.


Zusammenfassung

  • Prometheus verwendet ein Pull-Modell — es scrapt /metrics-Endpunkte in konfigurierbaren Intervallen
  • Node Exporter exponiert Hardware- und OS-Metriken auf Port 9100
  • PromQL mit rate(), increase() und histogram_quantile() bildet die Basis nützlicher Abfragen
  • Schreiben Sie Alarmregeln mit for-Klausel, um flatternde Alarme zu vermeiden; leiten Sie über Alertmanager weiter
  • Recording Rules berechnen teure Aggregationen vor — kritisch für Multi-Node-Dashboards
  • Passen Sie die Speicheraufbewahrung mit --storage.tsdb.retention.time oder --storage.tsdb.retention.size an
  • Stellen Sie Prometheus immer hinter einen Reverse Proxy mit TLS und beschränken Sie direkten Port-Zugriff

Verwandte Artikel