Qual è la differenza tra un'immagine Docker e un contenitore?



Answers

Dal mio articolo su Automatizzare le distribuzioni Docker :

Immagini di Docker e contenitori

In Dockerland, ci sono immagini e ci sono contenitori . I due sono strettamente correlati, ma distinti. Per me, cogliere questa dicotomia ha chiarito immensamente Docker.

Cos'è un'immagine?

Un'immagine è un file inerte, immutabile, essenzialmente un'istantanea di un contenitore. Le immagini vengono create con il comando build e produrranno un contenitore una volta avviato con run . Le immagini sono memorizzate in un registro Docker come registry.hub.docker.com . Poiché possono diventare piuttosto grandi, le immagini sono progettate per essere composte da strati di altre immagini, consentendo di inviare una quantità minima di dati durante il trasferimento delle immagini sulla rete.

Le immagini locali possono essere elencate eseguendo le 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:

  1. L'ID immagine è i primi 12 caratteri dell'identificatore vero per un'immagine. Puoi creare molti tag di una determinata immagine, ma i loro ID saranno tutti uguali (come sopra).
  2. VIRTUAL SIZE è virtuale perché sommando le dimensioni di tutti i diversi livelli sottostanti. Ciò significa che la somma di tutti i valori in quella colonna è probabilmente molto più grande dello spazio su disco utilizzato da tutte quelle immagini.
  3. Il valore nella colonna REPOSITORY deriva dal flag -t del comando di docker build , o dal docker tag -ing un'immagine esistente. Sei libero di taggare le immagini usando una nomenclatura che ha senso per te, ma sappi che la finestra mobile userà il tag come posizione del registro in una docker push docker pull o in una docker push docker pull .
  4. La forma completa di un tag è [REGISTRYHOST/][USERNAME/]NAME[:TAG] . Per ubuntu sopra, REGISTRYHOST è dedotto per essere registry.hub.docker.com . Pertanto, se si prevede di archiviare l'immagine denominata my-application in un registro su docker.example.com , è necessario contrassegnare tale immagine docker.example.com/my-application .
  5. La colonna TAG è solo la parte [: TAG] del tag completo . Questa è una sfortunata terminologia.
  6. L' latest tag non è magico, è semplicemente il tag predefinito quando non si specifica un tag.
  7. Puoi avere immagini senza tag identificabili solo con i loro ID IMAGE. Questi otterranno il <none> TAG e REPOSITORY. È facile dimenticarsene.

Maggiori informazioni sulle immagini sono disponibili nei documenti e nel glossary Docker .

Cos'è un contenitore?

Per usare una metafora di programmazione, se un'immagine è una classe, un contenitore è un'istanza di una classe, un oggetto runtime. I contenitori si spera che tu stia usando Docker; sono incapsulamenti leggeri e portatili di un ambiente in cui eseguire le applicazioni.

Visualizza 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 eseguo una versione ancorata del registro docker, in modo da avere un luogo privato in cui archiviare le mie immagini. Ancora una volta, alcune cose da notare:

  1. Come l'ID immagine, l'ID CONTENITORE è l'identificatore vero per il contenitore. Ha la stessa forma, ma identifica un diverso tipo di oggetto.
  2. docker ps emette solo contenitori in esecuzione . È possibile visualizzare tutti i contenitori (in esecuzione o arrestati ) con la docker ps -a .
  3. I NAMES possono essere utilizzati per identificare un container avviato tramite il flag --name .

Come evitare l'accumulo di immagini e contenitori?

Una delle mie prime frustrazioni con Docker era l' accumulo apparentemente costante di immagini prive di tag e contenitori bloccati . In una manciata di occasioni questo accumulo ha provocato un esaurimento dei dischi rigidi che ha rallentato il mio laptop o bloccato la mia pipeline di build automatizzata. Parla di "contenitori ovunque"!

Possiamo rimuovere tutte le immagini senza docker rmi combinando la docker rmi con la query dangling=true recente:

docker images -q --filter "dangling=true" | xargs docker rmi

Docker non sarà in grado di rimuovere le immagini che si trovano dietro container esistenti, quindi potrebbe essere necessario rimuovere prima i contenitori con docker rm :

docker rm `docker ps --no-trunc -aq`

Questi sono noti punti dolenti con Docker e potrebbero essere risolti in versioni future. Tuttavia, con una chiara comprensione di immagini e contenitori, queste situazioni possono essere evitate con un paio di pratiche:

  1. Rimuovi sempre un contenitore inutile e fermato con la docker rm [CONTAINER_ID] .
  2. Rimuovi sempre l'immagine dietro un contenitore inutile e fermato con la docker rmi [IMAGE_ID] .
Question

Quando utilizzi la finestra mobile, iniziamo con un'immagine di base. Lo avviamo, creiamo le modifiche e quelle modifiche vengono salvate nei livelli formando un'altra immagine.

Così alla fine ho un'immagine per il mio Postgres e un'immagine per la mia app Web, modifiche alle quali continuo ad essere persistente.

Quindi la domanda è: che cos'è un contenitore?




Un contenitore è solo un binario eseguibile che deve essere eseguito dal sistema operativo host in base a una serie di restrizioni preimpostate mediante un'applicazione (ad esempio, finestra mobile) che sa come indicare al sistema operativo quali restrizioni applicare.

