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
dnfstattapt) - 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
/metricsvon jedem Target imscrape_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
| Metrik | Beschreibung |
|---|---|
node_cpu_seconds_total | CPU-Zeit nach Modus (user, system, idle) — mit rate() verwenden |
node_memory_MemAvailable_bytes | Verfügbarer Speicher (inkl. rückforderbarem Cache) |
node_memory_MemTotal_bytes | Gesamter physischer Speicher |
node_filesystem_avail_bytes | Freier Festplattenspeicher |
node_network_receive_bytes_total | Empfangene Bytes pro Netzwerkschnittstelle — mit rate() verwenden |
node_load1 / node_load5 / node_load15 | System-Lastwerte |
node_disk_io_time_seconds_total | Zeit 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
| Funktion | Zweck |
|---|---|
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
| Merkmal | Prometheus | Zabbix | Nagios | Datadog | Netdata |
|---|---|---|---|---|---|
| Modell | Pull (Scrape) | Push/Pull | Pull | Push (Agent) | Push |
| Speicher | Lokale TSDB | PostgreSQL/MySQL | Flache Dateien | SaaS Cloud | Eigene DB |
| Abfragesprache | PromQL (leistungsstark) | Custom + SQL | Keine | DogStatsD | Custom |
| Dashboards | Grafana (extern) | Integriert | Nicht nativ | Integriert | Integriert |
| Kosten | Kostenlos / Open-Source | Kostenlos (Enterprise kostenpflichtig) | Kostenlos (Enterprise kostenpflichtig) | SaaS | Kostenlos (Cloud kostenpflichtig) |
| Lernkurve | Moderat (PromQL) | Steil | Steil | Niedrig | Sehr 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()undhistogram_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.timeoder--storage.tsdb.retention.sizean - Stellen Sie Prometheus immer hinter einen Reverse Proxy mit TLS und beschränken Sie direkten Port-Zugriff