Cloud-Infrastruktur: Was ist ein Container?


Sie haben bereits von Containern gehört, können sich aber noch wenig darunter vorstellen? Dann hilft dieser Artikel: Darin erklären wir das Konzept und die Eigenschaften von Containern. Das hilft zu verstehen, warum Container einer der grossen Trends in der Cloud-IT sind.

Was ist ein Container?

Das Konzept eines Containers basiert auf dem eines Schiffscontainers. Es handelt sich um eine standardisierte Box, die das enthält, was Sie liefern wollen (=> Ihre Anwendung), aber keine Vorgaben macht, ob der Transport per Luft, See oder Land erfolgt (=> auf welcher Hardware-Plattform die Anwendung laufen soll).

Auf der Ebene des Betriebssystems ist ein Container einfach ein weiterer Prozess auf Ihrem Host-Rechner, der von allen anderen Prozessen isoliert wurde. Diese Isolierung nutzt chroot, Kernel-Namespaces und cgroups. Diese Funktionen gibt es in Linux schon lange, sie wurden aber von Entwicklern nicht wirklich genutzt. Im Jahr 2013 machten sich Docker und Quay daran, diese Funktionen zugänglich und einfach nutzbar zu machen. Das war der Beginn der Container-Revolution aus. 

Im Gegensatz zu einer virtuellen Maschine enthält ein Container keine Hardwaretreiber oder einen Kernel, daher können Betriebsteams die Hardware und das Host-Betriebssystem frei wählen (z. B. Linux, MacOS, MS Windows). Um einen Container zu betreiben, müssen Sie eine Container-Engine wie Docker, CRI-O, Podman oder containerd installieren. Die Open-Source-Engine runC von Docker ist die zugrunde liegende Technologie, die in diesen Container-Engines verwendet wird. CRI-O ist die Engine, die in Kubernetes seit Version 1.18 verwendet wird.

Da wir bei den Containern auf unserer Cloud-Infrastruktur immer Kubernetes nutzen, werde ich noch kurz die so genannten Pods ekklären. Kubernetes führt Container nicht direkt aus, sondern bettet einen oder mehrere Container in eine übergeordnete Struktur ein, die Pod genannt wird. Alle Container im selben Pod teilen sich die gleichen Ressourcen und das lokale Netzwerk. Pods dienen in Kubernetes als Einheit der Replikation.

Abb 1: Die hierarchischen Schichten aus zwei Containern („Container Engine“ und darüber) und der darunter liegenden Hardware. Der Pod ist eine reine Kubernetes-Komponente

Was ist ein Container-Image?

Auf einer höheren Ebene lädt die Container-Engine ein Image herunter und entpackt es in ein isoliertes Laufzeit-Dateisystem-Bundle, das sie in das zugrunde liegende Dateisystem mountet. Das Bundle muss alles enthalten, was zur Ausführung einer Anwendung benötigt wird, einschliesslich aller Abhängigkeiten, Konfigurationen, Skripte und Binärdateien. Das Image enthält auch andere Konfigurationen für den Container, wie z. B. Umgebungsvariablen, einen auszuführenden Standardbefehl und andere Metadaten. Images sind schreibgeschützt und unveränderlich, daher muss die Container-Engine eine Thin-Read/Write-Fähigkeit, wie COW (Copy On Write), bereitstellen, um alle Dateisystemänderungen zu speichern. Alle Änderungen, die am laufenden Container vorgenommen werden, wie das Schreiben neuer Dateien, das Ändern bestehender Dateien und das Löschen von Dateien, werden in diese Container-Schicht geschrieben.

Container & Kubernetes in der Safe Swiss Cloud

Erfahren Sie mehr, was Sie mit Kubernetes/OpenShift distribution in der Safe Swiss Cloud erreichen können.

Was macht ein Image aus?

Laut Wikipedia ist ein Image eine serialisierte Kopie des gesamten Zustands eines Computersystems, die in einer nichtflüchtigen Form gespeichert ist (einer Datei). 

Ein System ist dann in der Lage, diese Abbilder (Images) zu verwenden, wenn es heruntergefahren und später in genau demselben Zustand wiederhergestellt werden kann. Ein Container-Image ist kaum anders. Heute sind fast alle wichtigen Tools und Engines auf das OCI-Image-Format (Open Container Initiative) umgestiegen, das die Layer und Metadaten innerhalb eines Container-Images definiert. 

OCI definiert ein Container-Image, das aus tar-Dateien für jede Schicht und einer manifest.json-Datei mit den Metadaten besteht. Image-Ebenen sind in einer Eltern-Kind-Beziehung miteinander verbunden. Jede Image-Ebene repräsentiert Änderungen zwischen sich selbst und der übergeordneten Ebene.

Jede Ebene hat ein Tag und einen Universally Unique Identifier (UUID). Wenn Sie ein Image z. B. mit einer Dockerdatei erstellen (siehe nächster Abschnitt), wird mit jeder Direktive in der Datei eine neue Ebene erstellt. 

Abb 2: Die Pod-, Container- und Image-Hierarchie mit einer hypothetischen Webapp als Image. Schicht 1 ist das übergeordnete Image.

Wie erstellt man ein Container-Image?

Sie können Ihr eigenes Image erstellen oder ein fertiges von einem der vielen öffentlichen Registrys wie docker.io oder quay.io beziehen. Es kann auch von einer privaten Registry wie der in OpenShift enthaltenen oder von Ihrem eigenen Computer stammen. Um Ihr eigenes Image zu erstellen, können Sie Tools wie Docker, Buildah, Podman, Kaniko oder OCIBuilder verwenden. Alle Images werden aus einem vorgefertigten Eltern-Image oder einem selbst erstellten Basis-Image erstellt, das oft ein kleines, leichtgewichtiges Betriebssystem wie Alpine enthält, das nur 5 MB gross sein kann. 

Die Anweisungen, wie das Image zu bauen ist, werden z. B. in einer Dockerdatei definiert. Images, wie sie mit OpenShift ausgeliefert werden, gibt es als „Builder-Images“ für gängige Programmiersprachen wie Golang, Python und Java sowie für Frameworks wie .NET. Image-Versionen werden mit Tags wie z. B. „latest“ oder „version1.0“ versehen und in Image-Repositories abgelegt. Eine Sammlung von Image-Repositories wird als Image-Registry bezeichnet. 


Weiterführende Links:

Container & Kubernetes in der Safe Swiss Cloud

Erfahren Sie mehr, was Sie mit Kubernetes/OpenShift distribution in der Safe Swiss Cloud erreichen können.

Schreiben Sie einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

Hinweis:
Sie können beim Kommentieren folgende HTML Tags und Attribute verwenden: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>