LXC vs. Docker

TechDivision setzt inzwischen verstärkt auf LXC

Zwischenzeitlich war die Container-Technologie Docker in aller Munde und jedes IT-Unternehmen, das “en vogue” sein wollte, setzte Docker in irgendeiner Form ein - im Zweifelsfall auch dann, wenn es nicht die Optimallösung war. Natürlich haben auch wir uns über einen längeren Zeitraum intensiv mit Docker beschäftigt und das Tool im Rahmen unserer Projekte verwendet.
Mit der Zeit sind wir allerdings immer häufiger wieder davon abgekommen und haben uns inzwischen komplett von Docker verabschiedet. Dies bedeutet allerdings in keinster Weise, dass wir die Vorteile von Containerlösungen nicht sehen oder verstehen - im Gegenteil. In der täglichen Arbeit bei zum Teil äußerst anspruchsvollen Szenarien haben wir LXC entdeckt und immer mehr schätzen gelernt.

Ein Vergleich der beiden Technologien

Mit der immer weiter zunehmenden Virtualisierung sowie dem Vormarsch verteiler Systeme kommen auch immer häufiger Containertechnologien zum Einsatz. Container stellen dabei keine neue Technologie dar. Die Solaris-Plattform bietet seit vielen Jahren das Konzept der Solaris Zones an, und viele Linux-Administratoren haben mit BSD-Jails eine leichte Alternative zu virtuellen Maschinen geschaffen. Das wachsende Interesse an Docker und LXC (Linux Container) hat zu einem Wiederaufleben der Container als benutzerfreundlichere Lösung geführt.

Wie findet man also die für sich besser geeignete Containerlösung? Dieser Beitrag basiert auf einem Artikel von Robinsystems und versucht das Bewusstsein für die Vor- und Nachteile beider Technologien zu schärfen. Dabei werden die folgenden Kriterien berücksichtigt:

  • Popularität
  • Architektur
  • Speicherverwaltung
  • Client-Tools und Onboarding
  • Bildregistrierung
  • Applikationsunterstützung
  • Hersteller Support & Ökosystem

 

Popularität

Wenn Sie gerade aus einem jahrzehntelangen Dornröschenschlaf aufgewacht sind und Google nach den beliebtesten Technologietrends von 2017 durchsucht haben, brauchen Sie sich nicht wundern, wenn Sie von Websites überflutet werden, die über Docker sprechen. In der Tat, ein Vergleich zwischen Docker und LXC, in Bezug auf die Google-Suchtrends beider Lösungen spricht eine sehr deutliche Sprache

 

Quelle: Google Trends

Um hier jedoch fair zu bleiben sei an dieser Stelle darauf hingewiesen, dass die erste Implementierung von Docker auf Basis von LXC erfolgte und damit Linux-Container für die Massen zugänglich machte. Es wurde versucht, genau wie bei Solaris Zones und BSD Jails, ein leichtes VM-Erlebnis für Systemadministratoren anzubieten. Dennoch lag Dockers Fokus von Anfang an auf den Container-Vorteilen, welche für die Entwicklergemeinde – vor allem auf dem Laptop und über alle Linux-Distributionen hinweg – ermöglicht werden sollten. Um dieses Ziel zu erreichen, hat Docker ab Version 0.9 die Unterstützung für LXC als Standard-Ausführungsumgebung eingestellt und durch eine eigene Implementierung namens libcontainer und schließlich die OCI spezifikationskonforme runc ersetzt. Während es noch diverse andere Container-Alternativen wie rkt, OpenVZ, Cloud Foundry Garden existieren, ist deren Einsatz jedoch eher begrenzt. Docker hat sich mit einer enormen Verbreitung sowie einem umfassenden Ökosystem sowie fortschrittlichen Tools und Einrichtungen, die speziell für diese Lösung entwickelt wurden eine führenden Marktposition erarbeitet.

 

Architektur