Le restrizioni tipiche sono legate all'isolamento del processo, alla sicurezza (come l'uso della protezione SELinux) e alle risorse di sistema (memoria, disco, CPU, rete).

Fino a poco tempo fa, solo i kernel nei sistemi basati su Unix supportavano la possibilità di eseguire file eseguibili sotto severe restrizioni. Questo è il motivo per cui la maggior parte dei talk container oggi riguarda principalmente Linux o altre distribuzioni Unix.

Docker è una di quelle applicazioni che sa dire al sistema operativo (principalmente Linux) quali restrizioni eseguire un eseguibile sotto. L'eseguibile è contenuto nell'immagine Docker, che è solo un tarfile. Questo eseguibile è solitamente una versione ridotta di una distribuzione Linux (Ubuntu, centos, Debian ecc.) Preconfigurata per eseguire una o più applicazioni all'interno.

Sebbene la maggior parte delle persone utilizzi una base Linux come eseguibile, può essere qualsiasi altra applicazione binaria purché il sistema operativo host possa eseguirla. (vedere la creazione di una semplice immagine di base usando scratch ). Se il file binario nell'immagine docker è un sistema operativo o semplicemente un'applicazione, per l'host del sistema operativo è solo un altro processo, un processo contenuto governato da limiti predefiniti del sistema operativo.

Altre applicazioni che, come Docker, possono dire al SO host quali limiti applicare a un processo mentre è in esecuzione includono LXC , libvirt e systemd . Docker utilizzava queste applicazioni per interagire indirettamente con il SO Linux, ma ora Docker interagisce direttamente con Linux usando la sua libreria chiamata " libcontainer ".

Quindi i contenitori sono solo processi in esecuzione in una modalità limitata, simile a ciò che era solito fare chroot .

IMO ciò che distingue Docker da qualsiasi altra tecnologia dei contenitori è il suo repository (Docker Hub) ei relativi strumenti di gestione che rendono estremamente facile il lavoro con i contenitori.

Vedi https://en.m.wikipedia.org/wiki/Docker_(Linux_container_engine)




flusso di lavoro

Ecco il flusso di lavoro end-to-end che mostra i vari comandi e i relativi input e output associati. Questo dovrebbe chiarire la relazione tra un'immagine e un contenitore.

+------------+  docker build   +--------------+  docker run -dt   +-----------+  docker exec -it   +------+
| Dockerfile | --------------> |    Image     | --------------->  | Container | -----------------> | Bash |
+------------+                 +--------------+                   +-----------+                    +------+
                                 ^
                                 | docker pull
                                 |
                               +--------------+
                               |   Registry   |
                               +--------------+

Per elencare le immagini che potresti eseguire, esegui:

docker image ls

Per elencare i contenitori è possibile eseguire comandi su:

docker ps



Come nell'aspetto della programmazione,

L'immagine è un codice sorgente.

Quando il codice sorgente è compilato e compilato, viene chiamato come applicazione.

Simillar a quello "quando l'istanza viene creata per l'immagine", viene chiamata " contenitore "




Dockerfile è come il tuo script bash che produce un tarball (immagine Docker).

I contenitori Docker sono come la versione estratta del tarball. Puoi avere tutte le copie che vuoi in diverse cartelle (i contenitori)




Forse spiegare l'intero flusso di lavoro può aiutare.

Tutto inizia con il Dockerfile . Il Dockerfile è il codice sorgente dell'immagine.

Una volta creato il Dockerfile, lo costruisci per creare l' immagine del contenitore. L'immagine è solo la "versione compilata" del "codice sorgente" che è il Dockerfile.

Una volta che hai l'immagine del contenitore, dovresti ridistribuirla usando il registro . Il registro è come un repository git: puoi spingere e tirare le immagini.

Successivamente, è possibile utilizzare l'immagine per eseguire i contenitori . Un contenitore in esecuzione è molto simile, in molti aspetti, a una macchina virtuale (ma senza l' hypervisor ).

Questo post spiega molte cose di base sui container docker (si tratta di Docker e Puppet, ma ci sono molti concetti che possono essere usati in qualsiasi contesto)




Dockerfile > (Build)> Immagine > (Esegui)> Contenitore .

  • Dockerfile : contiene una serie di istruzioni della finestra mobile che fornisce il sistema operativo nel modo che preferisci e installa / configura tutti i tuoi software.

  • Immagine : Dockerfile compilato. Risparmia tempo dalla ricostruzione del Dockerfile ogni volta che è necessario eseguire un contenitore. Ed è un modo per nascondere il codice di fornitura.

  • Contenitore : il sistema operativo virtuale stesso, puoi eseguirlo in ssh ed eseguire tutti i comandi che desideri, come se fosse un ambiente reale. Puoi eseguire oltre 1000 contenitori dalla stessa immagine.




Un'immagine Docker racchiude l'applicazione e l'ambiente richiesti dall'applicazione per l'esecuzione e un contenitore è un'istanza in esecuzione dell'immagine.

Le immagini sono la parte di imballaggio della finestra mobile, analoga a "codice sorgente" o "programma". I contenitori sono la parte di esecuzione della finestra mobile, analoga a un "processo".

Nella domanda, si fa riferimento solo alla parte "programma" e questa è l'immagine. La parte "in esecuzione" della finestra mobile è il contenitore. Quando viene eseguito un contenitore e vengono apportate modifiche, è come se il processo eseguisse una modifica nel proprio codice sorgente e lo salvasse come nuova immagine.




Links