Alerting für Container-Ressourcen mit Alertmanager einrichten
AI generated
FROM
RUN
Docker · Alertmanager · Prometheus · Alerting
Alerting für Container-Ressourcen mit Alertmanager einrichten
von der ersten Alert-Regel bis zur ruhigen Nachtschicht

Ein Dashboard, das niemand nachts ansieht, hilft im Ernstfall nichts. Alerting für Container-Ressourcen mit Prometheus-Regeln und Alertmanager meldet CPU-Engpässe, Memory-Druck und Restart-Schleifen automatisch, gruppiert verwandte Alarme und verhindert mit Silencing und Inhibition, dass ein einzelner Vorfall die Mannschaft mit Dutzenden Benachrichtigungen überflutet.

17 Min. Lesezeit Alertmanager · Prometheus · PromQL · Routing Docker Engine · Docker Compose

1. Warum Dashboards allein kein Alerting ersetzen

Ein Grafana-Dashboard mit sauber visualisierten Container-Ressourcen ist wertvoll für die Fehlersuche, aber nutzlos, wenn niemand gerade hinschaut. Alerting schließt genau diese Lücke: Statt darauf zu warten, dass ein Mensch zufällig eine Grafik betrachtet, wertet ein automatisiertes System kontinuierlich Metriken aus und meldet aktiv, sobald ein definierter Schwellenwert überschritten wird. Für Container-Umgebungen bedeutet das konkret, dass Speicherlecks, CPU-Sättigung oder wiederholte Neustarts erkannt werden, bevor Kunden den Ausfall bemerken.

Prometheus selbst wertet Alert-Regeln aus und erzeugt Alarme, verschickt sie aber nicht. Diese Aufgabe übernimmt Alertmanager, eine eigenständige Komponente, die Alarme empfängt, dedupliziert, gruppiert und über konfigurierbare Routen an E-Mail, Slack, PagerDuty oder andere Systeme weiterleitet. Diese Trennung zwischen Erkennung und Zustellung ist bewusst gewählt und erlaubt es, komplexes Routing-Verhalten zu definieren, ohne die Prometheus-Konfiguration selbst zu verkomplizieren. Die folgenden Abschnitte zeigen den kompletten Weg von der ersten Alert-Regel bis zu einem Alerting-Setup, das auch nachts verlässlich, aber nicht nervig funktioniert.

2. Architektur: Prometheus, Regeln und Alertmanager

Der Ablauf im Alerting-Stack folgt einer klaren Pipeline. Prometheus wertet in regelmäßigen Abständen die in rule_files definierten Alert-Regeln gegen die gesammelten Zeitreihen aus. Trifft eine Bedingung über die konfigurierte for-Dauer zu, wechselt der Alarm vom Zustand pending in firing und wird an Alertmanager übermittelt. Alertmanager selbst kennt keine Metriken, sondern verarbeitet ausschließlich die von Prometheus gesendeten Alarme.

Diese Architektur skaliert gut über mehrere Prometheus-Instanzen hinweg: In größeren Umgebungen können mehrere Prometheus-Server, etwa pro Region oder Cluster, denselben zentralen Alertmanager ansprechen. Alertmanager übernimmt dann die Deduplizierung, falls derselbe Alarm redundant von mehreren Quellen gemeldet wird, sowie die Gruppierung verwandter Alarme zu einer einzigen Benachrichtigung. Für Docker-Umgebungen mit cAdvisor als Metriken-Quelle ist dieser Aufbau der Standardweg für belastbares Alerting.


# docker-compose.yml — Prometheus + Alertmanager stack
services:
  prometheus:
    image: prom/prometheus:v2.53.0
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./alerts:/etc/prometheus/alerts:ro
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--web.enable-lifecycle"
    ports:
      - "9090:9090"

  alertmanager:
    image: prom/alertmanager:v0.27.0
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
    ports:
      - "9093:9093"
    command:
      - "--config.file=/etc/alertmanager/alertmanager.yml"

3. Alert-Regeln für CPU, Memory und Restarts formulieren

Eine gute Alert-Regel für Container-Ressourcen besteht aus drei Teilen: einer PromQL-Bedingung, einer for-Dauer, die kurze Ausreißer herausfiltert, und aussagekräftigen Labels und Annotationen für die spätere Benachrichtigung. Für CPU-Sättigung eignet sich eine Regel, die die CPU-Rate eines Containers über mehrere Minuten gegen einen Schwellenwert prüft. Für Memory eignet sich eher eine Regel relativ zum konfigurierten Limit, weil ein absoluter Speicherwert je nach Container völlig unterschiedliche Bedeutung hat.

