GNU/Linux >> Linux Esercitazione >  >> Panels >> Docker

Come modificare le immagini Docker

Presumo che tu abbia un po' di familiarità con Docker e conosca nozioni di base come l'esecuzione di contenitori docker ecc.

In articoli precedenti abbiamo discusso dell'aggiornamento del contenitore Docker e della scrittura di file Docker.

Che cos'è esattamente la modifica di un'immagine della finestra mobile?

Un'immagine contenitore è costruita in livelli (o è una raccolta di livelli), ogni istruzione Dockerfile crea un livello dell'immagine. Ad esempio, considera il seguente Dockerfile:

FROM alpine:latest

RUN apk add --no-cache python3

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

Poiché ci sono un totale di tre comandi Dockerfile, l'immagine creata da questo Dockerfile conterrà un totale di tre livelli.

Puoi confermarlo costruendo l'immagine:

docker image built -t dummy:0.1 .

E poi usando il comando docker image history sull'immagine creata.

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

Ignora l'ultimo livello "".

Ciascuno di questi livelli è di sola lettura. Ciò è vantaggioso perché poiché questi livelli sono di sola lettura, nessun processo associato a un'istanza in esecuzione di questa immagine sarà in grado di modificare il contenuto di questa immagine, pertanto questi livelli possono essere condivisi da molti contenitori senza dover mantenere un copia per ogni istanza. Ma affinché i processi dei contenitori siano in grado di eseguire r/w, un altro livello viene aggiunto sopra i livelli RO esistenti durante la creazione dei contenitori, questo è scrivibile e non condiviso da altri contenitori.

Lo svantaggio di questo livello r/w è che le modifiche apportate a questo livello non sono persistenti, sebbene sia possibile utilizzare i volumi per rendere persistenti alcuni dati, a volte potrebbe essere necessario/volere aggiungere un livello prima di un livello esistente o eliminare un livello da un immagine o semplicemente sostituire un livello. Questi sono i motivi per cui si potrebbe voler modificare una docker esistente immagine.

In questo articolo tratterò tutti i casi che ho menzionato sopra, utilizzando metodi diversi.

Metodi per modificare un'immagine della finestra mobile

Esistono due modi per modificare un'immagine della finestra mobile.

  1. Tramite Dockerfiles.
  2. Utilizzando il comando docker container commit .

Spiegherò entrambi i metodi e, alla fine, aggiungerò anche quale caso d'uso sarebbe migliore per il metodo nel contesto.

Metodo 1:modifica dell'immagine della finestra mobile tramite Dockerfile

Modificare un'immagine mobile significa essenzialmente modificare i livelli di un'immagine. Ora, poiché ogni comando Dockerfile rappresenta un livello dell'immagine, la modifica di ogni riga di un Dockerfile cambierà anche la rispettiva immagine.

Quindi, se dovessi aggiungere un livello all'immagine, puoi semplicemente aggiungere un'altra istruzione Dockerfile, per rimuoverne uno rimuoveresti una linea e per cambiare un livello, cambieresti la linea di conseguenza.

Esistono due modi per utilizzare un Dockerfile per modificare un'immagine.

  1. Utilizzare l'immagine che desideri modificare come immagine di base e creare un'immagine figlio.
  2. Modifica del Dockerfile effettivo dell'immagine che desideri modificare.

Lascia che ti spieghi quale metodo dovrebbe essere usato quando e come.

1. Utilizzo di un'immagine come immagine di base

Questo è quando prendi l'immagine che desideri modificare e aggiungi livelli ad essa per creare una nuova immagine figlio. A meno che un'immagine non sia creata da zero, ogni immagine è una modifica alla stessa immagine di base principale.

Considera il precedente Dockerfile. Supponiamo che la build dell'immagine da quell'immagine sia denominata dummy:0.1 . Ora, se dovessi pensare che ora ho bisogno di usare Perl invece di Python3 per stampare "Hello World", ma non voglio nemmeno rimuovere Python3, potrei semplicemente usare dummy:0.1 image come immagine di base (poiché Python3 è già presente) e costruisci da quella come segue

FROM dummy:0.1

RUN apk add --no-cache perl

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

Qui sto costruendo sopra dummy:0.1 , aggiungendo più livelli come ritengo opportuno.

