Design wechseln

Docker-Ressourcenlimits – vollständiger Leitfaden: Speicherlecks verhindern, bevor sie den Server lahmlegen

Easton editorial illustration: developer problem-solving desk

Das Handy klingelt – „Server antwortet nicht“, „CPU 100 %“, „SSH-Verbindung abgelaufen“. Dreimal VPN, dann ssh – Timeout. Der Server ist eingefroren.

Nach einem Hard-Reboot zeigen die Logs: Ein Container, der seit einem halben Jahr lief, hatte ein Speicherleck – von 500 MB bis 16 GB, der gesamte Server-Speicher war aufgebraucht, selbst SSH hatte keine Ressourcen mehr. Drei weitere normal laufende Container fielen ebenfalls aus – die Produktion brach zusammen. 2024 gab es in Docker 27.0.3 einen schwerwiegenden Speicherleck-Bug, der dazu führte, dass der OOM Killer 68 Container auf einmal beendete.

16GB
Speicherleck
Speicherleck in einem Container wächst von 500 MB auf 16 GB und frisst den gesamten Server-Speicher auf

Dieser Artikel beantwortet: Wie verhindern Sie, dass ein einzelner Container den gesamten Server lahmlegt? Von cgroups im Detail über --memory und --cpus in der Praxis bis zu docker stats, cAdvisor und Prometheus – alles zu Docker-Ressourcenlimits an einem Ort. Danach sollten Sie mindestens erreichen: Bei ersten Anzeichen eines Speicherlecks fällt der Container selbst aus – statt den ganzen Server mitzunehmen.

Warum können Container einen Server lahmlegen?

Docker hat ein „Feature“: Standardmäßig gibt es keine Ressourcenlimits für Container. Klingt frei – frei genug, dass ein Container den gesamten Speicher und die CPU des Hosts verbrauchen kann, bis alles zusammenbricht.

Ein realer Fall mit Docker 27.4.0: Nutzer stellten fest, dass der dockerd-Daemon innerhalb weniger Tage von einigen hundert MB auf 8 GB anwuchs und den Server träge machte. Docker ist nicht per se instabil – das Problem: Ohne explizite Limits galoppiert ein Container wie ungebremst und nimmt sich, was er will.

Dann greift der Linux-Kernel zum OOM Killer (Out Of Memory Killer). Wenn der Speicher knapp wird, wählt er einen „passenden“ Prozess zum Beenden. Jeder Prozess erhält einen oom_score – je höher, desto wahrscheinlicher das Ende. Prozesse in Containern liegen oft hoch; der Docker-Daemon senkt seine eigene OOM-Priorität (oom_score_adj auf -500) – getroffen werden meist Ihre Container.

In docker ps fehlt der Container plötzlich; in den Logs steht Exit Code 137: 128 + 9 (SIGKILL) – gewaltsam beendet, kein sauberer Shutdown.

Typische Symptome eines Speicherlecks:

  • Speicherverbrauch des Containers steigt stetig von einigen hundert MB auf mehrere GB
  • Der Server nutzt massiv Swap, die Festplatten-LED blinkt ununterbrochen
  • Andere Container werden langsamer und fallen schließlich aus
  • Im Monitoring eine schöne steigende Gerade

2024 gab es einen extremen Fall in der Storj-Community: Ein Container wuchs von normalen einigen hundert MB auf 37 GB und drohte den gesamten Storage-Knoten zu gefährden. Mit einem Speicherlimit von 1 GB hätte der OOM Killer den Container längst beendet – der Server wäre stabil geblieben.

[Bild: Speicherleck-Kurve]
Prompt: server memory usage graph showing sharp upward spike, red critical zone at 90%, dark background, monitoring dashboard style, high quality

cgroups: Das Prinzip hinter Ressourcenlimits

