Cgroups & Namespaces – Verwalten

Als Linux‑Systemadministrator sind Cgroups und Namespaces Ihre Werkzeuge, um Systemressourcen zuverlässig im Griff zu behalten. Sie ermöglichen es, Prozesse und Dienste sauber zu trennen und deren Ressourcennutzung zu kontrollieren.
Im Folgenden erfahren Sie, wie Sie diese Kernel‑Funktionen einsehen und einfach verwalten können.


1 · Namespaces – Prozesse isolieren

Namespaces trennen globale Systemressourcen voneinander. Jeder Prozess erhält so seine eigene, isolierte Sicht auf ausgewählte Ressourcen.

Funktionsprinzip

Stellen Sie sich vor, jeder Prozess bekäme seine persönliche „Version“ von Systemelementen wie Prozess‑IDs, Netzwerkgeräten oder Dateisystem‑Mounts. Ein Prozess sieht nur seine eigenen PIDs und Netzwerk‑Interfaces – das schafft starke, logische Trennung.

NamespaceZweckTypische Auswirkung
PIDEigene Prozess‑ID‑ListeProzess sieht nur seine PIDs
NETEigene NetzwerkkonfigurationEigene Interfaces & Routen
MNTIsolierte Dateisystem‑HierarchieEigene Mount‑Tabelle
UTSEigener HostnameHostname separat änderbar
USERUID‑Mapping / Root im NamespaceRoot innen, unpriv. außen

Namespaces anzeigen

lsns
SpalteBedeutung
NSeindeutige Namespace‑ID (Inode)
TYPENamespace‑Typ (pid, net, mnt, uts, user, ipc, cgroup)
NPROCSAnzahl Prozesse im Namespace
PIDBeispiel‑PID, die im Namespace läuft
COMMANDKommando des Beispiel‑Prozesses

Tipp: Eine hohe NPROCS‑Zahl oder bekannte TYPE‑Werte wie net oder pid deuten auf aktive Isolationsumgebungen (Container, spezielle Dienste) hin.

Namespace‑Details für einen bestimmten Prozess

sudo ls -la /proc/<PID>/ns/
# Beispiel: sudo ls -la /proc/1/ns/

Symbolische Links wie net -> 'net:[4026532009]' zeigen die Inode‑Nummer. Vergleichen Sie die Zahlen verschiedener Prozesse, um zu erkennen, ob sie denselben Namespace teilen.

Warum man Namespaces selten manuell erstellt

Eine vollwertige, manuell aufgebaute Umgebung verlangt:

  • Dateisysteme mounten (/proc, /sys, /dev, chroot)

  • Netzwerk konfigurieren (veth‑Paar, IP‑Adressen, Routen)

  • Init‑Prozess starten (PID 1 muss Kindprozesse verwalten)

  • Berechtigungen mappen (UID/GID‑Mapping im USER‑Namespace)

Ein fehlender oder falscher Schritt führt zu unvollständiger Isolation. Container‑Runtimes (Docker, Podman …) erledigen diesen Aufwand automatisiert.

Beispiel: neuer PID‑Namespace

sudo unshare --pid --fork --mount-proc bash
# Innerhalb der neuen Shell:
ps aux    # zeigt nur Prozesse im neuen Namespace (PID 1 = bash)
exit      # zurück im ursprünglichen Namespace
  • --pid  → neuer PID‑Namespace

  • --fork → Prozess als Kind starten

  • --mount-proc/proc neu mounten, damit die PIDs stimmen

Isolierte Umgebung: pivot_root vs. chroot

Eine eigene Mount‑Namespace stellt zunächst sicher, dass alle Einhängepunkte (Mounts) vom Host getrennt sind. Anschließend schafft man mit pivot_root – oder in einfacheren Fällen mit chroot – ein eigenständiges Wurzeldateisystem, in dem Prozesse sicher eingeschlossen bleiben.

Aspektchrootpivot_root
GrundideeVerlegt nur den Blick auf „/“.Tauscht das gesamte Root‑Mount dieser Namespace.
SicherheitAltes Dateisystem bleibt erreichbar (Escape über offene FDs).Altes Root kann vollständig ausgehängt werden – kein Rückweg.
Typischer EinsatzBuild‑Jails, Rescue‑Shells.Container‑Runtimes (Docker, podman, LXC) und initrd → echtes Root beim Boot.

