Das Docker-Ökosystem: Ein Überblick über die Containerisierung

Einführung

Es gibt oft viele Hürden, die verhindern, dass Ihre Anwendung leicht durch den Entwicklungszyklus und schließlich in die Produktion verschoben werden kann. Neben der eigentlichen Arbeit bei der Entwicklung Ihrer Anwendung, um in jeder Umgebung angemessen zu reagieren, können auch Probleme beim Aufspüren von Abhängigkeiten, beim Skalieren Ihrer Anwendung und beim Aktualisieren einzelner Komponenten auftreten, ohne die gesamte Anwendung zu beeinträchtigen.

Docker-Containerisierung und serviceorientiertes Design versuchen, viele dieser Probleme zu lösen. Anwendungen lassen sich in verwaltbare, funktionale Komponenten aufteilen, mit all ihren Abhängigkeiten einzeln verpacken und auf einfache Weise in einer unregelmäßigen Architektur implementieren. Das Skalieren und Aktualisieren von Komponenten wird ebenfalls vereinfacht.

In diesem Handbuch werden wir die Vorteile der Containerisierung erläutern und erläutern, wie Docker zur Lösung vieler der oben genannten Probleme beiträgt. Docker ist die Kernkomponente in verteilten Container-Bereitstellungen, die eine einfache Skalierbarkeit und Verwaltung bieten.

Eine kurze Geschichte der Linux-Containerisierung

Containerisierung und Isolation sind keine neuen Konzepte in der Computerwelt. Einige Unix-ähnliche Betriebssysteme setzen seit über einem Jahrzehnt ausgereifte Containerisierungstechnologien ein.

In Linux wurde LXC, der Baustein, der die Grundlage für spätere Containerisierungstechnologien bildete, 2008 zum Kernel hinzugefügt. LXC kombinierte die Verwendung von Kernel-Cgroups (ermöglicht das Isolieren und Nachverfolgen der Ressourcennutzung) und Namespaces (ermöglicht das Trennen von Gruppen, damit sie sich nicht gegenseitig „sehen“ können), um eine einfache Prozessisolierung zu implementieren.

Später wurde Docker eingeführt, um die zum Erstellen und Verwalten von Containern erforderlichen Tools zu vereinfachen. Zunächst wurde LXC als Standardausführungstreiber verwendet (seitdem wurde eine Bibliothek mit dem Namenlibcontainer für diesen Zweck entwickelt). Obwohl Docker nicht viele neue Ideen vorstellte, machte es sie für den durchschnittlichen Entwickler und Systemadministrator zugänglich, indem es den Prozess vereinfachte und eine Schnittstelle standardisierte. Dies hat bei den Entwicklern ein erneutes Interesse an der Containerisierung in der Linux-Welt geweckt.

Während einige der Themen, die in diesem Artikel behandelt werden, allgemeiner sind, konzentrieren wir uns aufgrund der überwältigenden Popularität und der Standardanwendung hauptsächlich auf die Docker-Containerisierung.

Welche Containerisierung bringt das Bild

Container bieten Entwicklern und Systemadministratoren / Betriebsteams zahlreiche attraktive Vorteile.

Einige der meisten Vorteile sind unten aufgeführt.

Abstraktion des Hostsystems von der containerisierten Anwendung

Container sollen vollständig standardisiert werden. Dies bedeutet, dass der Container über definierte Schnittstellen eine Verbindung zum Host und zu anderen Objekten außerhalb des Containers herstellt. Eine containerisierte Anwendung sollte sich nicht auf Details zu den Ressourcen oder der Architektur des zugrunde liegenden Hosts verlassen oder damit befasst sein. Dies vereinfacht Entwicklungsannahmen über die Betriebsumgebung. Ebenso ist für den Host jeder Container eine Black Box. Es kümmert sich nicht um die Details der Anwendung im Inneren.

Einfache Skalierbarkeit

Einer der Vorteile der Abstraktion zwischen dem Hostsystem und den Containern besteht darin, dass die Skalierung bei korrektem Anwendungsdesign einfach und unkompliziert sein kann. Serviceorientiertes Design (wird später erläutert) in Kombination mit containerisierten Anwendungen bilden die Grundlage für eine einfache Skalierbarkeit.