Sie haben vermutlich gehört, Docker nutze cgroups für Ressourcenlimits – aber was ist das? Kurz gesagt: cgroups (Control Groups) sind eine Linux-Kernel-Funktion, die Prozessgruppen Ressourcen-Kontingente zuweist – wie eine „Ressourcen-Karte“ pro Gruppe, ohne Überziehung.

Beim Erstellen eines Containers legt Docker automatisch eine cgroup an und ordnet die Container-Prozesse zu. Bei docker run -m 512m nginx schreibt Docker im Hintergrund in /sys/fs/cgroup/memory/docker/<Container-ID>/memory.limit_in_bytes den Wert 536870912 (512 MB in Bytes). Der Kernel liest das und begrenzt den Container auf 512 MB – Überschreitung führt zum Ende.

cgroups v1 vs. v2:

  • v1: Speicher, CPU und Disk-I/O in getrennten Subsystemen – wie einzelne Abteilungen
  • v2: Einheitliche Verwaltung, klarere Hierarchie – besser für Container mit Gesamtsteuerung
  • Ältere Systeme (z. B. RHEL 7) nutzen oft v1; neuere (Ubuntu 20.04+, RHEL 8+) meist v2

Die tatsächliche cgroup-Konfiguration eines Containers können Sie so prüfen:

# Vollständige Container-ID ermitteln
docker inspect --format='{{.Id}}' my_container

# Speicherlimit anzeigen (cgroups v1)
cat /sys/fs/cgroup/memory/docker/<Container-ID>/memory.limit_in_bytes

# CPU-Kontingent anzeigen (cgroups v1)
cat /sys/fs/cgroup/cpu/docker/<Container-ID>/cpu.cfs_quota_us

Als ich diese Dateien das erste Mal sah, war ich verwirrt: Ressourcenlimits über das Dateisystem? Das ist Linux’ „Everything is a file“-Philosophie – der Kernel exponiert cgroup-Konfiguration als Dateien; Docker schreibt Werte, der Kernel setzt Limits um. Elegant.

[Bild: cgroups-Hierarchie]
Prompt: Linux cgroups hierarchy diagram, containers grouped under docker cgroup, memory and CPU subsystems, tree structure, technical illustration, clean design, high quality

Speicher-Parameter im Detail

Die Speicher-Parameter von Docker wirken zunächst viel – in der Praxis zählen vor allem diese.

1. --memory / -m (Hard Limit – am wichtigsten)

Der lebensrettende Parameter. Erreicht der Container diesen Wert, greift der OOM Killer – der Container wird beendet. Minimum sind 6 MB (praktisch für fast nichts nutzbar); in der Produktion sollten Sie mindestens einige hundert MB einplanen.

# Container auf maximal 512 MB Speicher begrenzen
docker run -m 512m nginx

# Auch mit GB-Einheit
docker run -m 2g my-app

Wie setzen Sie sinnvoll? Meine Erfahrung: Lasttest unter Normalbetrieb, dann Faktor 1,2 bis 1,5. Nutzt die App 300 MB, sind 400–450 MB solide. Zu niedrig → häufige OOM-Kills; zu hoch → weniger Schutz.

2. --memory-swap (Swap – oft missverstanden)

Dieser Parameter ist knifflig. Er legt Speicher + Swap gesamt fest – nicht die reine Swap-Größe.

# 512 MB Speicher + 512 MB Swap (insgesamt 1 GB nutzbar)
docker run -m 512m --memory-swap 1g nginx

# Swap deaktivieren (nur Speicher)
docker run -m 512m --memory-swap 512m nginx

# Unbegrenzter Swap (gefährlich!)
docker run -m 512m --memory-swap -1 nginx

Ohne --memory-swap gilt standardmäßig: swap = memory – insgesamt also das Doppelte des Speicherlimits. Bei -m 512m sind das 1 GB (512 MB RAM + 512 MB Swap).

Empfehlung für die Produktion: Swap deaktivieren (--memory-swap gleich --memory) oder Swap auf höchstens die Hälfte des Speichers begrenzen. Nicht -1 – massiver Swap kann die Festplatte lahmlegen.

