Docker: Isolation mit Kernel Namespaces und Control Groups

Bevor wir in die technischen Details eintauchen, lass uns kurz klären, was unter „Isolation“ in Docker verstanden wird. Container sind leichtgewichtige, eigenständige Einheiten, in denen Anwendungen mit all ihren Abhängigkeiten ausgeführt werden. Diese Container sind voneinander isoliert, was bedeutet, dass sie nicht auf die Ressourcen oder Prozesse anderer Container oder des Hosts zugreifen können. Diese Isolation ist entscheidend für die Sicherheit und Stabilität in einer Container-basierten Infrastruktur.

Docker erreicht diese Isolation durch die Kombination von Kernel Namespaces und Control Groups (cgroups), beides Funktionen des Linux-Kernels.


Kernel Namespaces: Isolierung von Systemressourcen

Namespaces sind ein Feature im Linux-Kernel, das es ermöglicht, Systemressourcen wie Prozesse, Netzwerkinterfaces und Dateisysteme voneinander zu isolieren. Docker verwendet verschiedene Arten von Namespaces, um sicherzustellen, dass Container voneinander und vom Host-System isoliert bleiben. Hier sind die wichtigsten Namespaces, die Docker verwendet:

1. PID Namespace (Prozess-ID)

Der PID-Namespace sorgt dafür, dass jeder Container seine eigene Ansicht auf die Prozess-ID-Liste (also die laufenden Prozesse) hat. Prozesse in einem Container haben keinen Zugriff auf Prozesse in einem anderen Container oder auf dem Host. Jeder Container sieht also nur seine eigenen Prozesse.

  • Vorteil: Container können keine Prozesse des Hosts manipulieren oder beenden.

Beispiel: Wenn du in einem Container ps aux ausführst, siehst du nur die Prozesse, die in diesem Container laufen, nicht die des Hosts oder anderer Container.

2. Netzwerk-Namespace

Der Netzwerk-Namespace sorgt dafür, dass jeder Container seine eigene Netzwerkschnittstelle hat. Container haben dadurch eigene IP-Adressen und können nicht direkt auf die Netzwerkschnittstellen des Hosts oder anderer Container zugreifen.

  • Vorteil: Die Netzwerke der Container sind vollständig voneinander getrennt. Kommunikation zwischen Containern findet nur statt, wenn explizit Verbindungen hergestellt werden.

Docker erstellt für jeden Container einen eigenen Netzwerk-Namespace und bindet ihn an virtuelle Netzwerkschnittstellen, sogenannte veth-Paare, die mit dem Host kommunizieren.

3. Mount Namespace

Der Mount-Namespace isoliert das Dateisystem eines Containers vom Host und anderen Containern. Jeder Container hat seine eigene Ansicht auf das Dateisystem, und Änderungen in einem Container wirken sich nicht auf andere Container oder das Host-Dateisystem aus (außer, du verwendest Volumes oder Bind-Mounts).

  • Vorteil: Container können nur auf die Dateien und Verzeichnisse zugreifen, die ihnen explizit zugewiesen wurden.

4. User Namespace

Der User-Namespace ermöglicht es, dass Benutzer und Gruppen innerhalb eines Containers isoliert sind. Ein Container kann beispielsweise als root-Benutzer innerhalb des Containers laufen, ohne tatsächlich root-Rechte auf dem Host zu haben. Dadurch wird das Risiko minimiert, dass ein Angreifer bei einem erfolgreichen Angriff auf den Container auch Zugriff auf den Host erhält.

  • Vorteil: Erhöhte Sicherheit, da Container-Benutzer keine Rechte auf dem Host haben.

5. UTS Namespace (UNIX Time-Sharing)

Dieser Namespace ermöglicht es Containern, eigene Hostnamen und Domänennamen zu haben. Container können ihre eigenen Namen verwenden, ohne den Hostnamen des physischen Systems zu ändern.

  • Vorteil: Container können in einem Cluster oder Netzwerk unabhängig benannt werden, ohne Konflikte mit dem Hostnamen.

6. IPC Namespace (Interprozesskommunikation)

