29 Ressourcenbegrenzungen und -limits

29.1 Warum Container Ressourcenbegrenzungen brauchen

Container sind Prozesse – aber Prozesse ohne Grenzen können ein System ebenso blockieren wie ein schlecht programmiertes Monolithenprogramm. Während Docker lange mit einer Art „Best Effort“-Herangehensweise arbeitete, integriert Podman Ressourcensteuerung direkter und transparenter über die Linux-Cgroups. CPU, RAM, Block-I/O und PIDs lassen sich präzise regulieren. Für produktionsnahe Anwendungen ist das unverzichtbar: Ein einzelner Container darf weder das Gesamtsystem dominieren noch durch interne Fehler andere Dienste in Mitleidenschaft ziehen.

Podman nutzt ausschließlich Mechanismen des Linux-Kernels. Keine proprietären Scheduler, keine Daemonintervention, keine versteckten Obergrenzen. Alles läuft über Cgroups v2 oder – in älteren Systemen – Cgroups v1.


29.2 Cgroups v2 als Fundament

Moderne Distributionen aktivieren Cgroups v2 standardmäßig. Diese Fassung vereinheitlicht die Ressourcensteuerung in einer konsistenten, hierarchischen Struktur. Podman nutzt genau diese Struktur, um Containergrenzen abzubilden.

Ein abstrahiertes Modell:

Jeder Container erhält seine eigene Cgroup. Limits werden direkt als Dateien im jeweiligen Cgroup-Verzeichnis gesetzt – lesbar, nachvollziehbar, jederzeit mit klassischen Linux-Tools prüfbar.

Beispiel:

/sys/fs/cgroup/user.slice/podman-12345.scope/

29.3 CPU-Limits: Zeitanteile statt Kerne

Die wichtigste Unterscheidung: CPU-Limits bestimmen Zeitanteile, nicht physische Kerne.

29.3.1 CPU-Quota und CPU-Period

Mit folgenden Parametern lässt sich die CPU-Zeit begrenzen:

podman run --cpus=1.5 ...

Podman übersetzt dies intern in Cgroup-Parameter wie:

CPU-Limits sind keine Reservierungen, sondern Obergrenzen. Wird das System nicht ausgelastet, kann ein Container mehr Zeit bekommen – jedoch nie mehr als seine Quota in Konkurrenzsituationen.

29.3.2 CPU-Affinität

Optional lassen sich Kerne explizit zuweisen:

podman run --cpuset-cpus="2-3" ...

Dies ist nützlich, wenn bestimmte Anwendungen isoliert laufen sollen. Für datenbankähnliche Prozesse oder rechenintensive Dienste kann CPU-Pinning deterministische Performance erzeugen.


29.4 Speicherlimits: harte und weiche Grenzen

Speicher lässt sich deutlich granularer begrenzen als CPU.

29.4.1 Hard Limit (der Klassiker)

podman run --memory=512m ...

Dies definiert eine absolute Obergrenze. Wird sie überschritten, erhält der Prozess ENOMEM. Häufig führt das zum Out-of-Memory-Kill.

29.4.2 Memory-Swap Limits

podman run --memory-swap=1g ...

Hier legt man eine kombinierte Grenze aus RAM + Swap fest. In produktionsnahen Systemen ist Swap oft unerwünscht oder deaktiviert. In solchen Fällen sollte die Swap-Grenze identisch mit dem RAM-Limit gesetzt werden.

29.4.3 Memory-Reservation (Soft Limit)

podman run --memory-reservation=256m ...

Das Soft-Limit ist ein „Bitte, aber nicht zwingend“. Prozesse dürfen darüber hinaus wachsen, werden aber bevorzugt zurückgedrängt, wenn andere Dienste Ressourcen benötigen.

29.4.4 Memory-Min/Low/High Controls (Cgroups v2)

In modernen Systemen lassen sich feinere Schichten definieren:

Diese Parameter sind insbesondere bei Workloads nützlich, die Lastspitzen zeigen, aber typischerweise wenig RAM benötigen.


29.5 PID-Limits: Schutz vor Prozess-Explosion

PID-Limits sind ein Sicherheitsnetz gegen „Forkbomben“ oder unkontrollierte Parallelisierung:

podman run --pids-limit=500 ...

Ein Container kann so maximal 500 Prozesse erzeugen – inklusive Threads. Dies schützt das System vor Ressourcenerschöpfung im Kernel (der PID-Space ist begrenzt).


29.6 I/O-Limits: Kontrolle über Blockgeräte

Auch Block-I/O lässt sich regulieren. Das ist relevant, wenn mehrere Container gemeinsam auf NVMe- oder SSD-Ressourcen zugreifen und ein einzelner Dienst nicht alle IOPS dominieren darf.

Beispiele:

podman run --blkio-weight=200 ...

oder präziser:

podman run \
  --device-read-bps /dev/nvme0n1:100mb \
  --device-write-bps /dev/nvme0n1:50mb \
  ...

Die Parameter steuern:


29.7 Netzwerk-Limits: Bandbreitenkontrolle

Netzwerk-Bandbreiten lassen sich über Traffic Control (tc) und Podman-Optionen steuern – besonders sinnvoll bei Entwicklungsservern oder geteilten Hosts.

podman run --network-rate=10mbit ...
podman run --network-latency=20ms ...

Podman konfiguriert dafür Netavark bzw. CNI, die wiederum Linux-tc nutzen.

Es sind keine isolierten Netzwerk-Stacks mit eigenem Scheduler; stattdessen wird direkt der Host-Netzwerkstack gedrosselt. Das macht das Verhalten gut vorhersehbar.


29.8 Ressourcen in Pods (Gruppierung mehrerer Container)

Podman unterstützt gruppierte Container über Pods. Diese teilen:

Für Ressourcenlimits ergeben sich zwei Methoden:

29.8.1 Limits pro Container

Jeder Container erhält seine eigene Cgroup (Standard).

29.8.2 Limits pro Pod

Pod-Grenzen werden wie eine Ober-Cgroup gesetzt. Einzelne Container erben diese Grenzen:

podman pod create --cpus=4 --memory=4g --name webpod

Beispielhafte Struktur:

Diese Gruppierung eignet sich für Dienste, die gemeinsam als Einheit auftreten sollen – etwa ein Webserver plus Worker plus Cache.


29.9 Kontrolle über Cgroups ohne Podman

Ein wesentlicher Vorteil des daemonlosen Podman-Designs: Alle Limits sind direkt im Cgroup-Dateisystem sichtbar.

Beispiel:

cat /sys/fs/cgroup/user.slice/podman-12345.scope/memory.max

oder:

systemd-cgls

Damit lassen sich Containergrenzen prüfen, ohne jemals Podman selbst aufzurufen.

Für Diagnosen im Produktivbetrieb ist das ein unschätzbarer Vorteil: Probleme lassen sich mit Standard-Linux-Werkzeugen analysieren.


29.10 Praktische Hinweise für produktionsnahe Anwendungssysteme


Ressourcenbegrenzungen sind bei Podman kein Add-on, sondern ein direkt sichtbarer Bestandteil der Kernelmechanismen. Wer diese Limits bewusst einsetzt, schafft Systeme, die planbar, kontrollierbar und im Fehlerfall analysierbar bleiben.