linux-kernel-advanced performance tuning cgroups isolation kernel container advanced

Control Groups v1: Resource Isolation (Artikel 373)

Analyse des Control Groups v1 Subsystems. Erfahren Sie alles über die manuelle Limitierung von CPU, RAM und I/O-Ressourcen sowie die Architektur der klassischen Cgroups.

# Cgroups v1: Die Geburt der Ressourcen-Isolation

TL;DR / Management Summary Ohne Cgroups (Control Groups) gäbe es keine Container. Es ist das Kernel-Feature, das es erlaubt, Prozesse in Gruppen zusammenzufassen und diesen Gruppen harte Ressourcen-Limits (z.B. “Max. 2GB RAM”, “Max. 1 CPU-Kern”) zuzuweisen. In diesem Modul lernen wir die klassische v1-Architektur kennen, die heute noch in vielen Legacy-Systemen und Docker-Versionen aktiv ist. Wer Cgroups versteht, kann verhindern, dass ein einzelner Prozess den gesamten Host lahmlegt.


# 1. Einführung & Architektur

Die Trennung der Ressourcen.

Cgroups v1 ist modular aufgebaut. Jede Ressource (CPU, RAM, Disk-I/O) wird von einem eigenen Controller (Subsystem) verwaltet. Diese sind als virtuelle Dateisysteme unter /sys/fs/cgroup/ gemountet.

# Die v1-Struktur (Mermaid)

graph TD
    A[Root Cgroup: /sys/fs/cgroup/] --> B[cpu: CPU Time]
    A --> C[memory: RAM Limit]
    A --> D[blkio: Disk I/O]
    B --> B1[Group: web_server]
    B --> B2[Group: database]
    B1 --> B3[PID 1234]
    B1 --> B4[PID 5678]
    C --> C1[Group: web_server]
  • Vorteil: Extreme Flexibilität. Ein Prozess kann in der cpu Gruppe A und in der memory Gruppe B sein.
  • Nachteil: Unübersichtlich und inkonsistent bei komplexen Hierarchien.

# 2. Manuelle Verwaltung via Dateisystem

Limits ohne Tools setzen.

# Schritt 1: Gruppe erstellen

sudo mkdir /sys/fs/cgroup/memory/myapp

# Schritt 2: RAM-Limit setzen (z.B. 512MB)

echo "512M" | sudo tee /sys/fs/cgroup/memory/myapp/memory.limit_in_bytes

# Schritt 3: Prozess hinzufügen

# Verschiebt einen laufenden Prozess in die Gruppe
echo 1234 | sudo tee /sys/fs/cgroup/memory/myapp/cgroup.procs

# 3. Die wichtigsten Controller

Wer regelt was?

  1. CPU: Steuert die Anteile (cpu.shares) oder harte Millisekunden pro Sekunde (cpu.cfs_quota_us).
  2. Memory: Limitiert den RAM-Verbrauch und steuert das OOM-Verhalten.
  3. Blkio: Begrenzt die IOPS oder Bandbreite (Bytes/s) für Block-Devices.
  4. Cpuset: Bindet Prozesse an spezifische CPU-Kerne (ähnlich wie taskset, aber auf Gruppenebene).

# 4. Day-2 Operations: Monitoring

Wer sprengt sein Limit?

# Speicherverbrauch prüfen

cat /sys/fs/cgroup/memory/myapp/memory.usage_in_bytes

# OOM-Killer Statistik

cat /sys/fs/cgroup/memory/myapp/memory.failcnt
# Wenn dieser Wert steigt, hat die Gruppe ihr Limit erreicht.

# 5. Troubleshooting & “War Stories”

Wenn die Gruppe zur Falle wird.

# Story 1: “Der hängende Prozess-Verschub”

Symptom: Ein Admin versucht, einen Prozess in eine Cgroup zu verschieben, aber der echo Befehl bricht mit Invalid argument ab. Ursache: Cgroups v1 erlaubt den Verschub von Threads oft nicht einzeln, oder der Prozess hat bereits Kindprozesse in anderen inkompatiblen Gruppen. Lösung: Stellen Sie sicher, dass Sie alle Threads des Prozesses gleichzeitig verschieben oder nutzen Sie moderne Management-Tools wie cgred (CGroup Rules Engine Dämon).

# Story 2: “Das Memory-Leak im Cache”

Symptom: Eine Applikation in einer Cgroup wird gekillt, obwohl der reale Speicherverbrauch (RSS) niedrig ist. Ursache: memory.limit_in_bytes zählt in v1 auch den Page Cache (Dateizugriffe) mit. Wenn die App viele Dateien liest, zählt dies gegen das Limit. Lösung: Nutzen Sie memory.soft_limit_in_bytes, um dem Kernel zu erlauben, Caches freizugeben, bevor der Prozess gekillt wird.


# 6. Fazit & Empfehlung

  • Wahl: Nutzen Sie für neue Projekte die konsistentere Cgroups v2 Architektur (Artikel 374).
  • Pflicht: Limitieren Sie jeden Dienst, den Sie manuell (ohne Container) betreiben, via Cgroups. Es ist die einzige Versicherung gegen “Resource Exhaustion”.
  • Wartung: Nutzen Sie Tools wie cgtop, um eine Übersicht aller Gruppen zu erhalten.

# Anhang: Cheatsheet

Aufgabe Pfad / Befehl
Mount-Punkte finden lssubsys -m
Gruppe erstellen cgcreate -g memory:name
Limit setzen cgset -r memory.limit_in_bytes=1G name
Prozess hinzufügen cgclassify -g memory:name <pid>
CPU-Quota Info cat /sys/fs/cgroup/cpu/cpu.stat
RAM Statistik cat /sys/fs/cgroup/memory/memory.stat
PIDs in Gruppe cat /sys/fs/cgroup/memory/name/tasks
Paket suchen (Arch) sudo pacman -S libcgroup
Paket suchen (Alpine) apk add libcgroup