In diesem Beitrag stelle ich Ihnen einige der vielversprechendsten Technologien vor, die für die Ausführung von Cloud Nativen Anwendungen [1] in Aussicht stehen. Wenn Sie Container [2] verwenden (oder deren Verwendung in Erwägung ziehen), ist es wichtig, dass Sie diese neuen Technologien verstehen, damit Sie entscheiden können, ob und wann Sie diese einsetzen wollen.
Doch bevor wir in die Zukunft eintauchen, sollten wir zunächst den aktuellen Stand von Containern und einige der Probleme verstehen, mit denen wir derzeit konfrontiert sind.
Virtuelle Maschinen
Cloud Computing wäre nahezu ohne virtuelle Maschinen [3] nicht möglich. Sie sind die grundlegende Computer-Ressource für Cloud Native Anwendungen.
Virtuelle Maschinen ermöglichen es uns, einen ganzen Server zu virtualisieren, was als vollständige Virtualisierung bezeichnet wird. Auf der virtuellen Maschine läuft eine vollständige Kopie des Betriebssystems sowie eine virtuelle Kopie der Hardware. Es wird so viel Hardware simuliert, dass ein Gastbetriebssystem innerhalb der virtuellen Maschine unverändert ausgeführt werden kann. Das Gastbetriebssystem läuft, ohne zu wissen, dass es virtuell ausgeführt wird.
Virtuelle Maschinen werden durch den Hypervisor aktiviert, eine spezielle Software, die direkt auf dem Host-Computer läuft. Der Hypervisor ist für die Verwaltung der physischen Ressourcen des zugrunde liegenden Servers zuständig. Der Hypervisor stellt sicher, dass jede virtuelle Maschine ihre eigenen exklusiven Ressourcen wie CPU und Speicher zugewiesen bekommt.
Dank des Hypervisors ist jede virtuelle Maschine von allen anderen virtuellen Maschinen isoliert. Sie haben jeweils ihr eigenes Gastbetriebssystem sowie ihren eigenen Kernel. Aufgrund dieser starken Abgrenzung bieten virtuelle Maschinen eine hohe Sicherheit und eine starke Isolierung der Arbeitslasten.
Herkömmliche virtuelle Maschinen haben jedoch auch ihre Nachteile. Da sie so konzipiert sind, dass sie jedes beliebige Betriebssystem ohne Änderungen ausführen können, müssen sie eine breite Funktionalität und eine robuste Hardware-Simulation bieten. Folglich sind virtuelle Maschinen aufwendige Lösungen, die erhebliche Rechenressourcen erfordern, was zu einer schlechten Ressourcennutzung führt. Außerdem haben virtuelle Maschinen in der Regel lange Boot-Zeiten, was die Geschwindigkeit, mit der sie erstellt werden können, einschränkt.
Container
Dann kamen Container auf.
Mit Containern können wir nur unsere Anwendungen virtualisieren und nicht den gesamten Server. Das macht Container zu einer idealen Abstraktion für unsere Cloud Nativen Anwendungen.
Für die Virtualisierung greifen Container-Implementierungen auf Funktionen des Betriebssystemkerns zurück, z. B. auf Linux-Namespaces und cgroups (abgekürzt für control groups). Funktional gesehen sind Container einfach Prozesse, die unter dem Host-Betriebssystem laufen. Der Kernel teilt die Ressourcen zwischen diesen Prozessen auf und isoliert sie, indem er sie in separate Namespaces einordnet.
Da Container nicht einen ganzen Server und seine gesamte Hardware virtualisieren, sind Container schneller und weniger ressourcenintensiv als virtuelle Maschinen.
Die höhere Leistung und Ressourceneffizienz von Containern haben jedoch ihren Preis. Da Container auf Kernel-Funktionen angewiesen sind, um Virtualisierung zu ermöglichen, müssen sie sich einen einzigen Betriebssystem-Kernel mit dem Host und allen anderen auf diesem Host laufenden Containern teilen. Diese gemeinsame Nutzung des Kernels macht Container weniger sicher als virtuelle Maschinen.
Das Beste aus beiden Welten
Wie wäre es, wenn wir die Leistung und Ressourceneffizienz von Containern mit der verbesserten Sicherheit und Isolierung von virtuellen Maschinen kombinieren könnten?
Sehen wir uns drei der vielversprechendsten Technologien an, die darauf abzielen, das Beste aus virtuellen Maschinen und Containern zu kombinieren: Micro-VMs, Unikernel und Container-Sandboxen.
Micro-VMs
Micro-VMs sind eine neue Art, virtuelle Maschinen zu betrachten. Anstatt universell einsetzbar zu sein und alle potenziellen Funktionen bereitzustellen, die ein Gastbetriebssystem benötigt, versuchen Micro-VMs, die Probleme der Leistung und Ressourceneffizienz zu lösen, indem sie für bestimmte Anwendungsfälle spezialisiert werden.
Eine Cloud Native Anwendung benötigt beispielsweise nur einige wenige Hardware-Geräte, z.B. für Netze und Speicher. Geräte wie vollständige Tastaturen und Videobildschirme sind nicht erforderlich. Warum sollte die Anwendung also in einer virtuellen Maschine ausgeführt werden, die einen Haufen unnötiger Funktionen bietet?
Durch die Implementierung eines minimalen Umfangs von Funktionen und emulierten Geräten können Micro-VM-Hypervisoren bei geringem Overhead extrem schnell sein. Die Startzeiten können in Millisekunden gemessen werden (im Gegensatz zu Minuten bei herkömmlichen virtuellen Maschinen). Der Speicher-Overhead kann bis zu 5 MB RAM betragen, wodurch es möglich ist, tausende von Micro-VMs auf einem einzigen Bare-Metal-Server auszuführen.
Eine der vielleicht am meisten diskutierten Micro-VMs ist Firecracker. AWS hat Firecracker speziell für die Notwendigkeit entwickelt, serverlose Anwendungen schnell, effizient und mit größtmöglicher Sicherheit auszuführen. Durch die Spezialisierung auf einen bestimmten Anwendungsfall war AWS in der Lage, eine Virtualisierungsumgebung zu schaffen, die perfekt auf die Bedürfnisse von Cloud Nativen Anwendungen zugeschnitten ist.
Ein großer Vorteil von Containern ist, dass sie auf der Anwendungsebene virtualisiert werden und nicht auf der Serverebene wie virtuelle Maschinen. Dies passt natürlich zu unserem Entwicklungslebenszyklus – schließlich erstellen, installieren und betreiben wir Anwendungen, nicht Server.
Container sind eine ausgereifte Technologie, die durch ein reichhaltiges Ökosystem von Werkzeugen und Diensten unterstützt wird, die den gesamten Lebenszyklus von Anwendungen abdecken. Erstellungs-Tools, Verpackungsformate, Laufzeiten und Orchestrierungssysteme ermöglichen es uns, viel effizienter zu arbeiten als mit virtuellen Maschinen.
Eine bessere virtuelle Maschine allein nützt uns nicht viel, wenn wir zur Bereitstellung von Servern zurückkehren und unser reichhaltiges Container-Ökosystem aufgeben müssen. Das Ziel ist es, weiterhin mit Containern zu arbeiten, diese aber innerhalb einer eigenen virtuellen Maschine auszuführen, um das Problem der Sicherheit und Isolierung zu lösen.
Die meisten Micro-VM Projekte bieten einen Mechanismus zur Integration mit den vorhandenen Container-Laufzeiten. Anstatt einen Container direkt zu starten, startet die Micro-VM basierte Laufzeitumgebung zunächst eine Micro-VM und erstellt dann den Container innerhalb dieser Micro-VM. Die Container sind in einer Barriere aus virtuellen Maschinen gekapselt, ohne dass dies Auswirkungen auf die Leistung oder den Overhead hat.
Es ist, als ob wir unseren Kuchen haben und ihn auch essen könnten. Micro-VMs bieten uns die verbesserte Sicherheit und Workload-Isolierung virtueller Maschinen, während die Geschwindigkeit, Ressourceneffizienz und das reichhaltige Ökosystem von Containern erhalten bleiben.
Unikernel
Unikernels [6] zielen darauf ab, einige der gleichen Probleme wie Micro-VMs zu lösen. Wie Micro-VMs ermöglichen Unikernels die Ausführung von Cloud Nativen Anwendungen mit hoher Leistung und geringem Overhead bei gleichzeitiger Gewährleistung eines hohen Sicherheitsniveaus.
Obwohl Unikernels die gleichen Probleme wie Micro-VMs angehen, tun sie dies auf eine grunsätzlich andere Weise.
Ein Unikernel ist ein leichtgewichtiges, unveränderliches Betriebssystem, das speziell für die Ausführung einer einzigen Anwendung kompiliert wurde. Während der Kompilierung wird der Quellcode der Anwendung mit den minimalen Gerätetreibern und Betriebssystembibliotheken kombiniert, die zur Unterstützung der Anwendung erforderlich sind. Das Ergebnis ist ein Maschinenabbild, das ohne ein Host-Betriebssystem ausgeführt werden kann.
Unikernels erreichen ihre Leistungs- und Sicherheitsvorteile, indem sie die Ausführung stark einschränken. Unikernels können nur einen einzigen Prozess haben. Wenn Ihre Anwendung als Unikernel verpackt ist, kann sie keine Sub-Prozesse erzeugen. Da keine anderen Prozesse laufen, gibt es weniger Angriffsfläche für Sicherheitslücken.
Darüber hinaus haben Unikernels ein einziges Adressraummodell ohne Unterscheidung zwischen Anwendungs- und Betriebssystemspeicher. Dies erhöht die Leistung, da kein “Kontextwechsel” zwischen Benutzer- und Kernel-Adressraum erforderlich ist. Beachten Sie, dass bei einem einzigen Adressraum der Kernel nicht vor Anwendungsfehlern geschützt ist. Da der Unikernel aber nur einen einzigen Prozess – die Anwendung – ausführen kann, ist diese Art von Schutz nicht sehr sinnvoll. Wenn die Anwendung stirbt, ist es sinnlos, das Betriebssystem weiterlaufen zu lassen. Es ist besser, den Unikernel einfach neu zu starten.
Einer der großen Nachteile von Unikerneln ist jedoch, dass sie völlig anders implementiert sind als Container. Das umfangreiche Container-Ökosystem ist nicht mit Unikerneln austauschbar. Um Unikernel zu übernehmen, müssen Sie einen völlig neuen Stack wählen, beginnend mit der Auswahl einer Unikernel-Implementierung. Es stehen viele unterschiedliche Unikernel-Plattformen zur Auswahl, die jeweils ihre eigenen Anforderungen und Beschränkungen haben. Um beispielsweise Unikernels mit MirageOS [4] zu erstellen, müssen Sie Ihre Anwendungen in der Programmiersprache OCaml entwickeln.
Interessant ist, dass Docker Unikernel Systems im Januar 2016 übernommen hat. Die Erwartung war, dass dies die vertrauten Werkzeuge und die Portabilität von Docker mit der Effizienz und Spezialisierung von Unikernels kombinieren würde. Leider hat sich das nicht bewahrheitet. Docker hat das Konzept der Unikernel aufgegeben und konzentriert sich weiterhin auf Container.
Container-Sandboxen
Container-Sandboxen wurden entwickelt, um die Sicherheitsprobleme eines gemeinsam genutzten Betriebssystemkerns zu lösen. Sandboxen bieten einen “Kernel-Proxy” [5] für jeden Container. Anstatt dass jeder Container das Host-Betriebssystem direkt anspricht, wird ihm ein eigener Kernel-Proxy zugewiesen. Der Kernel-Proxy implementiert alle Kernel-Funktionen, die vom Container erwartet werden, so dass der Container in der Sandbox ohne jegliche Änderungen laufen kann.
Ein bekanntes Projekt, das Container-Sandboxen implementiert, ist das gVisor-Projekt von Google. gVisor stellt ein Kernel-Proxy-Modul bereit, das in der Sprache Go geschrieben ist und als Vermittler zwischen dem Container und dem Host-Betriebssystem fungiert.
Container-Sandboxen befassen sich speziell mit den Sicherheitsproblemen, die durch die gemeinsame Nutzung des Betriebssystemkerns durch Container entstehen, indem sie eine neue Trennungsebene einführen. Während Sandboxen also eine zusätzliche Isolierung bieten, haben sie einen zusätzlichen Leistungsverlust zur Folge, der durch die Übersetzungen zwischen dem Proxy und dem Kernel entsteht.
Was kommt als Nächstes?
Container-Sandboxen sind ein interessanter Ansatz zur Lösung der Auslastungs-Isolation, bieten aber nicht genügend Vorteile, um einen Wechsel zu rechtfertigen. Mit Blick auf die Zukunft denke ich, dass Micro-VMs und Unikernel die meiste Aufmerksamkeit verdienen.
Wenn Sie Container verwenden, sollten Micro-VMs definitiv auf Ihrem Entwicklungsplan stehen. Micro-VMs lassen sich in bestehende Container-Tools integrieren, was die Einführung recht einfach macht. Wenn Micro-VMs ausgereift sind, werden sie zu einer natürlichen Ergänzung der Laufzeitumgebung und machen Container wesentlich sicherer.
Unikernels hingegen erfordern eine völlig neue Art der Bereitstellung Ihrer Anwendung. Für sehr spezielle Anwendungsfälle können Unikernels die Investition in die Umstellung Ihres Workflows wert sein. Aber für die meisten Anwendungen sind Container, die in einer Micro-VM bereitgestellt werden, die beste Option.
Referenz
- [1] https://glossary.cncf.io/cloud-native-apps
- [2] https://glossary.cncf.io/container
- [3] https://glossary.cncf.io/virtual-machine
- [4] https://mirageos.org
- [5] https://lwn.net/Articles/726811
- [6] https://en.wikipedia.org/wiki/Unikernel
Pierre Gronau ist seit über 25 Jahren für namhafte Unternehmen als Senior IT-Berater mit umfangreicher Projekterfahrung tätig. Zu seinen Kompetenzfeldern gehören Server-Virtualisierungen, IT-Sicherheit, moderne Cloud- und Automationslösungen sowie Informationsschutz.