Ich bin brandneu bei Docker und versuche genau zu verstehen, was ein Docker- Image ist. Jede einzelne Definition eines Docker-Bildes verwendet den Begriff "Ebene", scheint jedoch nicht zu definieren, was unter Ebene zu verstehen ist .
Aus den offiziellen Docker-Dokumenten :
Wir haben bereits gesehen, dass Docker-Images schreibgeschützte Vorlagen sind, aus denen Docker-Container gestartet werden. Jedes Bild besteht aus einer Reihe von Ebenen. Docker verwendet Union-Dateisysteme, um diese Ebenen zu einem einzigen Bild zu kombinieren. Mit Union-Dateisystemen können Dateien und Verzeichnisse separater Dateisysteme, sogenannte Zweige, transparent überlagert werden und bilden ein einziges zusammenhängendes Dateisystem.
Also frage ich, was ist eine Schicht (genau); Kann jemand ein paar konkrete Beispiele dafür nennen? Und wie "schnappen" diese Ebenen zusammen, um ein Bild zu bilden?
https://labs.ctl.io/caching-docker-images/
) ist kaputt. Hat jemand Vorschläge für einen Ersatz?Ein Docker-Container-Image wird mithilfe einer Docker-Datei erstellt . Jede Zeile in einer Docker-Datei erstellt eine Ebene. Betrachten Sie das folgende Dummy-Beispiel:
Dadurch wird ein endgültiges Bild erstellt, in dem die Gesamtzahl der Ebenen X + 3 beträgt
quelle
Sie machen für mich mit einem Beispiel am meisten Sinn ...
Untersuchen von Ebenen Ihres eigenen Builds mit Docker Diff
Nehmen wir ein erfundenes Beispiel Dockerfile:
Jeder dieser
dd
Befehle gibt eine 1M-Datei auf der Festplatte aus. Erstellen Sie das Image mit einem zusätzlichen Flag, um die temporären Container zu speichern:In der Ausgabe sehen Sie, dass jeder der ausgeführten Befehle in einem temporären Container ausgeführt wird, den wir jetzt behalten, anstatt ihn automatisch zu löschen:
Wenn Sie
docker diff
für jede dieser Container-IDs eine ausführen , sehen Sie, welche Dateien in diesen Containern erstellt wurden:Jede Zeile mit dem Präfix a
A
fügt die Datei hinzu, dasC
zeigt eine Änderung an einer vorhandenen Datei an und dasD
zeigt ein Löschen an.Hier ist der TL; DR-Teil
Jedes der oben genannten Unterschiede in diesem Container-Dateisystem besteht aus einer "Ebene", die zusammengestellt wird, wenn Sie das Image als Container ausführen. Die gesamte Datei befindet sich in jeder Ebene, wenn hinzugefügt oder geändert wird. Daher führt jeder dieser
chmod
Befehle, obwohl nur ein Berechtigungsbit geändert wird, dazu, dass die gesamte Datei in die nächste Ebene kopiert wird. Die gelöschte / data / one-Datei befindet sich noch dreimal in den vorherigen Ebenen und wird über das Netzwerk kopiert und beim Abrufen des Bildes auf der Festplatte gespeichert.Bestehende Bilder untersuchen
Sie können die Befehle sehen, mit denen die Ebenen eines vorhandenen Bildes mit dem
docker history
Befehl erstellt werden. Sie können auchdocker image inspect
ein Bild ausführen und die Liste der Ebenen im Abschnitt RootFS anzeigen.Hier ist die Geschichte für das obige Bild:
Die neuesten Ebenen sind oben aufgeführt. Bemerkenswert ist, dass es unten zwei Schichten gibt, die ziemlich alt sind. Sie stammen aus dem Busybox-Image selbst. Wenn Sie ein Bild erstellen, erben Sie alle Ebenen des Bildes, die Sie in der
FROM
Zeile angeben . Es werden auch Ebenen für Änderungen an den Bild-Metadaten hinzugefügt, z. B. dieCMD
Linie. Sie nehmen kaum Platz ein und dienen eher dazu, aufzuzeichnen, welche Einstellungen für das von Ihnen ausgeführte Bild gelten.Warum Schichten?
Die Schichten haben einige Vorteile. Erstens sind sie unveränderlich. Einmal erstellt, wird sich diese durch einen sha256-Hash identifizierte Ebene niemals ändern. Diese Unveränderlichkeit ermöglicht es Bildern, sich sicher aufzubauen und voneinander zu trennen. Wenn zwei Docker-Dateien denselben Anfangssatz von Zeilen haben und auf demselben Server erstellt werden, teilen sie denselben Satz von Anfangsebenen, wodurch Speicherplatz gespart wird. Das bedeutet auch, dass beim erneuten Erstellen eines Images, bei dem nur die letzten Zeilen der Docker-Datei Änderungen erfahren, nur diese Ebenen neu erstellt werden müssen und der Rest aus dem Ebenen-Cache wiederverwendet werden kann. Dadurch können Docker-Images sehr schnell neu erstellt werden.
In einem Container sehen Sie das Image-Dateisystem, aber dieses Dateisystem wird nicht kopiert. Über diesen Bildebenen stellt der Container seine eigene Lese- / Schreib-Dateisystemebene bereit. Jeder Lesevorgang einer Datei durchläuft die Ebenen, bis sie auf eine Ebene trifft, die die Datei zum Löschen markiert hat, eine Kopie der Datei in dieser Ebene hat oder dem Lesevorgang die Ebenen zum Durchsuchen ausgehen. Bei jedem Schreibvorgang wird eine Änderung in der container-spezifischen Lese- / Schreibschicht vorgenommen.
Reduzierung des Aufblähens der Schicht
Ein Nachteil der Ebenen ist das Erstellen von Bildern, die Dateien duplizieren oder Dateien versenden, die in einer späteren Ebene gelöscht werden. Die Lösung besteht häufig darin, mehrere Befehle zu einem einzigen
RUN
Befehl zusammenzuführen. Insbesondere wenn Sie vorhandene Dateien ändern oder Dateien löschen, möchten Sie, dass diese Schritte in demselben Befehl ausgeführt werden, in dem sie zuerst erstellt wurden. Eine Neufassung der obigen Docker-Datei würde folgendermaßen aussehen:Und wenn Sie die resultierenden Bilder vergleichen:
Durch einfaches Zusammenführen einiger Zeilen im erfundenen Beispiel haben wir den gleichen resultierenden Inhalt in unserem Bild erhalten und unser Bild von 5 MB auf nur die 1 MB-Datei verkleinert, die Sie im endgültigen Bild sehen.
quelle
Seit Docker v1.10, mit der Einführung des inhaltsadressierbaren Speichers, wurde der Begriff "Ebene" ganz anders. Ebenen haben keine Vorstellung von einem Bild oder gehören zu einem Bild. Sie werden lediglich zu Sammlungen von Dateien und Verzeichnissen, die von mehreren Bildern gemeinsam genutzt werden können. Ebenen und Bilder wurden getrennt.
Beispiel: Bei einem lokal erstellten Image aus einem Basis-Image gibt
ubuntu:14.04
derdocker history
Befehl beispielsweise die Image-Kette aus. Einige der Image-IDs werden jedoch als "fehlend" angezeigt, da der Build-Verlauf nicht mehr geladen wird. Und die Ebenen, aus denen diese Bilder bestehen, können über gefunden werdenDer Ebeneninhalt wird gespeichert,
/var/lib/docker/aufs/diff
wenn die Auswahl des Speichertreibers lautetaufs
. Die Layer werden jedoch mit einer zufällig generierten Cache-ID benannt. Die Verbindung zwischen einem Layer und seiner Cache-ID scheint Docker Engine nur aus Sicherheitsgründen bekannt zu sein. Ich bin immer noch auf der Suche nach einem Weg, es herauszufindenDieser Blog lieferte viele Einblicke.
quelle
Per Docker- Bildspezifikation über The Moby Project :
Eine Ebene besteht also im Wesentlichen nur aus einer Reihe von Änderungen, die am Dateisystem vorgenommen wurden.
quelle
"Each [Docker] layer is a set of filesystem changes."
(Vorausgesetzt, dies ist wahr.) Aus irgendeinem Grund habe ich diesen grundlegenden Punkt beim Lesen zahlreicher anderer Dokumente nicht verstanden. Blogs / Q + A's / etc, und ich vermute, die Einschränkung lag bei ihnen und nicht bei mir. Unabhängig davon, Bravo Aditya, um die Sache auf den Punkt zu bringen.Ich denke, das offizielle Dokument enthält eine ziemlich detaillierte Erklärung: https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/ .
(Quelle: docker.com )
Ein Bild besteht aus vielen Ebenen, die normalerweise aus Dockerfile generiert werden. Jede Zeile in Dockerfile erstellt eine neue Ebene, und das Ergebnis ist ein Bild, das durch das Formular
repo:tag
wie gekennzeichnet istubuntu:15.04
.Weitere Informationen finden Sie in den offiziellen Dokumenten oben.
quelle
Vielen Dank an David Castillo für die nützlichen Informationen . Ich denke, die Ebene ist eine binäre Änderung oder Anweisung eines Bildes, die leicht durchgeführt oder rückgängig gemacht werden kann. Sie werden Schritt für Schritt ausgeführt, was einer Ebene auf einer Ebene entspricht, daher haben wir "Ebene" genannt.
Weitere Informationen finden Sie in der "Docker-Historie" wie folgt:
quelle
Mein persönliches Verständnis ist, dass wir die Docker-Ebene mit dem Github-Commit vergleichen können. Für Ihr Basis-Image (Ihr neues Master-Repo) führen Sie mehrere Commits durch, jedes Commit ändert Ihren Master-Status, es ist im Docker gleich, jede Ebene führt eine Operation basierend auf der vorherigen Zwischenebene aus. Und dann wird diese Schicht eine neue Zwischenschicht zur nächsten Schicht.
quelle
Früher dachte ich, sie sind wie Unterschiede in früheren Schichten. Nachdem ich einige der Antworten hier gelesen hatte, war ich mir nicht so sicher; Sie werden als Änderungssätze am Dateisystem beschrieben . Ich habe einige Dockerfiles geschrieben, um zu zeigen, dass sie eher Diffs sind, dh sie hängen wirklich von vorherigen Ebenen ab.
Angesichts dieser beiden Dockerfiles
und
Man würde den gleichen Satz von Ebenen erwarten, wenn es nur um Änderungen am Dateisystem geht, aber dies ist nicht der Fall:
und
Sie können sehen, wie wichtig die Reihenfolge ist , auch wenn die Änderungen am Dateisystem in beiden Fällen gleich sind.
quelle