Begriff
Linux Namespace
Warum wichtig?
Dieser Begriff ist ein Knoten im SengakujiWorks-Wissensnetz. Nutze Level 0 für die erste Einordnung, Level 1 für Praxis, Level 2 für technische Struktur und Level 3 für Grenzen, Fallstricke und Expertenkontext.
Stell dir vor, du wohnst in einem Haus (Server) mit vielen Zimmern. Normalerweise können alle in den Flur schauen und sehen, wer sonst noch da ist. Namespaces sind wie magische Zimmer. Wer im Zimmer "Container A" sitzt, glaubt, er sei alleine im Haus. Er sieht keine anderen Bewohner. Er sieht eine eigene Uhr, eigene Möbel (Festplatte), eigene Fenster (Netzwerk). Für den Hausmeister (Kernel) wohnen aber alle im selben Haus. Das ist der Trick hinter Containern: Die Prozesse laufen auf dem gleichen Kernel, aber sie sehen unterschiedliche Welten.
Merksatz: Ein Feature des Linux-Kernels, das Systemressourcen (wie Prozess-IDs, Netzwerk, Mount-Punkte) so isoliert, dass Prozesse innerhalb eines Namespace den Eindruck haben, sie hätten das System für sich allein.
Als Admin nutzt du unshare (CLI Tool), um Namespaces zu testen:
unshare --fork --pid --mount-proc /bin/bash
Du bist jetzt in einer neuen Shell.
Tippe ps aux.
Du siehst nur zwei Prozesse: Deine Bash und ps.
Alle anderen hunderte Prozesse des Systems sind unsichtbar.
Docker macht genau das für jeden Container.
Praxisroutine
In der Praxis lernst du Linux Namespace, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
1. Die 7 (oder 8) Namespaces
- PID: Eigene Prozess-Nummern (PID 1 im Container).
- NET: Eigener Netzwerk-Stack (eth0, IP, iptables).
- MNT: Eigene Mounts (Das Image-Dateisystem).
- UTS: Eigener Hostname (
my-container). - IPC: Eigene Shared Memory Segmente (damit Container A nicht in RAM von B schreibt).
- USER: Eigene User-IDs (Root im Container = Nobody draußen).
- CGROUP: Eigene Cgroup-View (selten genutzt).
- TIME: Eigene Uhrzeit (Neu in Kernel 5.6!).
2. Enter Namespace (nsenter)
Ein mächtiges Debugging-Tool.
Wenn ein Container spinnt, aber keine Shell (/bin/bash) hat.
Du kannst vom Host aus in den Namespace "springen".
- Finde PID:
docker inspect --format '{{.State.Pid}}' my-container-> 12345. nsenter --target 12345 --net --pidJetzt bist du mit deiner Host-Shell im Netzwerk- und Prozess-Namespace des Containers. Du kannstip addrtippen und siehst die Container-IP, obwohl du "draußen" bist.
3. User Namespaces (The Missing Link)
Lange Zeit war Docker unsicher, weil "Root im Container" auch "Root am Host" war (wenn man ausbricht). User Namespaces mappen UIDs. Container UID 0 (Root) -> Host UID 100.000 (Subuid). Selbst bei einem Kernel-Exploit bricht der Hacker aus und ist... Nobody. Das ist der Heilige Gral der Container-Sicherheit, aber komplex einzurichten (File Permissions).
1. File Deskriptor Leakage und unshare() Internals
Der pure clone()-Syscall reicht nicht, um eine Container-Runtime zu bauen. Ein gefährlicher Vektor für Container-Breaches ist das Leakage von File Deskriptoren vom Host in den Namespace.
Wenn der Parent-Prozess per fork(CLONE_NEWPID | CLONE_NEWNET) den Namespace spannt, erbt das Kind (der Container-Init) still und heimlich alle offenen File Descriptoren (Sockets, File-Handles).
Wenn im Host noch /etc/shadow als offener Descriptor 5 im C-Speicher lag, nützt im Container selbst der radikalste Mount-Namespace absolut nichts. Das Container-Binary greift trivial in C via read(5, buf) komplett am Namespace vorbei in den Host-Rootfs hinein! Echtes "Jailen" erfordert daher striktes FD-Srubbing (Close-on-Exec O_CLOEXEC) bevor in den Container execve gedroppt wird.
2. ARP-Poisoning & veth-Pair Netzwerk Isolation (NET Namespace)
Wie telefoniert ein NET Namespace? Die Applikation sieht drinnen eth0, doch faktisch ist das ein Software-Illusion.
Linux nutzt hier Virtual Ethernet Pairs (veth-pairs). Das ist ein virtuelles Kupferkabel. Das CNI-Plugin (Calico/Flannel) stopft das eine Ende (eth0) in den NET Namespace des Pods. Das andere Ende (veth13ab2) verbleibt im Host-Root-Namespace und wird an eine Linux-Bridge (docker0 oder cbr0).
Eine riesige L2-Sicherheitslücke in rohen Bridges: Pod A kann triviale ARP-Spoofing Pakete an die Bridge schicken ("Ich bin das Gateway-MAC"). Ohne harte iptables / eBPF-Policing im Host zwingt man Netzwerke in Kubenretes massiv in Denial Of Service Zustände, da Namespaces auf L2-Ebene nativ kaum Isolation zur Nachbar-Switch-Schnittstelle besitzen.
3. User Namespaces vs. OverlayFS (Shiftfs Problem)
Bis 2021 hatten User-Namespaces ein fundamentales Produktions-Desaster. Podman warb intensiv für Rootless-Containers (UID 0 innen gemappt auf User 1000 außen).
Aber was passiert, wenn man das Ubuntu-Docker-Image aus dem Internet zieht, dessen Dateien dem User 0 (Root) gehören?
Da der Worker Node als User 1000 läuft, durfte er beim Starten die /bin/bash im Ext4/OverlayFS nicht ausführen ("Permission Denied").
Die Kernel-Lösung nannte sich ursprünglich shiftfs und mündete schlussendlich in Ubuntu/Linux >= 5.12 in ID-mapped mounts. Der Kernel fälscht bei jedem Dateizugriff des Containers auf Festplattenebene die Berechtigungen im VFS-Layer "on-the-fly". Die Festplatte glaubt, UID 1000 fragt an, aber Container-intern antwortet der VFS Layer mit "Datei gehört UID 0". Diese VFS ID-Maps eliminierten das grausame stundenlange "Chownen" von Imagedaten für sichere K8s-Server.
Quick-Check
Sind Namespace Virtualisierung?
Nein. Es ist Isolation. Es wird keine Hardware emuliert. Ein Syscallopen()geht direkt an den Host-Kernel. Deshalb sind Container "Bare Metal" schnell.Was teilt man sich?
Den Kernel! Und (ohne User NS) oft den User. Und Zeit (vor Kernel 5.6). Wenn der Kernel crasht (Panic), sterben alle Namespaces.Zombies im PID Namespace?
Wenn PID 1 im Namespace stirbt, tötet der Kernel alle anderen Prozesse im Namespace (SIGKILL). Ein Namespace ohne PID 1 kann nicht existieren.