Restart-Alarme verdienen besondere Aufmerksamkeit, weil ein einzelner Neustart oft normal ist, etwa nach einem Deployment, während wiederholte Neustarts in kurzer Zeit auf ein CrashLoop hindeuten. Die Funktion increase() über ein Zeitfenster von einer Stunde eignet sich gut, um genau diesen Unterschied zwischen einmaligem und wiederholtem Neustart abzubilden. Die severity-Label in jeder Regel steuert später das Routing in Alertmanager und sollte konsistent zwischen warning und critical unterscheiden.


# alerts/container-resources.yml — Prometheus alerting rules
groups:
  - name: container-resources
    rules:
      - alert: ContainerHighCpuUsage
        expr: |
          sum by (name) (rate(container_cpu_usage_seconds_total{name!=""}[5m])) > 1.5
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Container {{ $labels.name }} exceeds 1.5 CPU cores"
          description: "Sustained CPU usage above the expected threshold for 10 minutes."

      - alert: ContainerMemoryNearLimit
        expr: |
          (container_memory_working_set_bytes{name!=""}
            / container_spec_memory_limit_bytes{name!=""}) > 0.90
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Container {{ $labels.name }} is at 90 percent of its memory limit"
          description: "OOM kill is likely if usage keeps rising."

      - alert: ContainerRestartingFrequently
        expr: |
          increase(container_last_seen{name!=""}[1h]) > 3
        for: 0m
        labels:
          severity: critical
        annotations:
          summary: "Container {{ $labels.name }} restarted more than 3 times in one hour"
          description: "Possible crash loop, check application logs immediately."

4. Alertmanager konfigurieren: Routing und Empfänger

Die Alertmanager-Konfiguration besteht aus einem route-Baum, der eingehende Alarme anhand ihrer Labels an unterschiedliche Empfänger weiterleitet, und einer Liste von receivers mit den technischen Details für E-Mail, Slack, PagerDuty oder Webhooks. Der oberste Routing-Knoten definiert Standardwerte für Gruppierung und Wartezeiten, untergeordnete Routen können diese anhand von Label-Matches wie severity: critical überschreiben.

Eine bewährte Praxis ist die Trennung nach Schweregrad: warning-Alarme landen in einem Slack-Kanal, den das Team tagsüber im Blick hat, während critical-Alarme zusätzlich einen Bereitschaftsdienst über PagerDuty alarmieren. Diese Differenzierung verhindert, dass jede kleinere Auffälligkeit denselben Alarmpegel auslöst wie ein echter Produktionsausfall, und ist die Grundlage für ein Alerting-System, dem das Team langfristig vertraut, statt es aus Frust zu ignorieren.


# alertmanager.yml — routing by severity
route:
  receiver: "slack-warnings"
  group_by: ["alertname", "compose_project"]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - matchers:
        - severity = "critical"
      receiver: "pagerduty-oncall"
      repeat_interval: 1h

receivers:
  - name: "slack-warnings"
    slack_configs:
      - api_url: "https://hooks.slack.com/services/REPLACE/WITH/WEBHOOK"
        channel: "#container-alerts"
        send_resolved: true

  - name: "pagerduty-oncall"
    pagerduty_configs:
      - service_key: "REPLACE_WITH_PAGERDUTY_KEY"
        send_resolved: true

5. Gruppierung, Silencing und Inhibition richtig einsetzen

Ohne Gruppierung würde jeder betroffene Container einen eigenen Alarm auslösen, sodass ein Ausfall des zugrundeliegenden Docker-Hosts zu Dutzenden Einzelbenachrichtigungen führt. group_by fasst zusammengehörige Alarme, etwa alle mit demselben alertname und compose_project, zu einer einzigen Nachricht zusammen. Das reduziert Alarmmüdigkeit erheblich, ohne relevante Informationen zu verlieren, weil die einzelnen betroffenen Container weiterhin in der zusammengefassten Nachricht aufgelistet werden.

Silencing pausiert Benachrichtigungen für einen definierten Zeitraum, etwa während einer geplanten Wartung, ohne die zugrundeliegende Alert-Regel zu deaktivieren. Inhibition geht einen Schritt weiter und unterdrückt automatisch nachgelagerte Alarme, wenn ein übergeordneter Alarm bereits aktiv ist, zum Beispiel wird ein einzelner Container-Alarm unterdrückt, sobald bereits ein Host-Ausfall-Alarm für denselben Host feuert. Diese Mechanismen zusammen verhindern, dass ein einziger Vorfall in einer Flut widersprüchlicher oder redundanter Benachrichtigungen endet.

