Docker-Container sind im Allgemeinen flüchtige Anwendungsinstanzen ohne internen Status. Das ist die bewährte Art, mit ihnen umzugehen, sodass Sie Ihre Container jederzeit anhalten oder neu starten können.
Manchmal sind Änderungen am Dateisystem eines Containers jedoch unvermeidlich. Vielleicht probieren Sie Software aus und möchten einen Schnappschuss, zu dem Sie später zurückkehren können. Ein weiterer Anwendungsfall könnten Situationen sein, in denen die Software in einem Container nicht mehr funktioniert und Sie eine Replik speichern möchten, die Sie in Zukunft debuggen können.
So erstellen Sie ein neues Docker-Image aus einem vorhandenen Container. Sie können dann einen neuen starten Container aus diesem Image, der mit dem Dateisystem des ersten gefüllt wird.
Bestätigung von Containern
Der docker commit
Der Befehl wird verwendet, um einen Container zu nehmen und daraus ein neues Image zu erstellen. Es funktioniert sowohl mit angehaltenen als auch mit laufenden Containern.
Die grundlegende Syntax lautet wie folgt:
docker commit example-container example-image:latest
Dadurch wird ein Image aus dem Container mit dem Namen example-container
erstellt . Sie können den Container auch anhand der ID identifizieren, wenn Sie dies bevorzugen. Beide Informationen sind in der Ausgabe von docker ps
verfügbar die alle Container auf Ihrem Host auflistet.
Dem resultierenden Bild wird das als zweiter Parameter des Befehls angegebene Tag zugewiesen. Dies ist example-image:latest
im oben gezeigten Beispiel. Genau wie bei einem normalen Bild-Tagging-Vorgang ersetzt das neue Bild die Referenz des Tags, falls sie bereits vorhanden ist.
Jetzt können Sie Ihr Image verwenden, um das Dateisystem aus example-container
wiederherzustellen in eine neue Containerinstanz:
docker run -d example-image:latest
Der Inhalt des Dateisystems entspricht dem example-container
Container zum Zeitpunkt des docker commit
Befehl ausgeführt wurde. Es gibt einen wichtigen Vorbehalt:Der Inhalt von bereitgestellten Volumes wird nicht eingeschlossen, sodass ihre Bereitstellungsorte im erstellten Container-Image leer sind. Um einen neuen Container mit intakten Volume-Daten auszuführen, verwenden Sie -v
-Flag, um die Volumes aus dem ersten Container neu anzuhängen, wenn Sie die zweite Instanz mit docker run
starten .
Ein weiterer bemerkenswerter Knackpunkt ist, wie Docker mit Commits von laufenden Containern umgeht. Zum größten Teil sollte dies nahtlos funktionieren, aber standardmäßig wird der Zielcontainer angehalten, bevor das Commit erstellt wird. Alle Prozesse innerhalb des Containers werden angehalten und nach Abschluss der Image-Erstellung wieder aufgenommen. Dadurch wird die Datenkonsistenz im neuen Image verbessert, der Container bleibt jedoch vorübergehend unzugänglich. Sie können dieses Verhalten deaktivieren, indem Sie --pause false
einfügen mit Ihrem docker commit
Befehl.
Commit-Nachrichten hinzufügen
Der docker commit
command unterstützt Commit-Nachrichten auf ähnliche Weise wie Versionskontrollsoftware wie Git. Wenn Sie beim Erstellen eines Images aus einem Container eine Nachricht hinzufügen, können Sie dokumentieren, was sich geändert hat, und den Grund für Ihren Commit.
Verwenden Sie die --message
oder -m
Flag, um eine Commit-Nachricht anzuwenden:
docker commit -m "Example commit" example-container example-image:latest
Sie können Informationen zur Urheberschaft auch mit einem speziellen Flag hinzufügen. Geben Sie eine Zeichenfolge im allgemeinen First Name <[email protected]>
an Format an --author
oder -a
Flagge. Es wird zusammen mit der Commit-Nachricht gespeichert.
docker commit -a "Example Author <[email protected]>" -m "Example commit" example-container example-image:latest
Commit-Meldungen werden angezeigt, wenn Sie den docker history
verwenden Befehl, um die Ebenen in einem Bild anzuzeigen. Sie werden im COMMENT
angezeigt Spalte ganz rechts.
Eine andere Möglichkeit, auf diese Informationen zuzugreifen, ist die Verwendung von docker inspect
zusammen mit grep
um Urheber- und Kommentarwerte aus der JSON-Darstellung eines Bildes zu extrahieren:
docker inspect <image-id> | grep 'Created|Author|Comment'
Dadurch werden die Daten angezeigt, die der obersten Ebene im Bild zugeordnet sind.
Ändern von Dockerfile-Anweisungen
Wenn Sie ein Image festschreiben, haben Sie die Möglichkeit, einige seiner Dockerfile-Anweisungen zu ändern. Sie können die folgenden Werte in Ihrem neuen Bild überschreiben:
CMD
ENTRYPOINT
ENV
EXPOSE
LABEL
ONBUILD
USER
VOLUME
WORKDIR
Um eine Anweisung festzulegen, verwenden Sie --change
oder -c
Flagge:
docker commit --change 'ENTRYPOINT ["sh"]' example-container example-image:latest
Sie können das Flag so oft wie nötig wiederholen, um alle beabsichtigten Änderungen zu übernehmen.
Es werden nur Anweisungen unterstützt, die sich auf die oberste Dateisystemschicht auswirken. Sie können ein festgeschriebenes Bild nicht nahtlos mit neuen Ebenen über Anweisungen wie RUN
erweitern und COPY
. Sie können jedoch das Ergebnis eines Commits nehmen und eine neue Docker-Datei schreiben, die bei Bedarf neue Inhalte hinzufügt:
# Created via `docker commit` FROM example-image:latest RUN apt install example-package
Wenn Sie Dockerfile-Anweisungen zum Commit-Zeitpunkt ändern, lohnt es sich, eine Commit-Nachricht hinzuzufügen, die erklärt, was Sie ändern und warum. Dies hilft allen anderen mit Zugriff auf das Image, Verhaltensunterschiede im Vergleich zu dem Container, aus dem es erstellt wurde, zu verstehen.
Zusammenfassung
Docker-Images werden normalerweise aus Dockerfiles erstellt und zum Starten von Einwegcontainern verwendet. Änderungen am Zustand des Dateisystems eines Containers werden vorgenommen, indem das Image neu erstellt, der vorhandene Container zerstört und ein neuer gestartet wird. In einer idealen Welt haben Container keinen internen Zustand, aber das ist in der Praxis nicht immer der Fall.
Das Festschreiben eines Containers gibt Ihnen die Möglichkeit, sein aktuelles Dateisystem in Zukunft wiederherzustellen. Commits sind nützlich, um Repliken von problematischen Containern zu erstellen, damit Sie in einer separaten Umgebung debuggen können, während Sie den Zugriff auf zuvor generierte Protokolle und temporäre Dateien behalten.
Obwohl sich Container-Commits oft ähnlich wie VM-Snapshots anfühlen, sind sie nicht ganz dasselbe. VMs steuern virtuelle Hardware, und der Status dieser Hardware wird im Snapshot angezeigt. Docker-Container sind nur eine Reihe von Prozessen, die auf dem Host ausgeführt werden. Ein Commit ist ein neues Docker-Image, das das Dateisystem des Containers darstellt aber es fehlen zwangsläufig Daten über den Status von Prozessen, dem Kernel und Ihrer Hardware.