Questo metodo non sarà molto utile se la tua intenzione è quella di modificare o eliminare un livello esistente. Per questo, devi seguire il metodo successivo.

2. Modifica del Dockerfile dell'immagine

Poiché i livelli esistenti di un'immagine sono di sola lettura, non è possibile modificarli direttamente tramite un nuovo Dockerfile. Con il FROM comando in un Dockerfile, prendi un'immagine come base e costruisci su su o aggiungi livelli ad esso.

Alcune attività potrebbero richiederci di modificare un livello esistente, anche se puoi farlo usando il metodo precedente con un mucchio di contraddittori RUN istruzioni (come eliminare file, rimuovere/sostituire i pacchetti aggiunti in qualche livello precedente), non è una soluzione ideale o quella che consiglierei. Perché aggiunge livelli aggiuntivi e aumenta notevolmente le dimensioni dell'immagine.

Un metodo migliore sarebbe non utilizzare l'immagine come immagine di base, ma modificare l'effettivo Dockerfile di quell'immagine. Considera ancora il precedente Dockerfile, e se non dovessi mantenere Python3 in quell'immagine e sostituire il pacchetto Python3 e il comando con quelli Perl?

Se seguendo il metodo precedente avrei dovuto creare un nuovo Dockerfile in questo modo -

FROM dummy:0.1

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

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

Se creato, ci saranno un totale di cinque livelli in questa immagine.

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

Inoltre, la dimensione dell'immagine è 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

Ora invece di farlo, prendi il Dockerfile iniziale e cambia quelli di Python3 in Perl in questo modo

FROM alpine:latest

RUN apk add --no-cache perl

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

Il numero di livelli è stato ridotto a 3 e la dimensione ora è 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

Immagine modificata correttamente.

Il metodo precedente è più utile quando vuoi semplicemente aggiungere livelli sopra quelli esistenti, ma non è molto utile quando provi a modificare i livelli esistenti come eliminarne uno, sostituirne uno, riordinare quelli esistenti e presto. È qui che brilla questo metodo.

Metodo 2:modifica dell'immagine tramite docker commit

C'è un altro metodo in cui puoi scattare un'istantanea di un container in esecuzione e trasformarlo in un'immagine a sé stante.

Costruiamo un dummy:0.1 immagine identica, ma questa volta senza utilizzare un Dockerfile. Dato che ho usato alpine:latest come dummy:0.1 's base, fai girare un contenitore di quell'immagine.

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

Ora all'interno del contenitore, aggiungi il pacchetto Python3, apk add --no-cache python3 . Una volta terminato, apri una nuova finestra di terminale ed esegui il seguente comando (o qualcosa di simile)

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

Con il --change flag Sto aggiungendo un'istruzione Dockerfile al nuovo dummy:04 immagine (in questo caso, il ENTRYPOINT istruzioni).

Con il docker container commit comando, fondamentalmente converti il ​​livello r/w più esterno in un livello r/o, lo aggiungi ai livelli dell'immagine esistente e crei una nuova immagine. Questo metodo è più intuitivo/interattivo, quindi potresti voler usarlo al posto di Dockerfiles, ma capisci che non è molto riproducibile. Inoltre, le stesse regole si applicano alla rimozione o alla modifica di qualsiasi livello esistente, aggiungere un livello solo per rimuovere qualcosa o modificare qualcosa fatto in un livello precedente non è l'idea migliore, almeno nella maggior parte dei casi.

Questo conclude questo articolo. Spero che questo ti sia stato utile, se hai qualche domanda, commenta qui sotto.


Docker
  1. Come spostare le immagini Docker tra host

  2. Come ridurre le dimensioni dell'immagine Docker:6 metodi di ottimizzazione

  3. Come utilizzare un Dockerfile per creare un'immagine Docker

  4. Come imballare e trasferire immagini Docker da un server all'altro

  5. Come eseguire il commit delle modifiche a un'immagine Docker

Come aggiornare le immagini Docker all'ultima versione

Come utilizzare Docker Commit per modificare le immagini del contenitore

Guida completa per la rimozione delle immagini Docker

Come creare un'immagine Docker personalizzata con Dockerfile

Condivisione di immagini Docker su Docker Hub

Come elencare / cercare / estrarre le immagini della finestra mobile su Linux