Im Kern hängen Docker, LXC und andere Container-Technologien von den wichtigsten Linux-Kernelfunktionen von cgroups und Namespaces ab. An dieser Stelle sei auf einen Vortrag von Jérôme Petazzoni verwiesen, der hier mehr zu diesen Kernel Features erläutert.

Quelle: https://robinsystems.com/blog/containers-deep-dive-lxc-vs-docker-comparison/

Zu Beginn sah die Docker-Architektur ziemlich ähnlich aus wie LXC, da anstelle von liblxc eine eigene Bibliothek namens libcontainer implementiert wurde, die die Ausführungsumgebung über mehrere Linux-Distributionen hinweg bereitstellte. Im Laufe der Zeit wurden jedoch mehrere Abstraktionsschichten hinzugefügt, um dem größeren Open-Source-Ökosystem besser gerecht zu werden und den Industriestandards zu entsprechen. Derzeit sind die beiden wichtigsten Docker-Engine-Komponenten: containerd und runC.

Quelle: https://robinsystems.com/blog/containers-deep-dive-lxc-vs-docker-comparison/

Docker ist jedoch weit mehr als ein Image Format und ein Daemon. Die komplette Docker-Architektur besteht aus den folgenden Komponenten:

  • Docker Daemon: läuft auf einem Host
  • Client: verbindet sich mit dem Daemon und ist die primäre Benutzeroberfläche.
  • Images: schreibgeschütztes Template zur Erstellung von Containern
  • Container: lauffähige Instanz eines Docker Images
  • Registrierung: private oder öffentliche Registrierung von Docker Images
  • Services: ein Scheduling-Service namens Swarm, der eine Multi-Host- und Multi-Container-Bereitstellung ermöglicht. Swarm wurde in der Version 1.12 eingeführt.

Weitere Informationen findet man in der Docker-Dokumentation.

 

Speicherverwaltung LXC vs. Docker

Die LXC-Speicherverwaltung ist recht einfach. Es unterstützt eine Vielzahl von Speicher-Backends wie btrfs, lvm, overlayfs und zfs. Aber standardmäßig (wenn kein Speicher-Backend definiert ist), speichert LXC einfach das Root-Dateisystem unter /var/lib/lxc/[container-name]/rootfs. Für Datenbanken und andere datenintensive Anwendungen können Daten direkt auf die Rootfs geladen oder separate externe Shared Storage-Volumes für die Daten und Rootfs eingebunden werden. Auf diese Weise können die Funktionen eines SAN- oder NAS-Speicherarrays genutzt werden. Um ein Image aus einem LXC-Container zu erstellen, muss nur das Rootfs-Verzeichnis als tar hochgeladen werden.

Quelle: https://robinsystems.com/blog/containers-deep-dive-lxc-vs-docker-comparison/

Andererseits bietet Docker eine raffiniertere Lösung für die Speicherung von Containern und das Management der Images.

Wir beginnen mit der Speicherung eines Image. Ein Docker Image verweist auf eine Liste von schreibgeschützten Ebenen, die Unterschiede im Dateisystem darstellen. Diese Ebenen sind übereinander gestapelt, wie im Bild oben gezeigt, und bilden die Basis des Container-Root-Dateisystems. Der Treiber des Docker Storage stapelt und managed die verschiedenen Schichten. Zudem wird die gemeinsame Nutzung von Ebenen über Images hinweg verwaltet. Das macht das Erstellen, Verschieben und Kopieren von Images schnell und spart Speicherplatz.

Wenn Sie einen Container erzeugen, erhält jeder seine eigene dünne beschreibbare Containerschicht, und alle Änderungen werden in dieser Containerschicht gespeichert, was bedeutet, dass mehrere Container auf das gleiche zugrundeliegende Image zugreifen können und dennoch ihren eigenen Datenzustand haben.

Docker verwendet standardmäßig die Copy-on-Write (CoW)-Technologie sowohl mit Images als auch Containern. Diese CoW-Strategie optimiert sowohl die Nutzung des Image-Plattenplatzes als auch die Performance der Container-Startzeiten.