6. Schwellenwerte datenbasiert statt geraten festlegen

Der häufigste Grund für ignoriertes Alerting sind Schwellenwerte, die ohne Bezug zur tatsächlichen Lastverteilung geraten wurden. Ein CPU-Schwellenwert von 80 Prozent klingt intuitiv vernünftig, ist aber für einen Batch-Job, der regelmäßig kurzzeitig auf 100 Prozent läuft, völlig ungeeignet und erzeugt ständige Fehlalarme. Der bessere Weg: historische Metriken aus Prometheus über quantile_over_time() auswerten und Schwellenwerte auf Basis des 95. oder 99. Perzentils der tatsächlichen Auslastung der letzten Wochen festlegen.

Für neue Container ohne historische Daten ist ein konservativer Startwert sinnvoll, der nach einer Beobachtungsphase von zwei bis vier Wochen anhand der gesammelten Metriken nachjustiert wird. Diese datenbasierte Herangehensweise an Schwellenwerte ist der entscheidende Unterschied zwischen einem Alerting-System, dem das Team vertraut, und einem, das nach kurzer Zeit stummgeschaltet wird, weil es ständig grundlos Alarm schlägt.

7. Eskalationsstufen und Bereitschaftsdienst abbilden

Nicht jeder Alarm braucht sofortige menschliche Reaktion um drei Uhr nachts. Eine durchdachte Eskalationsstrategie unterscheidet zwischen Alarmen, die während der Geschäftszeiten bearbeitet werden können, und solchen, die einen Bereitschaftsdienst wecken müssen. Alertmanager unterstützt dies über zeitbasierte Routing-Regeln in Kombination mit severity-Labels, sodass ein Memory-Alarm mit niedriger Priorität tagsüber im Team-Chat landet, während derselbe Alarmtyp mit hoher Priorität sofort eskaliert wird.

Für Teams mit mehrstufigem Bereitschaftsdienst lässt sich repeat_interval nutzen, um unbestätigte kritische Alarme in kürzeren Abständen erneut zu senden, bis jemand reagiert. Diese Eskalationslogik direkt in Alertmanager abzubilden, statt sie manuell zu koordinieren, stellt sicher, dass kritische Container-Ressourcen-Probleme auch dann Aufmerksamkeit bekommen, wenn die erste benachrichtigte Person nicht rechtzeitig reagiert.

8. Typische Fehler beim Container-Alerting

Der häufigste Fehler ist eine zu kurze oder fehlende for-Dauer, wodurch jeder kurzzeitige Ausreißer sofort einen Alarm auslöst, statt nur anhaltende Probleme zu melden. Ein zweiter verbreiteter Fehler ist fehlende Gruppierung, die bei einem größeren Vorfall zu einer Flut von Einzelbenachrichtigungen führt, die das eigentliche Problem eher verschleiert als klärt.


# Common mistakes in container resource alerting

# WRONG: no "for" duration — fires on every brief spike
# - alert: ContainerHighCpuUsage
#   expr: rate(container_cpu_usage_seconds_total[1m]) > 1.5
#   # missing: for: 10m

# RIGHT: sustained condition required before firing
# - alert: ContainerHighCpuUsage
#   expr: rate(container_cpu_usage_seconds_total[5m]) > 1.5
#   for: 10m

# WRONG: no group_by — one notification per affected container
# route:
#   receiver: "slack"
#   # missing: group_by

# RIGHT: related alerts bundled into a single notification
# route:
#   receiver: "slack"
#   group_by: ["alertname", "compose_project"]

# WRONG: identical severity for everything — no escalation possible
# labels:
#   severity: warning   # used for both minor and critical issues

# RIGHT: severity reflects actual urgency, drives routing
# labels:
#   severity: critical   # routes to on-call, shorter repeat_interval

Ein dritter Fehler ist das Fehlen von send_resolved: true in den Receiver-Konfigurationen. Ohne diese Einstellung erfährt das Team nie, wenn ein Alarm sich von selbst wieder aufgelöst hat, was zu unnötiger Verwirrung führt, ob ein gemeldetes Problem noch besteht. Ein vierter Fehler ist statische Schwellenwerte für alle Container gleichermaßen anzusetzen, obwohl Datenbank-Container, Worker-Container und Web-Container völlig unterschiedliche normale Lastprofile haben und entsprechend unterschiedliche Schwellenwerte benötigen.

9. Alerting-Strategien im direkten Vergleich