3. --memory-reservation (Soft Limit)

Eine „elastische“ Grenze. Bei ausreichend Speicher darf der Container darüber liegen; bei Knappheit drückt der Kernel zurück unter diesen Wert. Muss kleiner als --memory sein.

# Soft Limit 750 MB, Hard Limit 1 GB
docker run -m 1g --memory-reservation 750m nginx

Sinnvoll, wenn die Anwendung kurzzeitig viel Speicher braucht (z. B. Batch), im Normalbetrieb aber weniger.

4. --kernel-memory (Kernel-Speicher – mit Vorsicht)

Begrenzt Kernel-Speicher im Container (Netzwerk-Puffer, Dateisystem-Cache) – nicht swappable. Ehrlich: Nur wenn Sie genau wissen, was Sie tun – sonst startet der Container gar nicht.

5. --oom-kill-disable (gefährlich – unbedingt beachten)

Deaktiviert den OOM Killer – der Container wird bei Speicherüberschreitung nicht beendet. Klingt gut? Falsch. Läuft der Speicher aus dem Ruder und nichts stoppt den Prozess, frisst der Container den gesamten Server-Speicher.

# So nicht! (Container kann unbegrenzt Speicher nehmen)
docker run --oom-kill-disable nginx

# Falls unvermeidbar: immer mit Speicherlimit kombinieren
docker run -m 512m --oom-kill-disable nginx

Wann nutzen? Fast nie. Nur bei speziellen Anwendungen, die nicht abrupt beendet werden dürfen (z. B. DB-Checkpoint), und wenn die App den Speicher selbst kontrolliert.

Realer Fall: Ein AWS-Nutzer ließ eine EC2-Instanz abstürzen – ein Container ohne Speicherlimit wuchs auf 30 GB, die Instanz reagierte nicht mehr. Mit -m 2g beendet sich der Container am Limit und startet neu – der Server bleibt stabil.

[Bild: Speicher-Parameter-Beziehung]
Prompt: Docker memory parameters diagram, showing memory and swap relationship, visual chart with bars and labels, technical illustration, blue and orange colors, high quality

CPU-Parameter im Detail

CPU-Limits sind weniger brutal als Speicher – Überschreitung bedeutet Drosselung, nicht sofortiges Ende. Ungebremste CPU kann den Server aber genauso lahmlegen.

1. --cpus (am intuitivsten)

Direkt angeben, wie viele CPU-Kerne der Container nutzen darf – Dezimalwerte möglich.

# Maximal 1,5 CPU-Kerne
docker run --cpus="1.5" nginx

# Nur ein halber Kern
docker run --cpus="0.5" my-app

Unter der Haube nutzt Docker --cpu-period und --cpu-quota. Bei 1,5 nutzt der Container höchstens 1,5 Kerne gleichzeitig – ein Kern voll plus 50 % eines zweiten.

2. --cpu-shares (relative Gewichtung, kein Hard Limit)

Priorität im CPU-Scheduler, Standard 1024. Wichtig: Wirkt nur bei CPU-Knappheit. Ist genug CPU frei, nutzt der Container, was er braucht.

# Container A erhält doppelt so viel CPU-Zeit wie Container B
docker run --cpu-shares 2048 --name app_a my-app
docker run --cpu-shares 1024 --name app_b my-app

Bei zwei voll ausgelasteten Kernen teilen sich A und B im Verhältnis 2:1 – A etwa 1,33 Kerne, B 0,67. Bei Leerlauf laufen beide voll.

Wann nutzen? Mehrere Container – bei Konkurrenz soll ein wichtiger Dienst (z. B. API vor Hintergrundjobs) Vorrang haben.

3. --cpuset-cpus (an feste Kerne binden)

Container nur auf bestimmte CPU-Kerne legen.

# Nur Kerne 0 und 3
docker run --cpuset-cpus="0,3" nginx