Beim Löschen eines Containers gehen alle gespeicherten Daten verloren. Für Datenbanken und datenzentrische Anwendungen, die eine persistente Speicherung erfordern, ermöglicht Docker das Einbinden des Dateisystems des Hosts direkt in den Container. Dadurch wird sichergestellt, dass die Daten auch nach dem Löschen des Containers erhalten bleiben und über mehrere Container verteilt werden können. Docker gewährleistet auch die Übernahme von Daten aus externen Speicher-Arrays und Speicherdiensten wie AWS EBS über seine Docker Volume Plug-ins.

Weitere Informationen zur Docker-Speicherung findet man in deren Dokumentation.

 

Client Tools und Onboarding

Wie bereits erwähnt wurde, haben sich BSD jails und LXC auf Systemadministratoren konzentriert, die besonderen Wert auf eine leichtgewichtige Virtualisierungslösung legen. Für einen Systemadministrator ist der Übergang von Hypervisor-basierter Virtualisierung zu LXC also eher ein Klacks. Alles, von der Erstellung der Container-Templates, über die Bereitstellung von Containern, die Konfiguration des Betriebssystems, die Vernetzung, das Einbinden von Storages, die Bereitstellung von Anwendungen usw., bleibt gleich. LXC bietet dabei direkten SSH-Zugriff, d.h. alle Skripte und Automatisierungs-Workflows, die für VMs und physische Server geschrieben wurden, gelten auch für LXC-Container. LXC unterstützt zudem eine Art von Vorlagen, bei denen es sich im Wesentlichen um ein Shell-Skript handelt, das benötigte Pakete installiert und erforderliche Konfigurationsdateien erstellt.

Docker hat sich in erster Linie auf die Entwicklergemeinde konzentriert. Aus diesem Grund hat sie maßgeschneiderte Lösungen und Tools für die Erstellung, Versionierung und Verteilung von Images, die Bereitstellung und Verwaltung von Containern und Paketanwendungen mit all ihren Abhängigkeiten zum jeweiligen Image bereitgestellt. Die 3 wichtigsten Docker-Client-Tools sind:

  • Dockerfile: Eine Textdatei, die alle Befehle enthält, die ein Benutzer auf der Kommandozeile aufrufen kann, um ein Image zu erstellen.
  • Docker CLI: Dies ist die primäre Schnittstelle für die Nutzung aller Docker-Funktionen.
  • Docker Compose: Ein Werkzeug zum Definieren und Ausführen von Multi-Container-Docker-Anwendungen mit einer einfachen YAML-Datei.

Es ist wichtig zu beachten, dass Docker zwar die Benutzerfreundlichkeit durch eine Reihe von benutzerdefinierten Werkzeugen erhöht hat, dies jedoch zu einer steileren Lernkurve führt. Wenn Sie Entwickler sind, sind Sie es gewohnt, VirtualBox, VMware Workstation/Player und Vagrant usw. zu verwenden, um schnell Entwicklungsumgebungen zu erstellen. Andererseits haben die Administratoren eigene Skripte und Automatisierungs-Workflows für die Verwaltung von Test- und Produktionsumgebungen entwickelt. Beide Gruppen haben sich an diese Regelung gewöhnt, da die von der Industrie akzeptierte Norm Entwicklungsumgebung ist nicht gleich Produktionsumgebung bedeutet. Docker stellt das in Frage und versucht, diese beiden Gruppen dazu zu bringen, Standardwerkzeuge und -technologien in der gesamten Produktpipeline einzusetzen. Während Entwickler Docker intuitiv und einfach zu bedienen finden - vor allem aufgrund der Steigerung ihrer Produktivität - sind die IT-Administratoren immer noch dabei, sich auf die Idee überhaupt einzulassen. Sie versuchen also, in einer Welt zu arbeiten, in der Container und VMs nebeneinander existieren. Die Docker-Lernkurve für die IT-Administratoren bleibt steil, da sich ihre bestehenden Skripte ändern müssen. SSH-Zugriff ist dabei standardmäßig nicht verfügbar, Sicherheitsüberlegungen sind neu. Auch mit der neuen Microservices-Architektur werden sie ihre festgelegten Prozesse, die mit den typischen traditionellen 3-Tier-Anwendungen verbunden sind.

 

