Wie erkennt man, dass man Docker und nicht eine VM benötigt? Man muss feststellen, was genau isoliert werden soll. Wenn eine Isolation mit garantiert zugewiesenen Ressourcen und virtueller Hardware erforderlich ist, sollte die Wahl auf eine VM fallen. Wenn laufende Anwendungen als separate Prozesse im System isoliert werden müssen, benötigen Sie Docker.
Was ist der Unterschied zwischen Docker-Containern und VMs?
Eine virtuelle Maschine (VM) — ist ein virtueller Computer mit allen virtuellen Geräten und einer virtuellen Festplatte, auf der ein neues, unabhängiges Betriebssystem zusammen mit virtuellen Gerätetreibern, Speicherverwaltung und anderen Komponenten installiert wird. Das heißt, wir erhalten eine Abstraktion der physischen Hardware, die es ermöglicht, viele virtuelle Computer auf einem einzigen physischen Computer auszuführen.
Eine installierte VM kann unterschiedlich viel Platz auf der Festplatte des Computers einnehmen:
- fester Platz auf der Festplatte, der einen schnelleren Zugriff auf die virtuelle Festplatte ermöglicht und Fragmentierung der Datei vermeidet;
- dynamische Speicherzuweisung. Bei der Installation zusätzlicher Anwendungen wird der Speicher dynamisch für diese zugewiesen, bis das maximal dafür vorgesehene Volumen erreicht ist.
Je mehr virtuelle Maschinen auf dem Server, desto mehr Platz benötigen sie und erfordern auch ständige Unterstützung der Umgebung, die für den Betrieb Ihrer Anwendung erforderlich ist.
Docker — ist Software zur Erstellung von Anwendungen auf Basis von Containern. Container und virtuelle Maschinen haben vergleichbare Vorteile, funktionieren jedoch unterschiedlich. Container benötigen weniger Platz, da sie mehr gemeinsame Ressourcen des Host-Systems wiederverwendet, als VMs, da sie im Gegensatz zu VMs Virtualisierung auf Betriebssystemebene und nicht auf Hardwareebene bieten. Dieser Ansatz sorgt für einen geringeren Speicherbedarf, eine schnelle Bereitstellung und eine einfachere Skalierung.
Ein Container bietet einen effizienteren Mechanismus zur Kapselung von Anwendungen und stellt die erforderlichen Schnittstellen des Host-Systems bereit. Diese Möglichkeit erlaubt es den Containern, den Kernel des Systems zu teilen, wobei jeder Container als separater Prozess des Hauptbetriebsystems arbeitet, der über einen eigenen Satz von Speicherbereichen (ein eigenes virtuelles Adressraum) verfügt. Da der virtuelle Adressraum jedes Containers eigenständig ist, können Daten, die verschiedenen Speicherbereichen angehören, nicht verändert werden.
Das native Betriebssystem für Docker ist Linux (Docker kann auch unter Windows und MacOS verwendet werden). Er nutzt die wesentlichen Vorteile, die ihm die Organisation der Kernel-Trennung ermöglichen. Das Starten von Docker-Containern unter Windows erfolgt innerhalb einer virtuellen Maschine mit dem Betriebssystem Linux, da die Container das Betriebssystem des Host-Systems und das Hauptbetriebssystem für sie ist Linux.
Wie funktioniert ein Container?
Container sind eine Abstraktion auf Anwendungsebene, die Code und Abhängigkeiten vereint. Container werden immer aus Images erstellt, indem eine beschreibbare obere Schicht hinzugefügt wird und verschiedene Parameter initialisiert werden. Da jeder Container seine eigene Schicht zum Schreiben hat und alle Änderungen in dieser Schicht gespeichert werden, können mehrere Container gemeinsam auf dasselbe Basis-Image zugreifen.
Jeder Container kann über eine Datei im Projekt docker-compose, die in die Hauptlösung - docker-compose.yml - integriert ist, konfiguriert werden. Dort können verschiedene Parameter wie den Containernamen, Ports, IDs, Ressourcenbeschränkungen und Abhängigkeiten zwischen anderen Containern festgelegt werden. Wenn im Setup kein Containername angegeben wird, erstellt Docker jedes Mal einen neuen Container und weist ihm zufällig einen Namen zu.
Wenn ein Container aus einem Image gestartet wird, mountet Docker das Dateisystem zum Lesen und Schreiben über alle darunter liegenden Schichten. Hier werden alle Prozesse ausgeführt, die wir möchten, dass unser Docker-Container ausführt.
Wenn Docker einen Container zum ersten Mal startet, ist die anfängliche Lese-Schreib-Schicht leer. Wenn Änderungen vorgenommen werden, werden sie auf diese Schicht angewendet; wenn Sie beispielsweise eine Datei ändern möchten, wird diese Datei aus der darunter liegenden Nur-Lese-Schicht in die Lese-Schreib-Schicht kopiert.
Die nur lesbare Datei-Version wird weiterhin existieren, ist jedoch jetzt hinter einer Kopie verborgen. Für die Datenspeicherung, unabhängig vom Lebenszyklus des Containers, werden Volumes verwendet. Volumes werden bei der Erstellung des Containers initialisiert.
Wie ist ein Image mit einem Container verbunden?
Image — das grundlegende Element für jeden Container. Ein Image wird aus einer Dockerfile erstellt, die dem Projekt hinzugefügt wurde, und besteht aus einem Stapel übereinander geschichteter Dateisysteme (Schichten), die zusammengefasst und nur lesbar sind; die maximale Anzahl der Schichten beträgt 127.
Jedes Image basiert auf einem Basisimage, das durch den Befehl FROM angegeben wird — der Einstiegspunkt beim Erstellen des Dockerfile-Images. Jede Schicht ist eine schreibgeschützte Schicht und wird durch einen Befehl dargestellt, der das Dateisystem modifiziert, das im Dockerfile festgelegt ist.
Um diese Schichten zu einem einzigen Image zu kombinieren, verwendet Docker das Advanced multi layered Union file system (AuFS basiert auf UnionFS), das es ermöglicht, dass verschiedene Dateien und Verzeichnisse aus unterschiedlichen Dateischichten transparent übereinander gelegt werden und ein zusammenhängendes Dateisystem erstellt wird.
Die Schichten enthalten Metadaten, die es ermöglichen, begleitende Informationen über jede Schicht während der Laufzeit und des Builds zu speichern. Jede Schicht enthält einen Verweis auf die nächste Schicht. Wenn eine Schicht keinen Verweis hat, handelt es sich um die oberste Schicht im Image.
Die Dockerfile kann solche Befehle enthalten wie:
- FROM — der Einstiegspunkt beim Erstellen des Images;
- MAINTAINER — der Name des Besitzers des Images;
- RUN — Durchführung eines Befehls während des Bildbaus;
- ADD — Kopieren einer Datei vom Host in das neue Image. Wenn eine URL-Datei angegeben wird, lädt Docker sie in das angegebene Verzeichnis hoch;
- ENV — Umgebungsvariablen;
- CMD — startet die Erstellung eines neuen Containers auf Basis des Images;
- ENTRYPOINT — der Befehl wird beim Start des Containers ausgeführt.
- WORKDIR — das Arbeitsverzeichnis für die Ausführung des CMD-Befehls.
- USER — legt die UID für den auf Basis des Images erstellten Container fest.
- VOLUME — bindet das Verzeichnis des Hosts in den Container ein.
- EXPOSE — Satz von Ports, die im Container überwacht werden.
Wie funktioniert UnionFS?
UnionFS — ein dienstliches Stackspeichersystem (FS) für Linux und FreeBSD. Dieses FS implementiert den Mechanismus des Copy-On-Write (COW). Die Arbeitseinheit von UnionFS ist die Schicht, wobei jede Schicht als vollwertiges Dateisystem mit Verzeichnisstruktur vom Root betrachtet wird. UnionFS erstellt eine kombinierte Einbindung für andere Dateisysteme und ermöglicht es dem Benutzer, Dateien und Verzeichnisse verschiedener Dateisysteme (die als Äste bezeichnet werden) in ein einziges verbundenes Dateisystem transparent zusammenzuführen.
Der Inhalt von Verzeichnissen mit identischen Pfaden wird zusammen in einem kombinierten Verzeichnis (in einem gemeinsamen Namensraum) des resultierenden Dateisystems angezeigt.
UnionFS kombiniert Schichten nach folgenden Prinzipien:
- eine der Schichten wird zur obersten Schicht, während die zweite und die folgenden Schichten untere Schichten werden;
- Benutzern sind die Objekte der Schichten "von oben nach unten" zugänglich, d.h. wenn das angeforderte Objekt in der "oberen" Schicht vorhanden ist, wird es zurückgegeben, unabhängig davon, ob ein Objekt mit demselben Namen in der "unteren" Schicht vorhanden ist; andernfalls wird das Objekt der "unteren" Schicht zurückgegeben; wenn das angeforderte Objekt weder dort noch dort vorhanden ist, wird der Fehler "Datei oder Verzeichnis nicht gefunden" zurückgegeben;
- die aktive Schicht ist die "obere", das heißt, alle Benutzeraktionen zur Datenänderung wirken sich nur auf die oberste Schicht aus, ohne den Inhalt der unteren Schichten zu beeinflussen.
Docker ist die am weitesten verbreitete Technologie zur Nutzung von Containern in der Anwendungsarbeit. Es ist zum Standard in diesem Bereich geworden, basierend auf cgroups und Namespaces, die vom Linux-Kernel bereitgestellt werden.
Docker ermöglicht es uns, Anwendungen schnell bereitzustellen und das Dateisystem optimal zu nutzen, indem der Kernel des Betriebssystems zwischen allen Containern geteilt wird und wie separate OS-Prozesse gearbeitet wird.
Quelle: habr.com