Für Alerting in Docker-Umgebungen gibt es mehrere Ansätze mit unterschiedlichem Reifegrad und Aufwand.

Ansatz Reaktionszeit Aufwand Empfehlung
Manuelles Dashboard-Beobachten Nur wenn jemand hinschaut Gering Ungeeignet für produktive Systeme
Prometheus + Alertmanager Minuten Mittel, einmalige Einrichtung Standard für Docker-Umgebungen
Reine Log-basierte Alarme Minuten, aber lückenhaft Gering Ergänzend, nicht als einzige Quelle
Managed Observability-Plattform Minuten Kein eigener Betrieb, laufende Kosten Bei knappen Ops-Ressourcen

Prometheus mit Alertmanager bleibt der Standard für Docker-basierte Umgebungen, weil es sich nahtlos in bereits vorhandene Metriken-Pipelines mit cAdvisor einfügt und keine laufenden Lizenzkosten verursacht. Managed Plattformen sind sinnvoll, wenn das Team keine Kapazität für den Betrieb einer eigenen Alerting-Infrastruktur hat, verlagern den Aufwand aber lediglich in laufende Kosten statt in Betriebsaufwand.

10. Zusammenfassung

Alerting für Container-Ressourcen mit Alertmanager schließt die Lücke zwischen passiven Dashboards und aktiver Benachrichtigung. Prometheus wertet Alert-Regeln für CPU, Memory und Restarts gegen die gesammelten Zeitreihen aus, Alertmanager übernimmt Gruppierung, Routing und Zustellung an die richtigen Empfänger. Silencing und Inhibition verhindern, dass ein einzelner Vorfall in einer Flut redundanter Benachrichtigungen endet.

Der entscheidende Erfolgsfaktor ist die datenbasierte Festlegung von Schwellenwerten anhand historischer Perzentile statt geratener Prozentzahlen, kombiniert mit konsequenter Nutzung von severity-Labels für Eskalation. Wer diese Grundlagen beherzigt, bekommt ein Alerting-System, dem das Team langfristig vertraut, weil es genau dann meldet, wenn tatsächlich Handlungsbedarf besteht, und schweigt, wenn alles im normalen Rahmen läuft.

Alerting für Container-Ressourcen mit Alertmanager — Das Wichtigste auf einen Blick

Regeln

Prometheus-Alert-Regeln mit sinnvoller for-Dauer prüfen CPU, Memory und Restart-Häufigkeit pro Container.

Routing

Alertmanager verteilt Alarme nach severity-Label an Slack, PagerDuty oder andere Empfänger.

Ruhe im System

Gruppierung, Silencing und Inhibition verhindern Alarmflut bei größeren, zusammenhängenden Vorfällen.

Schwellenwerte

Historische Perzentile statt geratener Prozentzahlen als Basis für belastbare Alarmierung.

11. FAQ: Alerting für Container-Ressourcen mit Alertmanager

1Prometheus-Regeln vs. Alertmanager?
Prometheus erzeugt Alarme aus Regeln, Alertmanager empfängt, gruppiert und verteilt sie an die Empfänger.
2Wozu die for-Dauer?
Sie verlangt eine anhaltende Bedingung, bevor der Alarm feuert, und filtert kurze, harmlose Ausreißer heraus.
3Sinnvolle Schwellenwerte?
Historische Perzentile per quantile_over_time() auswerten, statt runde Prozentzahlen zu raten.
4Was macht group_by?
Fasst zusammengehörige Alarme zu einer Nachricht zusammen, statt für jeden Container einzeln zu benachrichtigen.
5Silencing vs. Inhibition?
Silencing pausiert manuell, Inhibition unterdrückt automatisch nachgelagerte Alarme bei bereits aktivem übergeordnetem Alarm.
6warning vs. critical?
Über das severity-Label, warning in den Team-Chat, critical zusätzlich an den Bereitschaftsdienst.
7Wozu send_resolved?
Ohne diese Einstellung erfährt das Team nie, dass ein gemeldetes Problem sich von selbst gelöst hat.
8Unterschiedliche Schwellenwerte?
Ja, über zusätzliche Label-Matches oder separate Regelgruppen je Container-Typ.
9Host-Ausfall ohne Alarmflut?
Inhibition-Regeln unterdrücken Container-Alarme, sobald ein Host-Ausfall-Alarm für denselben Host bereits feuert.
10E-Mail als einziger Kanal?
Für kritische Alarme meist nicht ausreichend, Slack und PagerDuty ergänzen für Sichtbarkeit und Eskalation.