Registrierung von Images

Eine der Schlüsselkomponenten der Docker-Architektur ist die Registrierung von Images, in der Sie Docker-Images speichern und verteilen können. Docker bietet sowohl eine private Image-Registrierung als auch eine öffentlich gehostete Version dieser Registrierung namens Docker Hub, die für alle Docker-Benutzer zugänglich ist. Außerdem ist der Docker-Client direkt in Docker Hub integriert, so dass der Daemon, wenn Sie `Docker run ubuntu` auf Ihrem Terminal ausführen, im Wesentlichen das erforderliche Docker-Image aus der öffentlichen Registry holt. Wenn Sie gerade erst mit Docker anfangen, ist es am besten, mit Docker Hub zu beginnen und sich dort mit der enormen Anzahl an bereits bestehenden Container-Images ein wenig vertraut zu machen.

Quelle: https://robinsystems.com/blog/containers-deep-dive-lxc-vs-docker-comparison/

Docker Hub wurde im März 2013 gestartet, aber laut Docker Inc. gab es im Oktober 2016 davon bereits mehr als 6 Milliarden Pulls. Neben Docker Hub gibt es viele andere Anbieter, die API-kompatible Docker-Registries anbieten, darunter Quay, AWS, JFrog um nur einige zu nennen.

LXC hingegen verfügt aufgrund seiner relativ einfachen Speicherverwaltung, sowohl im Hinblick auf das Container-Dateisystem als auch auf die Images, über keine speziellen Registries. Die meisten Hersteller, die LXC unterstützen, stellen in der Regel ihre eigenen Mechanismen zur Verfügung, um LXC-Images zu speichern und auf verschiedenen Servern bereitzustellen. Die Webseite Linuxcontainers.org bietet eine Liste von Basis-Images, die mit Hilfe der Community erstellt wurden. Ähnlich wie Docker bietet LXC ein Download-Template, mit dem man nach Images aus der obigen Quelle suchen und dann dynamisch Container erstellen kann. Der Befehl sieht aus wie `sudo lxc-create -t download -n `.

 

Applikationsunterstützung

Der Anwendungsbereich lässt sich grob in moderne, microservicebasierte- und traditionelle Unternehmensanwendungen einteilen.

Microservices-Architektur hat bei Web Unternehmen wie Netflix, Google, Twitter, etc. an Popularität gewonnen. Anwendungen mit einer Microservice-Architektur bestehen aus einer Reihe von eng fokussierten, unabhängig einsetzbaren Diensten, bei denen man auch durchaus mal von einem Ausfall oder Fehlverhalten ausgeht. Der Vorteil: erhöhte Agilität und Belastbarkeit. Agilität, da einzelne Services isoliert aktualisiert und neu bereitgestellt werden können. Aufgrund des verteilten Charakters von Microservices können sie über verschiedene Plattformen und Infrastrukturen hinweg eingesetzt werden, und die Entwickler sind gezwungen, von Grund auf über Ausfallsicherheit nachzudenken.

Microservices-Architektur und Container zusammen erlauben Anwendungen, die schneller zu erstellen und einfacher zu warten sind – bei insgesamt höherer Qualität. Das macht Docker zu einer perfekten Ergänzung. Docker hat seine Containerlösung auf die Microservice-Philosophie ausgerichtet und empfiehlt, dass sich jeder Container mit einem einzigen Anliegen befasst. So können Anwendungen jetzt aus hunderten oder sogar tausenden unterschiedlicher Container bestehen.