Ablauf in drei Schritten

  1. Mount‑Namespace starten – z. B. mit unshare -mU oder durch eine Container‑Runtime.

  2. Root‑Baum vorbereiten – gewünschtes Dateisystem (z. B. /srv/jail) vollständig befüllen.

  3. Root wechseln
    Einfache Sandbox: chroot /srv/jail /bin/sh
    Voll isoliert: pivot_root /srv/jail /srv/jail/.old → danach umount -l /.old.

Merksatz
chroot setzt Scheuklappen auf, pivot_root baut eine neue Welt.


2 · Cgroups – Ressourcen begrenzen

Cgroups v2 unter systemd – komplette, legacy‑freie Übersicht

Was sind Cgroups?

Control Groups (Cgroups) sind eine Kernel‑Funktion, mit der Prozesse in hierarchisch organisierte Gruppen einsortiert werden. Für jede Gruppe lassen sich Limits, Prioritäten und Statistiken für Ressourcen wie CPU‑Zeit, Hauptspeicher, I/O‑Bandbreite und Prozesszahl festlegen.

  • Baumstruktur – Vererbung: Ein Kind erbt die Limits seines Elternknotens und darf sie nur verschärfen, nie lockern.

  • Controller: Module wie cpu, memory, io, pids setzen unterschiedliche Arten von Grenzwerten.

  • Durchsetzung im Kernel: Scheduler, Memory‑Manager und Block‑I/O‑Layer lesen diese Grenzen und drosseln oder beenden Prozesse, sobald sie dagegen verstoßen.

Seit cgroup v2 (stabil seit Linux 4.5 / 2016) gibt es nur noch einen gemeinsamen Baum; alle Controller befinden sich dort. systemd baut und verwaltet diesen Baum automatisch – separate Tools aus der cgroup v1‑Ära werden damit überflüssig.

Kernidee:
Eine Control Group (Cgroup) ist ein Knoten in einem Baum. Jeder Knoten kann festlegen, wie viel CPU‑Zeit, RAM, I/O usw. seine Prozesse verbrauchen dürfen.
Seit 2021 benutzen praktisch alle Distributionen cgroup v2 + systemd – alles wird mit systemd‑Units verwaltet, kein cgcreate, kein cgroupfs‑mount nötig.


1 · Hierarchie & Begriffe

ElementWas es istWozu es dient
SliceDauerhafte „Schublade“ ganz oben im Baum (*.slice)Grobe Ressourcenschichtung: system.slice (System‑Dienste), user.slice (User‑Sessions). Limits hier wirken vererbend auf alles darunter.
ServiceUnit, die systemd selbst startet und überwacht (*.service)Typisch für Daemons wie nginx.service.
ScopeUnit für schon laufende PIDs (*.scope)Entsteht z. B. bei Login‑Sessions oder per systemd-run --scope.

Systemd legt beim Boot vier Slices an:

-.slice         (Root, darf unbegrenzt)
├─system.slice  (alle System‑Services)
├─user.slice    (angemeldete Benutzer)
└─init.scope    (PID 1 und seine Hilfs‑Threads)

Du kannst eigene Slices anlegen, um z. B. speicherhungrige Dienste gemeinsam zu deckeln.


2 · Baum anzeigen & lesen

systemd-cgls --no-pager

Beispiel‑Ausgabe:

├─1 /sbin/init
├─user.slice
│ └─user-1000.slice
│   ├─session-3.scope   # deine Shell & Tools
│   │ ├─2158 /usr/bin/bash
│   │ └─2190 htop
│   └─user@1000.service # DBus, gvfs, …
└─system.slice
  ├─nginx.service
  │ ├─668 nginx: master process
  │ └─672 nginx: worker process
  └─postgresql.service
    ├─872 /usr/lib/postgresql/16/bin/postmaster
    └─…
  • Eingerückte Pfade = Cgroup‑Verzeichnisse.
    Pfad von htop lautet hier /user.slice/user-1000.slice/session-3.scope/.

  • Abhängigkeiten (Vererbung):
    session-3.scope erbt Limits von user-1000.slice, das wiederum von user.slice erbt. Schärfere Limits tiefer im Baum übersteuern Elternwerte; lockern dürfen sie sie nie.


3 · Limits ad‑hoc testen

# 500 MB RAM‑Deckel & 40 % CPU‑Quote für ein Skript
sudo systemd-run --unit=testscope.scope \
                 --scope -p MemoryMax=500M -p CPUQuota=40% \
                 ./mein_skript.sh
  • Erstellt sofort testscope.scope unter deiner Sitzung.

  • Limits gelten nur solange der Prozess lebt.

Mit systemd-cgtop siehst du live, ob die Begrenzung greift.


4 · Eigene Slices & dauerhafte Limits

4.1 Slice‑Unit anlegen

