Ein Container ist eine standardisierte, isolierte Laufzeitumgebung, die es ermöglicht, Anwendungen und ihre Abhängigkeiten in einer konsistenten und tragbaren Weise auszuführen. Container verwenden das Betriebssystem des Host-Systems, teilen jedoch Ressourcen wie den Kernel und andere Systembibliotheken nicht direkt. Dadurch sind sie leichtgewichtig und ermöglichen eine effiziente Nutzung von Ressourcen im Vergleich zu herkömmlichen virtuellen Maschinen.
Container werden oft verwendet, um Anwendungen in einer Umgebung auszuführen, die von ihrer Entwicklungsumgebung isoliert ist. Dadurch können Entwickler sicherstellen, dass ihre Anwendungen unabhängig von der zugrunde liegenden Infrastruktur konsistent funktionieren.
Docker ist eine der bekanntesten Container-Plattformen, aber es gibt auch andere wie Kubernetes, containerd und Podman. Diese Plattformen bieten Tools und APIs für das Erstellen, Verwalten und Orchestrieren von Containern in großen verteilten Systemen.
Container haben viele Vorteile, darunter:
Portabilität: Container sind tragbar und können auf verschiedenen Plattformen und in verschiedenen Umgebungen ausgeführt werden, solange der Container-Runtime installiert ist.
Konsistenz: Da Container ihre Umgebung kapseln, sind sie konsistent und verhalten sich gleich, unabhängig von der Umgebung, in der sie ausgeführt werden.
Ressourceneffizienz: Container teilen Ressourcen wie den Kernel des Host-Betriebssystems, was zu einer effizienten Nutzung von Speicher und Rechenleistung führt.
Skalierbarkeit: Container können leicht skaliert werden, indem mehr Instanzen gestartet werden, um die Last zu bewältigen, und bei Bedarf automatisch auf- und abgebaut werden. Insgesamt bieten Container eine moderne und flexible Möglichkeit, Anwendungen zu entwickeln, zu bereitstellen und zu betreiben.
Ein Namespace ist ein Mechanismus, der es ermöglicht, dass ein Prozess eine isolierte Sicht auf bestimmte Ressourcen hat. Ein häufig verwendetes Beispiel ist der Netzwerknamespace, der es Prozessen erlaubt, ihr eigenes Netzwerk zu haben, das von anderen Prozessen isoliert ist. Beispiel:
unshare -n bash . Mit diesem Befehl starten wir eine neue Bash-Shell in einem eigenen Netzwerknamespace. Diese Shell hat ihr eigenes Netzwerkinterface und IP-Adresse, isoliert von anderen Prozessen.
Der Mount-Namespace ermöglicht es einem Prozess, sein eigenes Dateisystem zu haben, das von anderen Prozessen isoliert ist. Das ist nützlich für Container, die ihr eigenes Dateisystem benötigen. Beispiel:
unshare -m bash
Mit diesem Befehl starten wir eine neue Bash-Shell in einem eigenen Mount-Namespace. Diese Shell hat ein eigenes Dateisystem, das unabhängig von anderen Prozessen ist.
Der PID-Namespace isoliert die Prozess-IDs, so dass ein Prozess in einem separaten Namensraum seine eigene PID 1 haben kann, ohne die PIDs der anderen Prozesse im System zu beeinflussen.
Beispiel: unshare -p bash
Mit diesem Befehl starten wir eine neue Bash-Shell in einem eigenen PID-Namespace. Diese Shell hat ihre eigene PID 1 und alle anderen Prozesse in ihrem Namensraum haben PIDs, die relativ zu dieser PID 1 sind.
Die Prozessisolierung ist ein entscheidender Aspekt von Containern. Sie ermöglicht es, dass Prozesse innerhalb eines Containers unabhängig voneinander agieren, ohne dass sie die Ressourcen oder den Zustand anderer Prozesse beeinträchtigen können. Der “unshare” Befehl trägt dazu bei, diese Prozessisolierung zu erreichen, indem er verschiedene Namespaces isoliert, wie den PID-Namespace, der sicherstellt, dass Prozesse innerhalb des Containers ihre eigenen Prozess-IDs haben, und den Mount-Namespace, der ein separates Dateisystem für den Container bereitstellt.
Beispiel:
unshare -p -m bash
Mit diesem Befehl starten wir eine neue Bash-Shell in einem eigenen PID- und Mount-Namespace. Dadurch wird der Prozess isoliert und hat seine eigenen Prozess-IDs und sein eigenes Dateisystem, unabhängig von anderen Prozessen im System.