Microservices sind das Gebot der Stunde in IT-Unternehmen. In der Anwendungsentwicklung geht der Trend seit einigen Jahren weg von monolithischen Strukturen (IT-Systeme, die nicht in verschiedene Teilsysteme gegliedert sind) hin zu einem reduktionistischen Ansatz. Das heißt, Anwendungen werden in Kleinteile zerlegt. Die Vorteile liegen auf der Hand: In einzelne Einheiten aufgespaltene Prozesse lassen sich flexibler bearbeiten und schneller ausrollen als groß angelegte, komplexe Systeme.
Im Gegensatz zu solch umfassenden Ansätzen erfordert die Arbeit mit separaten Microservices allerdings einen deutlich erhöhten Konfigurations- und Überwachungsaufwand. Containerlösungen wie die Open-Source-Technologie Docker schaffen Abhilfe. Docker verpackt und isoliert einzelne Prozesse und macht sie dadurch deutlich handlicher und leichter automatisierbar.
Technologien wie Docker kommen vor allem bei der Bereitstellung von Cloud- und Hybrid-IT-Lösungen zum Einsatz. Die Anwendungen sind dabei vielfältig. So hat beispielsweise der Online-Verkäufer eDreams ODIEGO seit Ende 2020 sämtliche Server mithilfe von Docker und Kubernetes in die Cloud verlagert. Auch in deutschen Behörden sind Container bereits angekommen.
Das Informationstechnikzentrum Bund (ITZBund) verwendet Containertechnologie zur Bereitstellung digitaler Verwaltungsleistungen in einem Verbund aller Verwaltungsportale in Deutschland sowie zur Einrichtung der Bundescloud. Aber auch außerhalb von Cloud-nativen Lösungen findet Docker zum Beispiel Anwendung in No-Code-Plattformen. Und auch viele der größten Cloud-Hosts setzen Docker ein: Cisco, Avanade, Microsoft und Hewlett-Packard Enterprise (HPE) arbeiten offiziell mit Docker zusammen.
Wie funktioniert Docker?
Docker isoliert ausführbare Prozesse oder Anwendungen. Die Prozesse sind sowohl vom Host-System als auch von anderen Prozessen abgekapselt. Ist ein Docker-Container also im Grunde dasselbe wie eine Virtuelle Maschine (Virtual Machine, VM)?
Unter einer VM versteht man ein rein auf Software basierendes - also virtuelles - Computersystem, das auf einem realen Computersystem läuft, davon aber abgekapselt ist. Der Vorteil: Riskante Operationen wie die Arbeit in potenziell virenbelasteten Umgebungen können nur die VM, nicht aber den realen Rechner infizieren. VM werden auch eingesetzt, um auf einem realen System mehrere virtuelle Server laufen zu lassen, die alle voneinander getrennt sind. Die Vorteile hier: höhere Flexibilität, niedrigere Betriebskosten, geringere Serverkomplexität und in der Regel eine schnellere Bereitstellung der Kapazitäten.
Bei virtuellen Maschinen läuft ein Prozess in einem emulierten Gast-Betriebssystem (zum Beispiel Linux), das isoliert auf der Hardware des Host-Systems läuft. Der sogenannte Hypervisor vermittelt zwischen der Hardware, dem Host-Betriebssystem (Operating System, OS) und allen virtuellen Gast-Betriebssystemen. Er kann virtuelle, von der Hardware abgekapselte Umgebungen definieren. Dieser Prozess heißt Abstrahierung. Die VM besteht aus dem installierten OS und den Anwendungen und greift über die vom Hypervisor abstrahierten Schnittstellen auf die Hardware zu. Die Hardware ist dadurch beliebig veränderbar. Die Änderungen müssen nur im Hypervisor angepasst werden, nicht in der VM selbst. Virtuelle Maschinen arbeiten also mit Virtualisierung auf Hardware-Ebene und greifen nur indirekt über den Hypervisor auf die physikalische Hardware zu.
Virtuelle Maschinen isolieren komplette Maschinen. Sollen die Ressourcen eines Servers aufgeteilt werden, um beispielsweise die Performance des Arbeitsspeichers zu optimieren, werden mithilfe des Hypervisors verschiedene VM angelegt. Der Server wird sozusagen virtuell in mehrere separate Server aufgeteilt. Die einzelnen VM sind prinzipiell unabhängig voneinander.
Bei Containern sieht das anders aus: Ein Container ist eine Art Framework für die Kapselung von Software-Anwendungen und Prozessen. Der Container enthält alles, was für den Ablauf einer spezifischen Anwendung oder eines spezifischen Prozesses benötigt wird, zum Beispiel Code, Laufzeitmodul, Systemwerkzeuge und Systembibliotheken - und kann diese abgeschirmt von anderen Prozessen, Anwendungen oder Systemumgebungen ausführen. Ein Container ist letztendlich eine Sammlung von ausführbarem Code, der mithilfe des Kernels des Hostsystems vollkommen unabhängig als Mikroprogramm gestartet werden kann. Docker ist ein Instrument, das Software in solche Container verpacken kann.
Eine VM simuliert immer ein komplettes virtuelles System inklusive OS. Ein Container hingegen nutzt das OS des Host-Systems gemeinsam mit allen anderen Containern, die darauf laufen. Die im Container abgekapselte Software greift dazu auf die Docker Engine zu, die wiederum auf das Betriebssystem zugreift. Die Vorteile: Docker ermöglicht die schnelle Bereitstellung von Anwendungen, deren einfache Skalierung und einen verbesserten Service durch die Segmentierung komplexer Anwendungen in Microservices. Software Releases umfassen dann nicht mehr ein Rollout der kompletten Software, sondern nur noch den Rollout der jeweiligen Container - und dies zumeist im laufenden Betrieb, ohne dass Anwender den Austausch überhaupt wahrnehmen.
Der containerbasierte Ansatz isoliert Prozesse. Normalerweise laufen unterschiedliche Anwendungen in derselben Systemumgebung. Die Anwendungen "wissen" voneinander, sie können miteinander kommunizieren und nutzen dieselben Ressourcen - ähnlich der Arbeit in einem Großraumbüro. Eine Containerlösung dagegen sorgt dafür, dass Anwendungen nur genau das sehen können, was unmittelbar zum Ausführen der jeweils spezifischen Anwendung benötigt wird. Um in der Metapher zu bleiben: Alle Mitarbeitenden im Großraumbüro bekommen eine eigene Bürozelle, die all das enthält, was sie zum Verrichten ihrer Arbeit brauchen. Das heißt: Container teilen sich zwar ein Betriebssystem und einen Kernel (den Büroraum), sie "wissen" aber nichts voneinander und verhalten sich so, als hätten sie ihr jeweils eigenes Betriebssystem.
Die Vorteile von Docker-Containern
Containerlösungen wie Docker revolutionieren VM und machen das VM-Prinzip leichtgewichtig, automatisierbar und standardisierbar, indem sie die Isolation einzelner Prozesse (Container) der Isolation von Maschinen (VM) gegenüberstellen.
Während VM immer ein Gastsystem inklusive Kernel benötigen, fällt dieser Kern bei Docker-Containern weg. Dadurch werden die Prozesse deutlich kleiner, da sie nicht jedes Mal ein virtuelles Betriebssystem mitliefern müssen. Das spart wertvolle Ressourcen: Arbeits- und Festplattenspeicher. So können bei gleichbleibender Hardware wesentlich mehr Prozesse nebeneinander ablaufen - das System ist leicht skalierbar. Gleichzeitig verringert sich die zum Starten der Prozesse erforderliche Zeit erheblich.
Docker wurde ursprünglich für Linux entwickelt, ist mittlerweile in der Docker Desktop Version 3.5 aber auch für Windows und iOS verfügbar.
Container, Images und Daemons: Woraus besteht Docker?
Wie genau funktioniert die Erstellung eines Containers? Und wie bringt Docker diesen zum Laufen?
Bevor die Docker-Software die Bürozelle aus dem vorherigen Beispiel bauen kann, muss sie wissen, wie eine Bürozelle überhaupt aussieht. Das Programm braucht sozusagen eine Blaupause, der es entnehmen kann, dass die Zelle vier Wände hat, und dass ein PC, ein Telefon und ein Bürostuhl darin stehen müssen. In der Docker-Terminologie heißt diese Blaupause Image.
Images sind eine Art portabler, speicherbarer und prinzipiell schreibgeschützter Bauplan eines Containers. Das Image enthält alle Dateien, die für den Ablauf eines containerisierten Prozesses nötig sind, sowie alle Metadaten, die der Kernel zur Erstellung der Systemumgebung braucht. Auf der Grundlage der Blaupause lassen sich dann unzählig viele identische Bürozellen herstellen, sodass alle Angestellten darin ihre Arbeit verrichten können. Docker Inc. bietet in dem Web-Registry DockerHub (hub.docker.com) eine Menge voreingestellter Images an, die einfach heruntergeladen und in der Docker-Engine konfiguriert gestartet werden können - und das in einem Bruchteil der Zeit, die VM zum Start eines Prozesses brauchen würden.
Einer der größten Vorteile des Docker-Image-Modells ist die aktive Community. Hier spielt Docker seinen Vorteil als Open-Source-Plattform voll aus, denn jeder beliebige Nutzer kann - solange er über entsprechende Programmierkenntnisse verfügt - Images erstellen, spezifisch vorkonfigurieren und sie frei verfügbar machen. Das verringert selbst dann den Programmieraufwand, wenn keines der verfügbaren Images zu 100 Prozent zum gewünschten Anwendungsfall passt.
Denn Images können auch aufeinander aufbauen. Das bedeutet, dass auf der Grundlage eines vorkonfigurierten Images ein neues, maßgeschneidertes Image erstellt werden kann. Docker erzeugt daraus einen Container, der exakt den benötigten Prozess ausführt. Das macht Docker zur idealen Plattform für Software-Tests, denn schnelle Experimente mit verschiedenen Images erfordern so weder Vorbereitungs- noch Zeitaufwand.
Die Docker-Engine ermöglicht das Ausführen von Container-Images. Nachdem ein Image heruntergeladen wurde, kann es konfiguriert ausgeführt werden. Die Docker-Engine ist sozusagen der Abteilungsleiter, der die Aufstellung der einzelnen Zellen im Großraumbüro anordnet und den Mitarbeitenden ihre Aufgaben zuteilt.
Weil ein Container von der Systemumgebung isoliert ist, braucht es eine Schnittstelle, über die der containerisierte Prozess mit den restlichen Systemfunktionen kommunizieren kann. Diese Schnittstelle zwischen Container und Systemfunktionen ist der libcontainer. Der Ablauf der Prozesse wird von der runtime-Anwendung containerd geregelt.
Containerd ist ein sogenannter Docker Daemon, also eine Software, die eine konkrete Aufgabe erfüllt, meistens im Hintergrund und ohne direkten Userkontakt. Der Daemon ist der Praktikant, der von Zelle zu Zelle läuft und die Anliegen der Mitarbeitenden notiert: Ein Programm sendet eine Anforderung (zum Beispiel "save"), der Daemon hört diese Anforderung, schreibt mit (verarbeitet die Anforderung so, dass der Kernel sie verstehen kann), rennt damit zum Kernel und bittet ihn darum, diese Anforderung auszuführen (also etwa auf die Festplatte zuzugreifen).
Docker-Container sind leichtgewichtig und flexibel einsetzbar. Sie ermöglichen so die Integration von Anwendungen in unterschiedliche Umgebungen. Die Unabhängigkeit von Systemumgebungen ist der größte Vorteil einer Containerlösung: Eine containerbasierte Anwendung läuft in jedem System exakt gleich ab.
Schädlingsbekämpfung leicht gemacht
Sobald das Entwicklerteam einen containerisierten Prozess anpassen oder aktualisieren muss, greift es nicht auf den Container selbst, sondern auf das Container-Image zurück. Das Team stellt dann ein aktualisiertes Image zur Verfügung, aus dem die Docker-Engine einen aktualisierten Container generiert. Das hat den großen Vorteil, dass für Fehlerbehebungen statt der kompletten Anwendung nur der fehlerhafte Baustein außer Betrieb genommen werden muss. Das IT-Team muss nicht lange nach dem Bug suchen, sondern kann den fehlerhaften Prozess sofort identifizieren.
Der Container kann dann abgeschaltet werden, woraufhin aus einem aktualisierten Image ein neuer, bereinigter Container zur Verfügung gestellt wird. Weil aus Docker-Images immer auch ihre Versionshistorie erkennbar ist, ist ein Rollback problemlos durchführbar. Wird der Reparaturprozess mit Hilfe eines Orchestrators, wie beispielsweise Kubernetes, automatisiert, merken Anwender unter Umständen nicht einmal, dass ein Fehler vorliegt: Ein fehlerhafter Prozess kann automatisch aktualisiert werden, ohne dass dies signifikante Auswirkungen auf den Rest der Anwendung hat - und ohne Zutun der Anwender. Selbes gilt für Updates: Um einen Prozess anzupassen, muss nur das entsprechende Image aktualisiert werden, aus dem dann beliebig viele angepasste Container entstehen.
Automatisierte Containertechnologie ermöglicht die Bereitstellung selbstheilender, hochverfügbarer Systeme. Diese können selbstständig auf Fehler reagieren, indem sie einen automatischen Rollback zur letzten funktionierenden Version der Anwendung ausführen und diese selbstständig starten.
Erhöhte Performance, Skalierbarkeit und agile Serverlandschaft
Das Ausführen isolierter Prozesse benötigt signifikant weniger Zeit als das Ausführen von Prozessen in einer virtuellen Maschine, weil konfigurierte Images einfach aus dem Web-Registry DockerHub bezogen und in der Docker-Engine gestartet werden können. Gleichzeitig erfordert der Einsatz vorkonfigurierter Container-Images praktisch keinen Aufwand. Da Images keinen Kernel und kein OS mitliefern müssen, sind sie auch deutlich kompakter als virtuelle Maschinen.
Durch die daraus resultierende Einsparung von Rechen- und Festplattenspeicher können auf identischer Hardware im Vergleich zum Einsatz virtueller Maschinen deutlich mehr Containerprozesse parallel ausgeführt werden, wodurch die Performance ansteigt. Gleichzeitig wird das System so flexibler: Auf System- oder Abhängigkeitsänderungen kann sofort reagiert werden, indem das entsprechende Docker-Image angepasst wird. Selbst wenn Docker in einer VM verwendet wird, ist dieses System flexibler und effizienter als das parallele Aufsetzen mehrere VM.
Aus einem Image lassen sich beliebig viele Container erstellen, die parallel bearbeitet werden können und dabei deutlich weniger Platz wegnehmen als eine vergleichbare Anzahl von Instanzen bei virtuellen Maschinen. Containerlösungen sind also leicht skalierbar, was sie ideal für die Bereitstellung von cloud-nativen Anwendungen macht - und das sogar mit deutlicher Kosteneinsparung, weil im Vergleich zu virtuellen Maschinen weniger Infrastruktur gebraucht wird.
Docker-Container sparen Kosten
Docker bietet sich als Grundlage für die moderne und flexible Anwendungsentwicklung an. Container enthalten alle Abhängigkeiten, die für den Ablauf eines Prozesses nötig sind. Deshalb laufen sie problemlos in jeder beliebigen Systemumgebung. Die Standardisierung von Systemumgebungen vermeidet Konflikte und beschleunigt die Bereitstellung von Anwendungen. Gleichzeitig sind Container deutlich leichtgewichtiger als VM, weil sie weder ein OS noch einen Kernel liefern müssen und so verfügbaren Speicherplatz effektiver ausnutzen können. Und kommt es doch einmal zu Problemen, müssen Prozesse nicht aufwendig repariert oder aktualisiert werden, sondern lassen sich durch Anpassung des Images einfach neu ausrollen. So können Unternehmen Kosten sparen und verfügbare Ressourcen optimal ausnutzen.