# /etc/systemd/system/limits-lowprio.slice
[Slice]
CPUQuota=25%        # hartes 25 %-Limit
MemoryHigh=1G       # weicher RAM‑Deckel (Druck ab 1 GB)
IOWeight=50         # niedrigere I/O‑Priorität (1–10000, Standard 100)
sudo systemctl daemon-reload
sudo systemctl enable --now limits-lowprio.slice

Damit existiert ein Teilbaum /limits-lowprio.slice/….

4.2 Dienst hineinverschieben

sudo systemctl edit nginx.service
# /etc/systemd/system/nginx.service.d/10-slice.conf
[Service]
Slice=limits-lowprio.slice
MemoryMax=512M      # zusätzlich enger
CPUWeight=100       # „Shares“ in cgroup v2
sudo systemctl daemon-reload
sudo systemctl restart nginx

4.3 Units on‑the‑fly ändern

# sofort + persistent (Drop‑In in /etc)
sudo systemctl set-property postgresql.service CPUQuota=60% MemoryHigh=2G

--runtime anhängen, wenn es nur bis zum nächsten Reboot gelten soll.


5 · Laufende Prozesse nachträglich einordnen

# Prozess 2190 (htop) in limits-lowprio.slice verschieben
sudo systemd-run --scope --unit=htop-low \
                 --slice=limits-lowprio.slice --pid=2190

Systemd erzeugt automatisch htop-low.scope unter dem Slice und schreibt die PID in cgroup.procs.


6 · Wichtige Controller‑Properties (cgroup v2)

Ressourcesystemd‑PropertyEffekt
CPUCPUQuota= (hart, % von 100 %)CPUWeight= (relativ, 1‑10000)Zeitanteil begrenzen / fair verteilen
RAMMemoryMax= (hart)MemoryHigh= (weicher Schwellenwert)Out‑of‑memory verhindern / Speicherdruck auslösen
I/OIOWeight= (1‑10000)IOReadBandwidthMax=``IOWriteBandwidthMax=Priorität / BW‑Limit pro Blockgerät
PIDsTasksMax=Anzahl Threads & Prozesse

Alle lassen sich in *.slice, *.service oder zur Laufzeit per systemctl set-property setzen.


7 · Monitoring in Echtzeit

systemd-cgtop          # CPU, Memory, I/O-Verbrauch pro Cgroup
systemctl status nginx # zeigt "Control Group: /limits-lowprio.slice/…"
systemctl show nginx   | grep -iE 'cpu|memory|io|tasks'

Mehr Details liefert das Dateisystem selbst:

cat /sys/fs/cgroup/limits-lowprio.slice/nginx.service/memory.current
cat /sys/fs/cgroup/limits-lowprio.slice/nginx.service/cpu.stat

8 · Fallstricke & Tipps

  • Vererbungs‑Kaskade: Ein hartes MemoryMax im Slice kapp alle Units darunter, egal was sie selbst setzen.

  • CPUQuota vs. CPUWeight: Nur Quota begrenzt absolut. Weight ist relativ – 200 vs 100 = doppelt so viel, aber nur solange kein Quota greift.

  • Soft‑vs.-Hard‑RAM: MemoryHigh drückt erst, wenn knapp; MemoryMax killt sofort, wenn überschritten.

  • Delegation: Container‑Engines wie Docker brauchen Delegate=yes, um unter ihrer Unit eigene Cgroups anzulegen.

  • systemd-run zum Debuggen: Super, um Limits risikolos auszuprobieren, bevor man Services umstellt.


9 · Kurz‑Spickzettel

# Hierarchie sehen
systemd-cgls
 
# Live‑Verbrauch
systemd-cgtop
 
# Slice mit 30 % CPU anlegen
echo -e "[Slice]\nCPUQuota=30%" | sudo tee /etc/systemd/system/limited.slice
sudo systemctl daemon-reload && sudo systemctl start limited.slice
 
# Dienst dauerhaft einsortieren
sudo systemctl set-property --runtime=false nginx.service Slice=limited.slice MemoryMax=512M
 
# Prozess‑PID schnell drosseln
sudo systemd-run --scope -p CPUQuota=20% --pid=<PID>

Fazit – Isolation trifft Limitierung

  • Namespaces trennen die Umgebung von Prozessen und Prozessgruppen.

  • Cgroups begrenzen deren Ressourcenverbrauch.

LinuxKernelCgroupsNamespacesSystemdProcessIsolationRessourcenmanagementSysAdminTipsLinuxAdministrationPivotRootChrootPerformanceTuningKernelHacks

Linux-Blog-Overview