Ein Entwickler kann einige Container auf seiner Workstation ausführen, während dieses System in einem Bereitstellungs- oder Testbereich horizontal skaliert werden kann. Wenn die Behälter in Produktion gehen, können sie wieder skaliert werden.

Einfaches Abhängigkeitsmanagement und Anwendungsversionierung

Mit Containern kann ein Entwickler eine Anwendung oder eine Anwendungskomponente mit all ihren Abhängigkeiten als Einheit bündeln. Das Hostsystem muss sich nicht mit den Abhängigkeiten befassen, die zum Ausführen einer bestimmten Anwendung erforderlich sind. Solange Docker ausgeführt werden kann, sollten alle Docker-Container ausgeführt werden können.

Dies erleichtert das Abhängigkeitsmanagement und vereinfacht auch das Versionsmanagement von Anwendungen. Hostsysteme und Betriebsteams sind nicht mehr für die Verwaltung der Abhängigkeitsanforderungen einer Anwendung verantwortlich, da sie, abgesehen von der Abhängigkeit von verwandten Containern, alle im Container selbst enthalten sein sollten.

Extrem leichte, isolierte Ausführungsumgebungen

Während Container nicht die gleiche Isolations- und Ressourcenverwaltungsebene wie Virtualisierungstechnologien bieten, profitieren sie von einer extrem leichten Ausführungsumgebung. Container werden auf Prozessebene isoliert und teilen sich den Kernel des Hosts. Dies bedeutet, dass der Container selbst kein vollständiges Betriebssystem enthält, was zu fast sofortigen Startzeiten führt. Entwickler können problemlos Hunderte von Containern von ihrer Workstation aus ausführen.

Shared Layering

Container sind in einem anderen Sinne leichtgewichtig, da sie in „Ebenen“ festgeschrieben sind. Wenn mehrere Container auf derselben Ebene basieren, können sie die zugrunde liegende Ebene ohne Duplizierung gemeinsam nutzen, was zu einer sehr geringen Auslastung des Speicherplatzes für spätere Bilder führt.

Kompositionsfähigkeit und Vorhersagbarkeit

Mithilfe von Docker-Dateien können Benutzer die genauen Aktionen definieren, die zum Erstellen eines neuen Container-Images erforderlich sind. Auf diese Weise können Sie Ihre Ausführungsumgebung wie Code schreiben und bei Bedarf in der Versionskontrolle speichern. Dieselbe Docker-Datei, die in derselben Umgebung erstellt wurde, erzeugt immer ein identisches Container-Image.

Verwenden von Dockerdateien für wiederholbare, konsistente Builds

Während es möglich ist, Container-Images mithilfe eines interaktiven Prozesses zu erstellen, ist es häufig besser, die Konfigurationsschritte in einer Docker-Datei zu platzieren, sobald die erforderlichen Schritte bekannt sind. Docker-Dateien sind einfache Build-Dateien, die beschreiben, wie ein Container-Image von einem bekannten Ausgangspunkt aus erstellt wird.

Dockerfiles sind unglaublich nützlich und ziemlich einfach zu beherrschen. Einige der Vorteile, die sie bieten, sind:

  • Easy versioning: Die Docker-Dateien selbst können zur Versionskontrolle verpflichtet werden, um Änderungen zu verfolgen und Fehler zurückzusetzen

  • Predicatability: Durch das Erstellen von Bildern aus einer Docker-Datei können menschliche Fehler aus dem Bilderstellungsprozess entfernt werden.

  • Accountability: Wenn Sie Ihre Bilder freigeben möchten, ist es häufig eine gute Idee, die Docker-Datei, mit der das Bild erstellt wurde, bereitzustellen, damit andere Benutzer den Prozess überwachen können. Es enthält im Wesentlichen einen Befehlsverlauf der Schritte, die zum Erstellen des Abbilds ausgeführt wurden.

  • Flexibility: Durch das Erstellen von Bildern aus einer Docker-Datei können Sie die Standardeinstellungen für interaktive Builds überschreiben. Dies bedeutet, dass Sie nicht so viele Laufzeitoptionen angeben müssen, damit das Image wie vorgesehen funktioniert.

Dockerfiles sind ein großartiges Werkzeug zur Automatisierung der Erstellung von Container-Images, um einen wiederholbaren Prozess zu erstellen.

Die Architektur containerisierter Anwendungen