Quelle: https://robinsystems.com/blog/containers-deep-dive-lxc-vs-docker-comparison/

Derzeit ist die Microservice-Architektur noch verhältnismäßig neu, und die darauf basierenden Anwendungen sind begrenzt. Ein großer Teil des Unternehmensrechenzentrums wird von den typischen 3-Tier-Anwendungen - Web, App und db - dominiert. Diese Anwendungen sind in Java, Ruby, Python usw. geschrieben, verwenden häufig einzelne Applikationsservern und Datenbanken und erfordern große CPU- und Speicherzuweisungen, da ein Großteil der Komponenten über In-Memory-Funktionsaufrufe kommuniziert. Im Hinblick auf die Verwaltung dieser Anwendungen müssen Administratoren die Anwendungsdienste herunterfahren, Patches und Upgrades anwenden, Konfigurationsänderungen vornehmen und die Dienste anschließend neu starten. All dies setzt voraus, dass Sie die volle Kontrolle über die App haben und den Status ändern können, ohne den Zugriff auf die zugrundeliegende Infrastruktur zu verlieren.

Bei Betrachtung der bestehenden oder traditionellen Enterprise-Anwendungen, scheint LXC eine logische Ergänzung zu sein. Sysadmins können ihre bestehenden Anwendungen, die noch auf physischen Servern oder in VMs laufen, einfach in LXC-Container umwandeln. Während Docker ihre Technologie auch für bestehende Anwendungen promoted, erfordert dies ein erhebliches Engagement und Arbeit, um solche Applikationen zum Laufen zu bringen. Natürlich wird dies zukünftig immer einfacher, da die meisten Hersteller ihre Software inzwischen als Docker-Images zur Verfügung stellen, was den Start neuer Anwendungen erleichtern dürfte.

Wenn Sie von Grund auf neue Anwendungen schreiben, unabhängig davon, ob sie auf Microservices oder 3-Tier-Architekturen basieren ist Docker unterm Strich häufig die bessere Lösung. Aber wenn Sie alle Vorteile von Containern nutzen wollen, ohne die Betriebsabläufe wesentlich zu verändern, dann wird LXC häufig die bessere Option darstellen.

 

Hersteller Support & Ökosystem

Sowohl Docker als auch LXC sind Open-Source-Projekte. Docker wird von Docker Inc. unterstützt, während LXC & LXD (synchronisierter Container-Hypervisor) nun von Canonical, dem Unternehmen hinter Ubuntu OS, unterstützt werden. Während Docker Inc. eine Enterprise-Distribution der Docker-Lösung namens Docker DataCenter anbietet, gibt es viele andere Anbieter, die ebenfalls offizielle Distributionen anbieten. Im Gegensatz dazu gibt es nur sehr wenige LXC-Anbieter. Die meisten unterstützen LXC als zusätzliche Containertechnologie.

Im Gegensatz zu VMs ist das Container-Thema noch recht jung, die Lösungen sind noch unausgereift und besitzen häufig noch Funktionslücken. Dies hat zu einem massiven Wachstum an  Unternehmen geführt, die verschiedenste Lösungen rund um Container anbieten und somit zum Entstehen eines enormen Ökosystems führten. Das folgende Bild zeigt einige der Partner, die das Docker-Ökosystem unterstützen. LXC verfügt nicht über ein so reichhaltiges und engagiertes Ökosystem, aber das liegt in erster Linie an seiner nativen VM-ähnlichen Erfahrung. Die meisten Tools, die auf VMs funktionieren, sollten natürlich auch mit LXC-Containern kompatibel sein.

 

Quelle: https://robinsystems.com/blog/containers-deep-dive-lxc-vs-docker-comparison/

Was die Plattformunterstützung betrifft, wurde Docker inzwischen auch auf Windows portiert. Das bedeutet, dass alle großen Cloud-Anbieter - AWS, Azure, Google und IBM - jetzt native Docker-Unterstützung anbieten. Das ist eine enorme Entwicklung für die Container und zeigt den wachsenden Trend.

 