Der IPC-Namespace isoliert die Interprozesskommunikationsmechanismen, wie z.B. Shared Memory, zwischen Containern. Das verhindert, dass Container über diese Mechanismen miteinander kommunizieren oder die Kommunikation des Hosts beeinflussen.

  • Vorteil: Container sind isoliert und können keine sensiblen Daten aus anderen Containern oder dem Host lesen.

Control Groups (cgroups): Ressourcenverwaltung

Während Namespaces für die Isolation der Sichtbarkeit und des Zugriffs auf Systemressourcen zuständig sind, kommen Control Groups (cgroups) ins Spiel, wenn es darum geht, wie viele Systemressourcen (CPU, Speicher, Netzwerkbandbreite etc.) einem Container zugewiesen werden. Cgroups ermöglichen die Verwaltung und Begrenzung von Ressourcen, die ein Container nutzen darf.

1. CPU-Ressourcenverwaltung

Mit cgroups kannst du die CPU-Zeit einschränken, die ein Container nutzen darf. Du kannst Prioritäten für Container festlegen und verhindern, dass ein einzelner Container die gesamte CPU-Zeit aufbraucht.

Beispiel:

docker run --cpus="1.5" my_container

Dieser Befehl beschränkt den Container auf 1,5 CPUs. Wenn du viele Container auf einem Host betreibst, hilft diese Begrenzung, Überlastungen zu vermeiden.

2. Speicherverwaltung

Mit cgroups kannst du den Speicherverbrauch von Containern einschränken, um zu verhindern, dass ein Container den gesamten Speicher des Hosts beansprucht.

Beispiel:

docker run --memory="512m" my_container

Dieser Befehl beschränkt den Container auf 512 MB RAM. Wenn ein Container versucht, mehr Speicher zu verwenden, wird der Prozess beendet oder in den Swap-Speicher ausgelagert.

3. Block-I/O Verwaltung

Mit cgroups kannst du die Input/Output (I/O) Operationen von Containern begrenzen, um zu verhindern, dass ein Container die Festplatten- oder Netzwerkbandbreite des Hosts monopolisiert.

Beispiel:

docker run --blkio-weight="500" my_container

Dieser Befehl weist dem Container eine I/O-Gewichtung von 500 zu, wodurch seine I/O-Operationen gegenüber anderen Containern priorisiert oder eingeschränkt werden können.

4. Netzwerkbandbreitenbegrenzung

Cgroups ermöglichen es auch, die Netzwerkbandbreite eines Containers zu begrenzen. Dies ist besonders nützlich, um zu verhindern, dass Container das Netzwerk überlasten.

Beispiel:

tc qdisc add dev eth0 root tbf rate 1mbit burst 10kb latency 50ms

Dieser Befehl setzt eine Netzwerkbandbreitengrenze von 1 Mbit/s für den Container.


Zusammenspiel von Namespaces und cgroups

Docker nutzt sowohl Namespaces als auch cgroups, um Container zu isolieren und zu verwalten. Namespaces sorgen dafür, dass Container von den Ressourcen anderer Container und des Hosts isoliert sind, während cgroups sicherstellen, dass jeder Container nur eine begrenzte Menge an Ressourcen verbrauchen kann.

Zusammen bieten diese beiden Technologien eine leistungsstarke Grundlage für die Erstellung sicherer und effizienter Containerumgebungen.


Fazit

Kernel Namespaces und Control Groups sind die beiden zentralen Technologien, die Docker verwendet, um Container zu isolieren und die Ressourcennutzung zu steuern. Sie sorgen dafür, dass Container unabhängig voneinander und sicher arbeiten können, während sie gleichzeitig effizient mit den verfügbaren Ressourcen umgehen.

Indem du dir ein gutes Verständnis von diesen Technologien aneignest und Best Practices befolgst, kannst du deine Container-Umgebung sicherer und leistungsfähiger gestalten.

Docker vereinfacht zwar die Nutzung dieser Technologien, aber es ist dennoch wichtig zu verstehen, wie sie im Hintergrund arbeiten, um Container sicher und effizient betreiben zu können.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert