Quando si usa Docker, si inizia con un'immagine di base. La avviamo, creiamo dei cambiamenti e questi cambiamenti vengono salvati in strati che formano un'altra immagine.
Così alla fine ho un'immagine per la mia istanza PostgreSQL e un'immagine per la mia applicazione web, le cui modifiche continuano ad essere persistite.
Cos'è un contenitore?
Un'istanza di un'immagine è chiamata contenitore. Avete un'immagine, che è un insieme di livelli come descritto. Se si avvia questa immagine, si ha un contenitore in esecuzione di questa immagine. Potete avere molti container in esecuzione della stessa immagine.
Puoi vedere tutte le tue immagini con docker images
mentre puoi vedere i tuoi container in esecuzione con docker ps
(e puoi vedere tutti i container con docker ps -a
).
Quindi un'istanza in esecuzione di un'immagine è un contenitore.
Dal mio articolo su Automating Docker Deployments:
In Dockerland, ci sono immagini e ci sono contenitori. I due sono strettamente correlati, ma distinti. Per me, afferrare questa dicotomia ha chiarito Docker immensamente.
Un'immagine è un file inerte, immutabile, che è essenzialmente un'istantanea di un contenitore. Le immagini sono create con il comando build, e produrranno un contenitore quando avviato con run. Le immagini sono memorizzate in un registro Docker come registry.hub.docker.com. Poiché possono diventare abbastanza grandi, le immagini sono progettate per essere composte da strati di altre immagini, permettendo una quantità minima di dati da inviare quando si trasferiscono le immagini in rete.
Le immagini locali possono essere elencate eseguendo docker images
:
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 13.10 5e019ab7bf6d 2 months ago 180 MB
ubuntu 14.04 99ec81b80c55 2 months ago 266 MB
ubuntu latest 99ec81b80c55 2 months ago 266 MB
ubuntu trusty 99ec81b80c55 2 months ago 266 MB
<none> <none> 4ab0d9120985 3 months ago 486.5 MB
Alcune cose da notare:__
-t
del comando docker build
, o dal docker tag
-ing di un'immagine esistente. Sei libero di etichettare le immagini usando una nomenclatura che ha senso per te, ma sappi che docker userà il tag come posizione del registro in un docker push
o docker pull
.[REGISTRYHOST/][USERNAME/]NAME[:TAG]
. Per ubuntu
sopra, REGISTRYHOST è dedotto essere registry.hub.docker.com
. Quindi, se avete intenzione di memorizzare la vostra immagine chiamata my-application
in un registro su docker.example.com
, dovreste assegnare a quell'immagine il tag docker.example.com/my-application
.latest
non è magico, è semplicemente il tag di default quando non si specifica un tag.<none>
TAG e REPOSITORY. È facile dimenticarsi di loro.Maggiori informazioni sulle immagini sono disponibili nella documentazione Docker e nel glossario.
Per usare una metafora di programmazione, se un'immagine è una classe, allora un contenitore è un'istanza di una classe, un oggetto runtime. Si spera che i contenitori siano il motivo per cui stai usando Docker; sono incapsulamenti leggeri e portatili di un ambiente in cui eseguire applicazioni.
Visualizza i contenitori locali in esecuzione con docker ps
:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2ff1af05450 samalba/docker-registry:latest /bin/sh -c 'exec doc 4 months ago Up 12 weeks 0.0.0.0:5000->5000/tcp docker-registry
Qui sto eseguendo una versione dockerizzata del registro docker, in modo da avere un posto privato per memorizzare le mie immagini. Di nuovo, alcune cose da notare:
docker ps
mostra solo i container running. È possibile visualizzare tutti i contenitori (running o stopped) con docker ps -a
.--name
.Una delle mie prime frustrazioni con Docker era l'accumulo apparentemente costante di immagini non taggate e container fermi. In una manciata di occasioni questo accumulo si è tradotto in dischi rigidi esauriti che hanno rallentato il mio portatile o fermato la mia pipeline di compilazione automatica. Parliamo di "contenitori ovunque"!
Possiamo rimuovere tutte le immagini non taggate combinando docker rmi
con la recente query dangling=true
:
docker images -q --filtro "dangling=true" | xargs docker rmi
.
Docker non sarà in grado di rimuovere le immagini che sono dietro i contenitori esistenti, quindi potrebbe essere necessario rimuovere prima i contenitori fermi con docker rm
:
docker rm `docker ps --no-trunc -aq`
Questi sono punti dolenti noti con Docker e potrebbero essere affrontati nelle versioni future. Tuttavia, con una chiara comprensione delle immagini e dei contenitori, queste situazioni possono essere evitate con un paio di pratiche:
docker rm [CONTAINER_ID]
.docker rmi [IMAGE_ID]
.Anche se è più semplice pensare a un contenitore come a un'immagine in esecuzione, questo non è del tutto accurato.
Un'immagine è in realtà un modello che può essere trasformato in un contenitore. Per trasformare un'immagine in un contenitore, il motore Docker prende l'immagine, aggiunge un filesystem in lettura-scrittura sopra e inizializza varie impostazioni tra cui le porte di rete, il nome del contenitore, l'ID e i limiti delle risorse. Un contenitore in esecuzione ha un processo attualmente in esecuzione, ma un contenitore può anche essere fermato (o exited nella terminologia di Docker). Un container in uscita non è la stessa cosa di un'immagine, in quanto può essere riavviato e manterrà le sue impostazioni e qualsiasi modifica al filesystem.