Zusammenfassung

Wie bei jedem Blogbeitrag dieser Art, der zwei sehr ähnliche Technologien vergleicht, ist die Antwort darauf, welche letztendlich am besten ist, häufig das bereits hinlänglich bekannte “es kommt darauf an”....  Sowohl Docker als auch LXC haben ein enormes Potenzial und bieten dieselben Vorteile in Bezug auf Leistung, Konsolidierung, Bereitstellungsgeschwindigkeit usw.. Da sich Docker aber deutlich stärker auf die Entwicklergemeinde konzentriert, ist seine Popularität in die Höhe geschnellt und wächst weiter. Auf der anderen Seite hat sich LXC nur begrenzt durchgesetzt, scheint aber eine äußerst brauchbare Alternative für bestehende traditionelle Anwendungen zu sein. Auch die VM-Administratoren würden den Übergang zu LXC einfacher finden als zu Docker, müssen aber beide Container-Technologien unterstützen.

Warum wir bei TechDivision inzwischen auf LXC setzen und Docker als nicht mehr so "spannend" empfinden

In der lokalen Entwicklungsumgebung unserer Devs gab es mehrere Gründe wieder auf ein natives Toolset zurück zu greifen. Zum einen ist die Performance mit Docker gerade bei der Entwicklung von Magento2-Projekten auf Grund der Virtualisierung über “xhyve” immer noch stark verbesserungs- würdig, vor allem wenn es darum geht viele Dateien vom Host “macOS” über die Virtualisierung hinweg in die entsprechenden Docker-Container zu linken. Alternativlösungen wie z.B. docker-sync oder auch ein von uns eigens entwickeltes Tool um die Dateien während der Entwicklung mit den Docker Containern zu synchronisieren bringen zwar einen deutlichen Performancegewinn, sind jedoch instabiler und umgehen das Docker eigene Feature um Verzeichnisse und Dateien in Containern zu linken gänzlich. Bereitgestellte Updates von Docker für macOS stabilisierten die Funktionalität nicht wie gewünscht, sondern stellten uns meist vor neuen Herausforderungen. Da unser Fokus stets auf Performance und Effizienz in der Entwicklungsphase von Projekten liegt, setzen wir mittlerweile auf native Entwicklungsumgebungen. Übergangsweise nutzen wir hierzu aktuell Valet+. Valet+ ist OpenSource und auf GitHub (https://github.com/weprovide/valet-plus) erhältlich. Es handelt sich hierbei um einen Fork von Laravel Valet. Es erweitert Valet um Funktionalität mit dem Ziel, die Dinge noch einfacher und schneller zu machen. Wir sind dem Laravel-Team sowie der Firma We Provide sehr dankbar für die Bereitstellung der Basis bzw. des Forks. Aktuell wird in unserer Forschung und Entwicklungsabteilung an einer eigenen, standardisierten Lösung für native Entwicklungsumgebungen auf macOS gearbeitet, die mittelfristig auch Valet+ und das damit verbundene Homebrew komplett ablösen wird.

Auf unseren Linux-basierten CI-Umgebungen war Docker als Container-Lösung zu Beginn grundsätzlich in Ordnung, brachte im Praxiseinsatz über die Zeit aber nicht die gewünschten bzw. erhofften Vorteile, da sich die lokalen Entwicklungssysteme aus den o.g. Gründen nicht in gleicher Form abbilden lassen und somit eine homogene Systemlandschaft während der Entwicklung unmöglich ist. Gerade während der Entwicklung unseres neuen Build- & Deployment Frameworks (BDF) war uns LXC & LXD für diesen Einsatz hinsichtlich Handhabung, Performance, Wartung und Automatisierung in vielen Punkten sympathischer. Bis auf ein paar kleinen Ausnahmen haben wir uns dadurch mittlerweile von Docker komplett verabschiedet und den Wal “zurück in die Freiheit entlassen”…. ;).