# Kerne 2 bis 5
docker run --cpuset-cpus="2-5" my-app

Einsatz:

  • NUMA: Container auf Kerne eines CPU-Sockets binden, weniger Cross-Socket-Zugriffe
  • Cache: Feste Kerne → bessere Cache-Treffer
  • Isolation: Wichtige Container auf dedizierte Kerne

In einer Kubernetes-Umgebung band man DB-Container auf die hinteren vier Kerne eines 8-Kern-Servers, Web auf die vorderen vier – spürbarer Gewinn.

4. --cpu-period und --cpu-quota (feine Steuerung)

Low-Level-Parameter; --cpus kapselt beides.

  • --cpu-period: CFS-Periode, Standard 100000 Mikrosekunden (100 ms)
  • --cpu-quota: CPU-Zeit pro Periode in Mikrosekunden
# In 100 ms nur 50 ms CPU (entspricht 0,5 Kern)
docker run --cpu-period=100000 --cpu-quota=50000 nginx

# Äquivalent zu
docker run --cpus="0.5" nginx

Meist reicht --cpus – außer Sie brauchen sehr kurze Perioden für häufigeres Scheduling.

Realer Fall: Ein Bug ließ einen Thread-Pool in Endlosschleife laufen – CPU bei 800 % (8-Kern-Server). Ohne Limit war der ganze Server betroffen, SSH tot. Nach --cpus="2" für alle Container verlangsamt sich nur der betroffene Container – der Rest bleibt stabil.

[Bild: CPU-Limit-Vergleich]
Prompt: CPU usage comparison chart, with and without limits, before/after graph showing CPU spike prevention, performance monitoring dashboard, clean visualization, high quality

Monitoring in der Praxis

Ressourcenlimits sind Schritt eins – Sie müssen wissen, was Container tatsächlich verbrauchen. Sonst merken Sie das Leck erst beim OOM.

Tool 1: docker stats (eingebaut, null Kosten)

Am einfachsten – von Docker mitgeliefert.

# Live-Aktualisierung, Ctrl+C zum Beenden
docker stats

# Einmalige Ausgabe, für Skripte
docker stats --no-stream

# Nur bestimmte Container
docker stats nginx_container mysql_container

Ausgabe etwa so:

CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O
a1b2c3d4e5f6   nginx     0.50%     45.2MiB / 512MiB     8.83%     1.2kB / 0B

Vorteile: Sofort einsatzbereit, keine Installation.
Nachteile: Nur aktueller Zustand, keine Historie, keine Alarme, keine Visualisierung. Gut für Ad-hoc-Analyse, nicht für Dauerbetrieb.

Tool 2: cAdvisor (Google, Container-Monitoring)

cAdvisor (Container Advisor) erkennt alle Container auf dem Host, sammelt CPU, Speicher, Netzwerk, Disk-I/O und bietet Web-UI sowie Prometheus-Metriken.

Start:

docker run -d \
  --name=cadvisor \
  --restart=always \
  -p 8080:8080 \
  -v /:/rootfs:ro \
  -v /var/run:/var/run:ro \
  -v /sys:/sys:ro \
  -v /var/lib/docker/:/var/lib/docker:ro \
  -v /dev/disk/:/dev/disk:ro \
  gcr.io/cadvisor/cadvisor:latest

Unter http://<Server-IP>:8080 sehen Sie Trends pro Container; unter http://<Server-IP>:8080/metrics Prometheus-Format.

Vorteile: Umfassend, Prometheus-Ökosystem.
Nachteile: Nur etwa 2 Minuten Historie – für Trends brauchen Sie Prometheus.

Tool 3: Prometheus + Grafana (Enterprise-Niveau)

Vollständiger Stack:

  • cAdvisor: Metriken sammeln
  • Prometheus: scrapen und speichern
  • Grafana: Visualisierung + Alarme

Vollständige docker-compose.yml:

version: '3.8'

