Ein Server ohne Monitoring ist ein blinder Fleck. Man erfährt von Problemen erst, wenn der Nutzer sich beschwert — oder wenn der Server bereits abgestürzt ist. Prometheus sammelt Metriken, Grafana visualisiert sie und sendet Alerts. Zusammen bilden sie das de-facto Standard-Monitoring-Stack für Server und Kubernetes.
Architektur des Stacks
Server Prometheus Grafana
[Node Exporter] ──→ [Scraping] ──→ [Dashboards]
[nginx Exporter] [Storage] [Alerting]
[PHP-FPM Exporter] [Query (PromQL)] [Notifications]
[Blackbox Exporter] └── Email/Slack
Prometheus "scrapet" Metriken von Exportern in regelmäßigen Intervallen (Standard: 15 Sekunden). Die Metriken werden in einer Zeitreihendatenbank gespeichert. Grafana verbindet sich mit Prometheus als Datenquelle und rendert Dashboards.
Setup mit Docker Compose
# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:v2.50.0
container_name: prometheus
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=30d'
ports:
- "9090:9090"
restart: unless-stopped
grafana:
image: grafana/grafana-oss:10.3.0
container_name: grafana
environment:
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD: "${GRAFANA_PASSWORD}"
GF_SERVER_ROOT_URL: https://monitoring.example.com
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
ports:
- "3000:3000"
depends_on:
- prometheus
restart: unless-stopped
node-exporter:
image: prom/node-exporter:v1.7.0
container_name: node-exporter
pid: host
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'
ports:
- "9100:9100"
restart: unless-stopped
volumes:
prometheus_data:
grafana_data:
Prometheus Konfiguration
# prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
rule_files:
- /etc/prometheus/rules/*.yml
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
scrape_interval: 30s
- job_name: 'nginx'
static_configs:
- targets: ['nginx-exporter:9113']
- job_name: 'php-fpm'
static_configs:
- targets: ['php-fpm-exporter:9253']
# Blackbox für HTTP-Monitoring
- job_name: 'blackbox-http'
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
- https://www.wunner-software.de
- https://firma-neu.ddev.site
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115
Wichtige Metriken und PromQL
PromQL (Prometheus Query Language) ist die Abfragesprache für Metriken.
CPU-Auslastung
# CPU-Nutzung in Prozent (ohne idle)
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Load Average (1 Minute)
node_load1
Memory
# Verfügbarer Arbeitsspeicher in Prozent
(node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# Swapnutzung
(1 - (node_memory_SwapFree_bytes / node_memory_SwapTotal_bytes)) * 100
Festplattenplatz
# Freier Festplattenplatz in Prozent
(node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100
# Festplatten-IO
rate(node_disk_io_time_seconds_total[5m])
nginx Metriken
# Aktive Verbindungen
nginx_connections_active
# Requests pro Sekunde
rate(nginx_http_requests_total[5m])
# 4xx und 5xx Fehlerrate
rate(nginx_http_requests_total{status=~"[45].."}[5m])
/ rate(nginx_http_requests_total[5m]) * 100
HTTP-Verfügbarkeit (Blackbox Exporter)
# 1 = Up, 0 = Down
probe_success
# SSL-Zertifikat läuft ab in X Tagen
(probe_ssl_earliest_cert_expiry - time()) / 86400
Alerting-Regeln
# prometheus/rules/alerts.yml
groups:
- name: server
rules:
- alert: HighCPUUsage
expr: >
100 - (avg by (instance)
(irate(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 {{ $value | printf \"%.1f\" }}% > 85% seit 5 Minuten"
- alert: LowDiskSpace
expr: >
(node_filesystem_avail_bytes{mountpoint="/"}
/ node_filesystem_size_bytes{mountpoint="/"}) * 100 < 10
for: 1m
labels:
severity: critical
annotations:
summary: "Wenig Festplattenplatz auf {{ $labels.instance }}"
description: "Noch {{ $value | printf \"%.1f\" }}% freier Speicher auf /"
- alert: HighMemoryUsage
expr: >
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
for: 5m
labels:
severity: critical
annotations:
summary: "Sehr hohe Speicherauslastung"
- alert: SiteDown
expr: probe_success == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Website nicht erreichbar: {{ $labels.instance }}"
- alert: SSLCertificateExpiringSoon
expr: (probe_ssl_earliest_cert_expiry - time()) / 86400 < 14
for: 1h
labels:
severity: warning
annotations:
summary: "SSL-Zertifikat läuft bald ab: {{ $labels.instance }}"
description: "Noch {{ $value | printf \"%.0f\" }} Tage bis zum Ablauf"
Grafana Dashboard provisioning
# grafana/provisioning/dashboards/dashboards.yml
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
options:
path: /etc/grafana/provisioning/dashboards
Für Server-Monitoring empfiehlt sich der fertige "Node Exporter Full" Dashboard (ID: 1860) von grafana.com — importieren über Dashboard → Import → ID 1860.
Benachrichtigungen: E-Mail und Slack
In Grafana unter Alerting → Contact Points:
{
"name": "email-alert",
"type": "email",
"settings": {
"addresses": "thomas@wunner-software.de",
"subject": "[{{ .Status | toUpper }}] {{ .CommonAnnotations.summary }}"
}
}
Für Slack:
{
"name": "slack-alert",
"type": "slack",
"settings": {
"url": "https://hooks.slack.com/services/xxx/yyy/zzz",
"channel": "#monitoring",
"title": "{{ .CommonAnnotations.summary }}",
"text": "{{ .CommonAnnotations.description }}"
}
}
Fazit
Prometheus und Grafana sind der Industriestandard für Open-Source-Monitoring aus gutem Grund: flexibel, skalierbar, mit riesigem Ökosystem an Exportern. Für einen typischen Web-Server (nginx, PHP-FPM, MariaDB) genügen Node Exporter, nginx Exporter und Blackbox Exporter, um vollständige Sichtbarkeit zu erhalten.
Die wichtigsten Metriken, die man im Blick haben sollte:
- CPU und Memory Auslastung
- Festplattenplatz (mit Trend)
- HTTP-Verfügbarkeit und Antwortzeiten
- SSL-Zertifikat-Ablaufdatum
- Error-Rate in nginx-Logs
Kommentare
Kommentare werden von Remark42 bereitgestellt. Beim Laden werden Daten an unseren Kommentar-Server übertragen.