GNU/Linux >> LINUX-Kenntnisse >  >> Panels >> Docker

So ändern Sie Docker-Images

Ich nehme an, Sie sind mit Docker ein wenig vertraut und kennen Grundlagen wie das Ausführen von Docker-Containern usw.

In früheren Artikeln haben wir das Aktualisieren von Docker-Containern und das Schreiben von Docker-Dateien besprochen.

Was genau ist das Ändern eines Docker-Images?

Ein Container-Image ist in Schichten aufgebaut (oder es ist eine Sammlung von Schichten), jede Dockerfile-Anweisung erstellt eine Schicht des Bildes. Betrachten Sie beispielsweise die folgende Dockerfile:

FROM alpine:latest

RUN apk add --no-cache python3

ENTRYPOINT ["python3", "-c", "print('Hello World')"]

Da es insgesamt drei Dockerfile-Befehle gibt, enthält das aus dieser Dockerfile erstellte Image insgesamt drei Ebenen.

Sie können dies bestätigen, indem Sie das Bild erstellen:

docker image built -t dummy:0.1 .

Und dann mit dem Befehl docker image history auf dem erstellten Image.

articles/Modify a Docker Image on  modify-docker-images [?] took 12s 
❯ docker image history dummy:0.1 
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
b997f897c2db   10 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["python3" "-c…   0B        
ee217b9fe4f7   10 seconds ago   /bin/sh -c apk add --no-cache python3           43.6MB    
28f6e2705743   35 hours ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      35 hours ago     /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB

Ignorieren Sie die letzte ''-Ebene.

Jede dieser Schichten ist schreibgeschützt. Dies ist vorteilhaft, da diese Ebenen schreibgeschützt sind und kein Prozess, der mit einer laufenden Instanz dieses Abbilds verbunden ist, in der Lage sein wird, den Inhalt dieses Abbilds zu ändern. Daher können diese Ebenen von vielen Containern gemeinsam genutzt werden, ohne dass eine Kopie für jede Instanz. Aber damit die Prozesse der Container R/W ausführen können, wird beim Erstellen der Container eine weitere Ebene zu den vorhandenen RO-Ebenen hinzugefügt, die beschreibbar ist und nicht von anderen Containern geteilt wird.

Der Nachteil dieser R/W-Ebene ist, dass Änderungen, die in dieser Ebene vorgenommen werden, nicht dauerhaft sind, obwohl Sie Volumes verwenden können, um einige Daten beizubehalten, müssen/möchten Sie manchmal eine Ebene vor einer vorhandenen Ebene hinzufügen oder eine Ebene aus einer löschen Bild oder ersetzen Sie einfach eine Ebene. Dies sind die Gründe, warum man einen bestehenden docker ändern möchte Bild.

In diesem Artikel werde ich alle oben genannten Fälle mit verschiedenen Methoden behandeln.

Methoden zum Ändern eines Docker-Images

Es gibt zwei Möglichkeiten, wie Sie ein Docker-Image ändern können.

  1. Über Dockerfiles.
  2. Mit dem Befehl docker container commit .

Ich werde beide Methoden erklären und am Ende hinzufügen, welcher Anwendungsfall für die Methode im Kontext besser wäre.

Methode 1:Ändern des Docker-Image über die Dockerfile

Das Ändern eines Docker-Bildes bedeutet im Wesentlichen das Ändern der Ebenen eines Bildes. Da nun jeder Dockerfile-Befehl eine Ebene des Bildes darstellt, wird das Ändern jeder Zeile einer Dockerfile auch das entsprechende Bild ändern.

Wenn Sie also dem Bild eine Ebene hinzufügen würden, können Sie einfach eine weitere Dockerfile-Anweisung hinzufügen, um eine zu entfernen, würden Sie eine Zeile entfernen und um eine Ebene zu ändern, würden Sie die Zeile entsprechend ändern.

Es gibt zwei Möglichkeiten, wie Sie ein Dockerfile verwenden können, um ein Bild zu ändern.

  1. Verwenden Sie das Bild, das Sie ändern möchten, als Basisbild und erstellen Sie ein untergeordnetes Bild.
  2. Ändern der eigentlichen Docker-Datei des Images, das Sie ändern möchten.

Lassen Sie mich erklären, welche Methode wann und wie angewendet werden sollte.

1. Verwendung eines Bildes als Basisbild

In diesem Fall nehmen Sie das Bild, das Sie ändern möchten, und fügen Ebenen hinzu, um ein neues untergeordnetes Bild zu erstellen. Sofern ein Image nicht von Grund auf neu erstellt wird, ist jedes Image eine Modifikation desselben übergeordneten Basis-Images.

Betrachten Sie die vorherige Dockerfile. Angenommen, das Image, das aus diesem Image erstellt wird, heißt dummy:0.1 . Wenn ich jetzt denken würde, dass ich jetzt Perl anstelle von Python3 verwenden muss, um "Hello World" zu drucken, aber ich möchte Python3 auch nicht entfernen, könnte ich einfach den dummy:0.1 verwenden image als Basis-Image (da Python3 bereits vorhanden ist) und daraus wie folgt erstellen

FROM dummy:0.1

RUN apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

Hier baue ich auf dummy:0.1 auf , indem ich nach Belieben weitere Ebenen hinzufüge.

Diese Methode ist nicht sehr hilfreich, wenn Sie beabsichtigen, eine vorhandene Ebene zu ändern oder zu löschen. Dazu müssen Sie der nächsten Methode folgen.

2. Dockerfile des Bildes ändern

Da die vorhandenen Ebenen eines Images schreibgeschützt sind, können Sie sie nicht direkt über eine neue Dockerfile ändern. Mit dem FROM Befehl in einer Docker-Datei, nehmen Sie ein Image als Basis und bauen auf auf oder fügen Sie Ebenen hinzu.

Bei einigen Aufgaben müssen wir möglicherweise eine vorhandene Ebene ändern, obwohl Sie dies mit der vorherigen Methode mit einer Reihe widersprüchlicher RUN tun können Anweisungen (wie das Löschen von Dateien, das Entfernen/Ersetzen von Paketen, die in einer früheren Ebene hinzugefügt wurden), ist dies keine ideale Lösung oder was ich empfehlen würde. Weil es zusätzliche Ebenen hinzufügt und die Bildgröße um einiges erhöht.

Eine bessere Methode wäre, das Image nicht als Basis-Image zu verwenden, sondern die eigentliche Docker-Datei dieses Images zu ändern. Betrachten Sie noch einmal das vorherige Dockerfile. Was wäre, wenn ich Python3 nicht in diesem Image behalten und das Python3-Paket und den Befehl durch die Perl-Pakete ersetzen müsste?

Wenn ich der vorherigen Methode gefolgt wäre, hätte ich eine neue Dockerfile wie folgt erstellen müssen -

FROM dummy:0.1

RUN apk del python3 && apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

Wenn es gebaut wird, wird es in diesem Bild insgesamt fünf Ebenen geben.

articles/Modify a Docker Image on  modify-docker-images [?] took 3s 
❯ docker image history dummy:0.2
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
2792036ddc91   10 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["perl" "-e" "…   0B        
b1b2ec1cf869   11 seconds ago   /bin/sh -c apk del python3 && apk add --no-c…   34.6MB    
ecb8694b5294   3 hours ago      /bin/sh -c #(nop)  ENTRYPOINT ["python3" "-c…   0B        
8017025d71f9   3 hours ago      /bin/sh -c apk add --no-cache python3 &&    …   43.6MB    
28f6e2705743   38 hours ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      38 hours ago     /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB

Außerdem beträgt die Größe des Bildes 83,8 MB.

articles/Modify a Docker Image on  modify-docker-images [?] 
❯ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
dummy        0.2       2792036ddc91   19 seconds ago   83.8MB

Anstatt das jetzt zu tun, nehmen Sie die anfängliche Docker-Datei und ändern Sie die Python3-Dateien so in Perl

FROM alpine:latest

RUN apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

Die Anzahl der Ebenen wurde auf 3 reduziert und die Größe beträgt jetzt 40,2 MB.

articles/Modify a Docker Image on  modify-docker-images [?] took 3s 
❯ docker image history dummy:0.3
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
f35cd94c92bd   9 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["perl" "-e" "…   0B        
053a6a6ba221   9 seconds ago   /bin/sh -c apk add --no-cache perl              34.6MB    
28f6e2705743   38 hours ago    /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      38 hours ago    /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB    

articles/Modify a Docker Image on  modify-docker-images [?] 
❯ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
dummy        0.3       f35cd94c92bd   29 seconds ago   40.2MB

Bild erfolgreich geändert.

Die vorherige Methode ist nützlicher, wenn Sie nur Ebenen über den vorhandenen hinzufügen möchten, ist jedoch nicht sehr hilfreich, wenn Sie versuchen, die vorhandenen Ebenen zu ändern, z. B. eine löschen, eine ersetzen, die vorhandenen neu anordnen und bald. Hier glänzt diese Methode.

Methode 2:Bild mit Docker-Commit ändern

Es gibt noch eine weitere Methode, mit der Sie einen Snapshot eines laufenden Containers erstellen und diesen in ein eigenes Image umwandeln können.

Lassen Sie uns einen dummy:0.1 erstellen identisches Image, aber diesmal ohne Verwendung eines Dockerfiles. Da ich alpine:latest verwendet habe als dummy:0.1 in der Basis von , einen Container dieses Bildes hochfahren.

docker run --rm --name alpine -ti alpine ash

Fügen Sie nun im Container das Python3-Paket hinzu, apk add --no-cache python3 . Wenn Sie fertig sind, öffnen Sie ein neues Terminalfenster und führen Sie den folgenden Befehl (oder etwas Ähnliches)

aus
docker container commit --change='ENTRYPOINT ["python3", "-c", "print(\"Hello World\")"]' alpine dummy:0.4

Mit dem --change flag Ich füge dem neuen dummy:04 eine Dockerfile-Anweisung hinzu Bild (in diesem Fall der ENTRYPOINT Anleitung).

Mit dem docker container commit Befehl konvertieren Sie im Grunde die äußerste R/W-Ebene in eine R/O-Ebene, hängen diese an die Ebenen des vorhandenen Bildes an und erstellen ein neues Bild. Diese Methode ist intuitiver/interaktiver, daher möchten Sie sie möglicherweise anstelle von Dockerfiles verwenden, aber verstehen Sie, dass dies nicht sehr reproduzierbar ist. Die gleichen Regeln gelten auch für das Entfernen oder Ändern vorhandener Ebenen. Das Hinzufügen einer Ebene, nur um etwas zu entfernen oder etwas zu ändern, das in einer vorherigen Ebene gemacht wurde, ist nicht die beste Idee, zumindest in den meisten Fällen.

Damit ist dieser Artikel abgeschlossen. Ich hoffe, dieser war hilfreich für Sie, wenn Sie Fragen haben, kommentieren Sie unten.


Docker
  1. So verschieben Sie Docker-Images zwischen Hosts

  2. So reduzieren Sie die Docker-Image-Größe:6 Optimierungsmethoden

  3. So verwenden Sie ein Dockerfile zum Erstellen eines Docker-Images

  4. So teilen Sie Docker-Images mit anderen

  5. So übertragen Sie Änderungen an einem Docker-Image

So aktualisieren Sie Docker-Images auf die neueste Version

So verwenden Sie Docker Commit zum Ändern von Container-Images

Vollständige Anleitung zum Entfernen von Docker-Images

So erstellen Sie ein benutzerdefiniertes Docker-Image mit Dockerfile

Teilen von Docker-Images auf Docker Hub

So listen / suchen / ziehen Sie Docker-Images unter Linux