services:
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: cadvisor
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro
    restart: always

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    restart: always

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    restart: always

volumes:
  prometheus_data:
  grafana_data:

Zugehörige prometheus.yml:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

Nach dem Deployment:

  1. Prometheus scraped cAdvisor alle 15 Sekunden
  2. Grafana unter http://<Server-IP>:3000 (Standard admin/admin)
  3. Prometheus als Datenquelle (http://prometheus:9090)
  4. Dashboard importieren (empfohlen: ID 19908 für Docker-Container)

Wichtige Metriken:

  • container_memory_usage_bytes: aktueller Speicherverbrauch
  • container_memory_max_usage_bytes: historisches Maximum
  • container_cpu_load_average_10s: 10-Sekunden-CPU-Last
  • container_fs_io_time_seconds_total: Disk-I/O-Zeit

Alarm bei Speicherauslastung über 80 % per E-Mail oder Chat – Probleme früh erkennen.

Ehrlich: Der Aufbau ist etwas Arbeit, lohnt sich langfristig. Über 20 Container laufen bei mir nur noch über Grafana – nächtliche Weckrufe gehören der Vergangenheit an.

[Bild: Grafana Container-Dashboard]
Prompt: Grafana dashboard showing Docker container metrics, memory and CPU graphs, clean modern UI, dark theme, monitoring panels with colorful charts, high quality

Vollständiger Ablauf zur Diagnose von Speicherlecks

Alarm oder plötzlich beendeter Container – so gehen Sie vor.

Schritt 1: Abweichung erkennen

Mit docker stats prüfen, welcher Container Speicher frisst:

docker stats --no-stream | grep -v "0.00%"

Speicher nahe am Limit? Prüfen, ob der OOM Killer zugeschlagen hat:

# Container-Ereignisse
docker events --filter 'event=oom' --since '24h'

# Exit-Status
docker inspect <Container-Name> --format='{{.State.ExitCode}}'
# 137 = vom OOM Killer beendet

Schritt 2: Speicherverbrauch analysieren

In den Container und Prozesse prüfen:

# Container betreten
docker exec -it <Container-Name> /bin/bash

# Prozesse nach Speicher (top/htop im Container)
top -o %MEM

# Oder mit ps
ps aux --sort=-%mem | head -n 10

Bei Java-Apps Heap-Dump:

# Java-PID finden
jps

# Heap-Dump exportieren
jcmd <PID> GC.heap_dump /tmp/heap.hprof

# Datei kopieren
docker cp <Container-Name>:/tmp/heap.hprof ./

Schritt 3: Sofortmaßnahmen

Wenn der Dienst bereits leidet:

# Container neu starten (temporäre Daten im Container gehen verloren)
docker restart <Container-Name>

# Laufendes Limit anpassen
docker update --memory 1g --memory-swap 1g <Container-Name>

# Ungenutzte Ressourcen bereinigen (Vorsicht – löscht ungenutzte Images/Container)
docker system prune -a

Schritt 4: Dauerhafte Lösung

Notmaßnahmen stoppen nur die Blutung:

  1. Anwendung fixen: Leck in Code finden (offene Verbindungen, unbegrenzter Cache, große Objekte) und beheben
  2. Ressourcenlimits: Falls noch nicht gesetzt – --memory ergänzen
  3. Monitoring: Prometheus + Grafana, Alarm vor dem Ausbruch
  4. Auto-Restart: --restart=on-failure:3, nach OOM maximal 3 Neustarts

Befehls-Spickzettel:

# Ressourcenlimits aller Container
docker ps --format "{{.Names}}" | xargs docker inspect \
  --format='{{.Name}}: Memory={{.HostConfig.Memory}} CPU={{.HostConfig.NanoCpus}}'

# Neustart-Zähler
docker inspect --format='{{.RestartCount}}' <Container-Name>

# Letzte 100 Log-Zeilen
docker logs --tail 100 <Container-Name>

# Speicher-Detail
docker stats --no-stream --format \
  "table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}" <Container-Name>

Rückblick Storj (37 GB): Der Nutzer ging so vor:

  1. Nach Speicher-Spike docker restart für kurzfristige Stabilisierung
  2. -m 1g, damit der Host nicht erneut fällt
  3. Logs und Heap-Dump an das Entwicklungsteam
  4. Nach Bugfix neues Image deployen
  5. cAdvisor mit Alarm bei Speicher > 70 %

Aufwendig – aber danach kein ähnlicher Vorfall mehr.

[Bild: Speicher-Diagnose-Flowchart]
Prompt: flowchart showing memory leak diagnosis process, step by step from detection to resolution, arrows connecting boxes, clean infographic style, blue and green colors, high quality

Best Practices und typische Fallstricke

Parameter und Tools im Überblick – so setzen Sie es in der Produktion um.

Pflicht-Checkliste für die Produktion

Jeder Container braucht ein Speicherlimit
Keine Ausnahmen. Selbst ein Nginx für statische Dateien: mindestens 512 MB. Lieber konservativ als nach einem Vorfall.

Entwicklung wie Produktion
Lokal ohne Limits, in Produktion Speichermangel – vermeiden. In der Entwicklung etwa 80 % der Produktionslimits, Probleme früh sehen.

Regelmäßige Ressourcen-Reviews
Monatlich docker stats – Anforderungen ändern sich; Limits anpassen.

OOM Killer nicht deaktivieren
Außer Sie sind sich absolut sicher, dass die App den Speicher kontrolliert – --oom-kill-disable ist riskant.

Kein unbegrenzter Swap
--memory-swap -1 lockt, ist aber eine Falle. Massiver Swap killt die Festplatte – OOM ist oft die bessere Wahl.

Limits nicht zu niedrig
Unter dem realen Bedarf → ständige OOM-Kills und schlechte Verfügbarkeit. Erst Lasttest, dann Limits.

Richtig in Docker Compose

services:
  web:
    image: nginx:latest
    deploy:
      resources:
        limits:
          cpus: '1.5'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M
    restart: on-failure:3

deploy (Compose v3): limits = Hard Limit, reservations = Soft Limit. Normal 256 MB, Spitzen bis 512 MB.

Viele Container gemeinsam steuern

Mit cgroup-parent eine gemeinsame cgroup für mehrere Dienste:

# Eltern-cgroup mit Gesamtlimit
docker run --cgroup-parent=/my-services -m 2g service-a
docker run --cgroup-parent=/my-services -m 2g service-b
# Beide teilen sich die Eltern-cgroup, Gesamtspeicher begrenzt

Sinnvoll für zusammengehörige Container als eine Business-Einheit.

Faustformeln für Limits

AnwendungstypSpeicher-EmpfehlungCPU-Empfehlung
Nginx (statisch)256–512 MB0,5–1 Kern
Node.js API512 MB–1 GB1–2 Kerne
Java-Microservice1–2 GB2–4 Kerne
Datenbank (MySQL/PostgreSQL)2–4 GB2–4 Kerne
Message Queue (RabbitMQ/Kafka)1–2 GB1–2 Kerne

Konservative Schätzung – Last und Traffic entscheiden. Peak im Lasttest × 1,5 als Limit ist ein solider Ansatz.

Vergleich mit Kubernetes

In Kubernetes entsprechen requests und limits den Docker-Parametern:

  • requests: ähnlich --memory-reservation
  • limits: ähnlich --memory

K8s: Limits zentral in YAML; Docker: flexibler mit docker update.

Abschließender Rat

Ressourcenlimits sind nicht „einmal setzen, für immer“. Apps und Traffic ändern sich – Monitoring zeigt, ob Sie skalieren oder optimieren müssen. Regelmäßig prüfen, Konfiguration nicht verstauben lassen.

[Bild: Vergleich Ressourcenlimits Best Practices]
Prompt: comparison table showing Docker resource limits best practices, checkmarks and crosses, clean infographic style, professional layout, high quality

Fazit

Zurück zur Eröffnung: Alarm um 3 Uhr morgens, Server durch Container lahmgelegt. Die Lektion: Dockers Standard-„Freiheit“ ist eine Falle. Ohne Limits überlassen Sie dem Container die Kontrolle über den Server.

Die Verteidigung in drei Linien:

Erste Linie: Ressourcenlimits (Prävention)
Jeder Container mit --memory und --cpus – wie ein Zügel am wilden Pferd. Bei Kontrollverlust fällt nur der Container aus, nicht der ganze Server. Basis und entscheidend.

Zweite Linie: Monitoring und Alarme (Erkennung)
docker stats für den Moment; cAdvisor + Prometheus + Grafana für Trends und Historie. Alarm bei Speicher > 80 % – oft 48 Stunden Vorlauf vor dem Desaster.

Dritte Linie: Diagnose-Ablauf (Reaktion)
Im Ernstfall: Abweichung → Analyse → Sofortmaßnahme → dauerhafte Lösung. Die Befehle stehen oben.

Von cgroups über --memory-swap bis Compose und Kubernetes – das Wichtige zu Docker-Ressourcenlimits ist hier. Der Rest liegt bei Ihnen.

Drei Schritte jetzt:

  1. Produktion prüfen – welche Container haben kein Limit?
docker ps --format "{{.Names}}" | xargs docker inspect \
  --format='{{.Name}}: Memory={{.HostConfig.Memory}} CPU={{.HostConfig.NanoCpus}}'

Memory=0 bedeutet Zeitbombe.

  1. Monitoring deployen – docker-compose.yml aus dem Artikel kopieren, in 30 Minuten startklar.

  2. Kalender-Erinnerung – monatlich 1 Stunde docker stats, Ressourcen prüfen.

Ich wünsche Ihnen nicht die Lektion um 3 Uhr morgens. Ressourcenlimits lohnen sich je früher – nicht erst nach dem Vorfall.

Vollständiger Ablauf zur Konfiguration von Docker-Ressourcenlimits

Speicherlecks in Containern verhindern, bevor sie den Server lahmlegen – von cgroups über --memory und --cpus bis zu Monitoring-Lösungen

⏱️ Estimated time: 1 hr

  1. 1

    Step 1: Schwere des Problems und cgroups-Prinzip verstehen

    Schwere des Problems:
    • Speicherlecks in Containern wachsen von 500 MB auf 16 GB
    • Der gesamte Server-Speicher ist aufgebraucht, selbst SSH reagiert nicht mehr
    • Andere normal laufende Container fallen ebenfalls aus – die Produktion bricht zusammen

    cgroups-Prinzip:
    • cgroups (Control Groups) im Linux-Kernel steuern die Ressourcennutzung von Containern
    • Docker begrenzt CPU, Speicher, I/O und andere Ressourcen über cgroups
    • Ein einzelner Container kann so nicht mehr den gesamten Server lahmlegen

    2024 gab es in Docker 27.0.3 einen schwerwiegenden Speicherleck-Bug, der dazu führte, dass der OOM Killer des Linux-Kernels 68 Container auf einmal beendete.
  2. 2

    Step 2: Ressourcenlimits konfigurieren: Speicher und CPU

    Speicherlimits:
    • Speicher mit --memory begrenzen: docker run --memory=512m container-name
    • Ressourcenlimits in docker-compose: deploy.resources.limits.memory: 512m
    • Swap-Limit setzen: --memory-swap

    CPU-Limits:
    • CPU mit --cpus begrenzen: docker run --cpus=1.0 container-name
    • CPU-Gewichtung mit --cpu-shares setzen
    • In docker-compose: deploy.resources.limits.cpus: '1.0'

    Limits verifizieren:
    • Ressourcennutzung mit docker stats prüfen
    • Bestätigen, dass die Limits greifen
  3. 3

    Step 3: Monitoring-Lösung und Best Practices bereitstellen

    Monitoring-Lösung:
    • docker stats für Echtzeit-Überwachung: docker stats container-name
    • cAdvisor mit Web-Oberfläche:
    docker run -d -p 8080:8080 --name=cadvisor google/cadvisor
    • Prometheus + Grafana für produktionsreife Überwachung und Alarme:
    Prometheus so konfigurieren, dass cAdvisor-Metriken gescraped werden; Grafana für Visualisierung

    Best Practices:
    • In der Produktion sind Ressourcenlimits Pflicht
    • Sinnvolle Limit-Werte setzen (Speicher, CPU)
    • Monitoring und Alarme konfigurieren
    • Ressourcennutzung regelmäßig prüfen (monatlich 1 Stunde docker stats)
    • Abweichungen zeitnah beheben

FAQ

Warum sollte man Docker-Ressourcenlimits konfigurieren?
Schwere des Problems:
• Speicherlecks in Containern wachsen von 500 MB auf 16 GB
• Der gesamte Server-Speicher ist aufgebraucht, selbst SSH reagiert nicht mehr
• Andere normal laufende Container fallen ebenfalls aus – die Produktion bricht zusammen

2024 gab es in Docker 27.0.3 einen schwerwiegenden Speicherleck-Bug, der dazu führte, dass der OOM Killer des Linux-Kernels 68 Container auf einmal beendete.

Ressourcenlimits verhindern, dass ein einzelner Container den gesamten Server lahmlegt. Bei ersten Anzeichen eines Speicherlecks fällt der Container selbst aus – statt den ganzen Server mitzunehmen.
Wie konfiguriert man Ressourcenlimits für Docker-Container?
Speicherlimits:
• Speicher mit --memory begrenzen: docker run --memory=512m container-name
• Ressourcenlimits in docker-compose: deploy.resources.limits.memory: 512m
• Swap-Limit setzen: --memory-swap

CPU-Limits:
• CPU mit --cpus begrenzen: docker run --cpus=1.0 container-name
• CPU-Gewichtung mit --cpu-shares setzen
• In docker-compose: deploy.resources.limits.cpus: '1.0'

Limits verifizieren:
• Ressourcennutzung mit docker stats prüfen
• Bestätigen, dass die Limits greifen
Wie überwacht man die Ressourcennutzung von Docker-Containern?
Monitoring-Lösung:

docker stats in Echtzeit:
• docker stats container-name

cAdvisor mit Web-Oberfläche:
• docker run -d -p 8080:8080 --name=cadvisor google/cadvisor

Prometheus + Grafana für produktionsreife Überwachung und Alarme:
• Prometheus so konfigurieren, dass cAdvisor-Metriken gescraped werden
• Grafana für Visualisierung

Monitoring bereitstellen: docker-compose.yml aus dem Artikel kopieren und starten – in 30 Minuten erledigt.

Regelmäßige Prüfung: monatlich 1 Stunde docker stats, Ressourcennutzung auf Plausibilität prüfen.
Was sind die Best Practices für Docker-Ressourcenlimits?
Best Practices:
• In der Produktion sind Ressourcenlimits Pflicht
• Sinnvolle Limit-Werte setzen (Speicher, CPU)
• Monitoring und Alarme konfigurieren
• Ressourcennutzung regelmäßig prüfen (monatlich 1 Stunde docker stats)
• Abweichungen zeitnah beheben

Ressourcenlimits lohnen sich je früher, desto weniger Ärger. Kalender-Erinnerung setzen: monatlich 1 Stunde docker stats, Ressourcennutzung auf Plausibilität prüfen.

13 Min. Lesezeit · Veröffentlicht am: 18. Dez. 2025 · Aktualisiert am: 14. Juli 2026

Ähnliche Beiträge

Kommentare

Melde dich mit GitHub an, um einen Kommentar zu hinterlassen

Easton BlogEaston Blog