Beim Entwerfen von Anwendungen, die in Containern bereitgestellt werden sollen, ist die tatsächliche Architektur der Anwendung einer der Hauptaspekte. Im Allgemeinen funktionieren containerisierte Anwendungen am besten, wenn ein serviceorientiertes Design implementiert wird.

Serviceorientierte Anwendungen teilen die Funktionalität eines Systems in diskrete Komponenten auf, die über genau definierte Schnittstellen miteinander kommunizieren. Die Containertechnologie selbst fördert diese Art von Design, da jede Komponente unabhängig skaliert oder aktualisiert werden kann.

Anwendungen, die diese Art von Design implementieren, sollten die folgenden Eigenschaften aufweisen:

  • Sie sollten sich nicht um Besonderheiten des Host-Systems kümmern oder sich darauf verlassen

  • Jede Komponente sollte konsistente APIs bereitstellen, mit denen Verbraucher auf den Dienst zugreifen können

  • Jeder Service sollte bei der Erstkonfiguration die Umgebungsvariablen berücksichtigen

  • Anwendungsdaten sollten außerhalb des Containers auf bereitgestellten Volumes oder in Datencontainern gespeichert werden

Mit diesen Strategien kann jede Komponente unabhängig voneinander ausgetauscht oder aktualisiert werden, solange die API beibehalten wird. Sie eignen sich auch für eine fokussierte horizontale Skalierbarkeit, da jede Komponente je nach Engpass skaliert werden kann.

Anstatt bestimmte Werte hart zu codieren, kann jede Komponente im Allgemeinen angemessene Standardwerte definieren. Die Komponente kann diese Werte als Fallback-Werte verwenden, sollte jedoch Werte bevorzugen, die sie aus ihrer Umgebung abrufen kann. Dies wird häufig mithilfe von Diensterkennungstools erreicht, die die Komponente während des Startvorgangs abfragen kann.

Wenn Sie die Konfiguration aus dem eigentlichen Container entfernen und in die Umgebung stellen, können Sie das Anwendungsverhalten problemlos ändern, ohne das Container-Image neu erstellen zu müssen. Eine einzelne Einstellung kann auch mehrere Instanzen einer Komponente beeinflussen. Im Allgemeinen lässt sich serviceorientiertes Design gut mit Umgebungskonfigurationsstrategien kombinieren, da sowohl flexiblere Bereitstellungen als auch eine einfachere Skalierung möglich sind.

Verwenden einer Docker-Registrierung für die Containerverwaltung

Sobald Ihre Anwendung in funktionale Komponenten unterteilt und so konfiguriert ist, dass sie auf andere Container und Konfigurationsflags in der Umgebung angemessen reagiert, besteht der nächste Schritt normalerweise darin, Ihre Container-Images über eine Registrierung verfügbar zu machen. Durch das Hochladen von Container-Images in eine Registrierung können Docker-Hosts das Image herunterfahren und Container-Instanzen hochfahren, indem sie einfach den Image-Namen kennen.

Zu diesem Zweck stehen verschiedene Docker-Register zur Verfügung. Bei einigen handelt es sich um öffentliche Registrierungen, in denen jeder die festgeschriebenen Bilder sehen und verwenden kann, während andere Registrierungen privat sind. Bilder können mit Tags versehen werden, damit sie für Downloads oder Aktualisierungen leicht ausgewählt werden können.

Fazit

Docker bietet den grundlegenden Baustein für die Bereitstellung verteilter Container. Durch das Verpacken von Anwendungskomponenten in eigenen Containern wird die horizontale Skalierung zu einem einfachen Vorgang des Hochfahrens oder Herunterfahrens mehrerer Instanzen jeder Komponente. Docker bietet die erforderlichen Tools, um nicht nur Container zu erstellen, sondern diese auch zu verwalten und für neue Benutzer oder Hosts freizugeben.

Während containerisierte Anwendungen die erforderliche Prozessisolierung und -verpackung bieten, um die Bereitstellung zu unterstützen, sind viele andere Komponenten erforderlich, um Container über einen verteilten Cluster von Hosts angemessen zu verwalten und zu skalieren. In unserennext guide werden wir diskutieren, wie Service Discovery und global verteilte Konfigurationsspeicher zu Cluster-Container-Bereitstellungen beitragen.