Questa è la prima parte di una serie in due parti su come lavorare con i contenitori Docker. In questa parte, ci concentreremo sui molti modi e opzioni per eseguire un'immagine e su come l'host può interagire con un contenitore Docker.
Nella seconda parte vedremo l'elenco, l'avvio, l'arresto e il riavvio dei contenitori, nonché l'esecuzione di comandi sui container in esecuzione. Le immagini Docker sono le unità di distribuzione. Quando si esegue un'immagine, si crea un'istanza di un contenitore Docker che esegue un singolo processo nel proprio ambiente isolato per il file system, la rete e l'albero dei processi.
I contenitori Docker sono molto flessibili e consentono molti casi d'uso troppo pesanti, complessi e / o costosi con altre tecnologie come macchine virtuali e server bare metal.
Prima di iniziare, assicurati che Docker sia installato correttamente nel tuo ambiente. A seconda di come è installato e dell'utente, potrebbe essere necessario eseguirlo come sudo. Salterò il sudo.
Si avvia un contenitore Docker eseguendo un'immagine. Esistono diversi modi per eseguire un contenitore che influiscono sulla facilità con cui è possibile gestire tutti i contenitori. All'avvio del contenitore, in genere viene eseguito il comando definito nel file Docker. Ecco il Dockerfile per il contenitore hello-world:
DA zero COPIA ciao / CMD ["/ ciao"]
Il comando esegue semplicemente il file binario "ciao" che è stato copiato nella radice del contenitore durante la creazione dell'immagine.
Un contenitore può essere eseguito in primo piano dove si blocca fino a quando il processo non termina e il contenitore smette di funzionare. In modalità primo piano, il contenitore stampa l'output sulla console e può leggere l'input standard. In modalità distaccata (quando si fornisce il flag -d), il controllo ritorna immediatamente e il contenitore
Il modo più semplice per eseguire un contenitore è: run docker
.
Quando si esegue un contenitore utilizzando questo comando, Docker assegnerà un nome composto da due parole casuali. Per esempio: finestra mobile eseguire hello-world
.
Se hai già l'immagine ciao-mondo, Docker la eseguirà. Se non lo fai, lo estrarrà dal DockerHub del repository Docker ufficiale e poi lo eseguirà. L'output dovrebbe essere simile a:
Ciao da Docker! Questo messaggio mostra che l'installazione sembra funzionare correttamente. Per generare questo messaggio, Docker ha compiuto i seguenti passaggi: 1. Il client Docker ha contattato il daemon Docker. 2. Il demone Docker ha estratto l'immagine "ciao-mondo" dall'hub Docker. 3. Il demone Docker ha creato un nuovo contenitore da quell'immagine che esegue l'eseguibile che produce l'output che stai leggendo attualmente. 4. Il daemon Docker ha trasmesso in streaming quell'output al client Docker, che lo ha inviato al terminale. Per provare qualcosa di più ambizioso, puoi eseguire un contenitore Ubuntu con: $ docker run -it ubuntu bash Condividi immagini, automatizza i flussi di lavoro e altro con un Docker ID gratuito: https://cloud.docker.com/ Per altri esempi e idee, visita: https://docs.docker.com/engine/userguide/
Il programma Hello viene chiuso dopo la visualizzazione del messaggio, che termina il processo in esecuzione all'interno del contenitore e termina l'esecuzione del contenitore. Il contenitore si attacca ancora nel caso in cui si desideri connettersi ad esso, esaminare i registri o qualsiasi altra cosa. Per visualizzare il contenitore, è possibile eseguire il seguente comando:
docker ps -a --format "table .ID \ t . Status \ t . Names" CONTAINER ID STATUS NAMES 8e2e491accb5 Uscito (0) 2 minuti fa clever_liskov
Spiegherò in seguito come elencare i contenitori e tutte le opzioni pertinenti. Per ora, concentriamoci sulla sezione Nomi. Docker ha generato automaticamente il nome "clever_liskov", e dovrò usarlo o l'ID del contenitore per fare riferimento a questo contenitore per qualsiasi scopo come riavviarlo, rimuoverlo o eseguire un comando.
L'utilizzo di ID contenitore o di nomi generati automaticamente a volte è inopportuno. Se si interagisce spesso con un contenitore che si ricrea frequentemente, otterrà un ID diverso e un nome generato automaticamente. Inoltre, il nome sarà casuale.
Docker ti consente di assegnare un nome ai contenitori quando li esegui fornendo un "--name finestra mobile run --name ciao-mondo ciao-mondo
.
Ora, se guardiamo al processo (ho rimosso clever_liskov in precedenza) vedremo che il contenitore è denominato ciao-mondo:
finestra mobile ps -a --format "table .ID \ t . Names" NOME ID CONTENITORE f6fe77b3b6e8 ciao-mondo
Esistono numerosi vantaggi in un contenitore denominato:
Diamo un'occhiata all'ultima opzione. Se provo a eseguire nuovamente lo stesso comando di esecuzione con lo stesso nome "ciao-mondo", viene visualizzato un messaggio di errore chiaro:
docker run --name hello-world hello-world docker: Risposta di errore da demone: Conflict. Il nome del contenitore "/ hello-world" è già in uso dal contenitore f6fe77b3b6e8e77ccf346c32c599e67b2982893ca39f0415472c2949cacc4a51. Devi rimuovere (o rinominare) quel contenitore per poter riutilizzare quel nome. Vedi 'finestra mobile run --help'.
I contenitori restano bloccati per impostazione predefinita. A volte, non ne hai bisogno. Invece di rimuovere manualmente i contenitori usciti, fai in modo che il contenitore vada via da solo. Il --rm
l'argomento della riga di comando fa il trucco: finestra mobile run --rm hello-world
.
Per impostazione predefinita, Docker esegue il comando specificato nel file Docker utilizzato per creare l'immagine (o direttamente il punto di ingresso se non viene trovato alcun comando). Puoi sempre sostituirlo fornendo il tuo comando alla fine del comando di esecuzione. Corriamo ls -la
sul busybox immagine (il Ciao mondo l'immagine ha no ls
eseguibile):
finestra mobile run busybox ls -la totale 44 drwxr-xr-x 18 root root 4096 mar 18 17:06. drwxr-xr-x 18 root root 4096 mar 18 17: 06 ... -rwxr-xr-x 1 root root 0 mar 18 17:06 .dockerenv drwxr-xr-x 2 root root 12288 mar 9 00:05 bin drwxr-xr -x 5 root root 340 mar 18 17:06 dev drwxr-xr-x 2 root root 4096 mar 18 17:06 etc drwxr-xr-x 2 nessuno nogroup 4096 mar 9 00:05 home dr-xr-xr-x 85 radice radice 0 mar 18 17:06 proc drwxr-xr-x 2 radice radice 4096 mar 9 00:05 radice dr-xr-xr-x 13 radice radice 0 mar 18 17:06 sys drwxrwxrwt 2 root root 4096 mar 9 00: 05 tmp drwxr-xr-x 3 root root 4096 mar 9 00:05 usr drwxr-xr-x 4 root root 4096 mar 9 00:05 var
I contenitori Docker gestiscono processi isolati nel loro piccolo mondo. Ma spesso è necessario e utile fornire l'accesso all'host.
I contenitori Docker non ereditano automaticamente l'ambiente del processo host che li ha eseguiti. È necessario fornire esplicitamente variabili di ambiente al contenitore quando lo si esegue utilizzando -e
flag della riga di comando. È possibile passare più variabili d'ambiente. Ecco un esempio:
finestra mobile run --rm -it -e ENV_FROM_HOST = "123" busybox / # env HOSTNAME = 8e7672bce5a7 SHLVL = 1 HOME = / root ENV_FROM_HOST = 123 TERM = xterm PERCORSO = / usr / local / sbin: / usr / local / bin: / usr / sbin: / usr / bin: / sbin: / bin PWD = / / #
La prima riga esegue il contenitore busybox, passandogli il ENV_FROM_HOST variabile e quindi all'interno del contenitore in esecuzione ENV
mostra che il ENV_FROM_HOST è impostato correttamente.
È anche possibile utilizzare le variabili di ambiente host. Imposta un paio di variabili di ambiente host e le utilizza nel comando di esecuzione:
$ export VAR_1 = 1 $ export VAR_2 = 2 $ esecuzione docker --rm -it -e VAR_1 = "$ VAR_1" -e VAR_2 = "$ VAR_2" busybox
All'interno del contenitore, sono ora visibili:
/ # env | grep VAR VAR_1 = 1 VAR_2 = 2
Una delle interazioni più utili è il montaggio delle directory host. Ciò consente diversi casi d'uso interessanti:
Qui creo un file sull'host: $ echo "Sì, funziona!" > ~ / data / 1.txt
Quindi eseguo il busybox immagine che monta il ~ / directory dei dati a /dati nel contenitore e visualizzando il contenuto del file sullo schermo:
$ docker run --rm -v ~ / data: / data busybox cat /data/1.txt Sì, funziona!
Ho usato il cat /data/1.txt
comando qui.
Se esponi una porta nel tuo Dockerfile usando ESPORRE, sarà accessibile solo ad altri container docker. Per renderlo accessibile sull'host, è necessario utilizzare il -p
argomento della riga di comando. La sintassi è -p
.
Qui è in esecuzione il nginx immagine, che espone la porta 80 e utilizza il -p
argomento della riga di comando per renderlo visibile sull'host sulla porta 9000:
finestra mobile run --name nginx --rm -d -p 9000: 80 nginx
Si noti che a differenza dei comandi precedenti che eseguivano alcune attività e completate, il contenitore nginx continuerà a funzionare e ad ascoltare le richieste in arrivo. Verifichiamo che nginx sia realmente attivo e in esecuzione e risponda alle richieste sulla porta 9000. Preferisco l'eccellente client HTTP httpie a curvatura per colpire server e servizi Web dalla riga di comando:
http HEAD localhost: 9000 HTTP / 1.1 200 OK Accetta-Ranges: byte Connessione: keep-alive Content-Length: 612 Content-Type: text / html Data: Sun, 19 Mar 2017 07:35:55 GMT ETag: "58a323e4- 264 "Last-Modified: Tue, 14 Feb 2017 15:36:04 GMT Server: nginx / 1.11.10
Esistono molti modi per eseguire un'immagine Docker per creare un contenitore e ci sono molte opzioni. Ogni combinazione supporta un uso particolare. È molto utile quando si lavora con i contenitori Docker per afferrare completamente i dettagli e utilizzare il metodo migliore per avviare i contenitori.
Inoltre, il collegamento dei volumi host e delle porte di esposizione e pubblicazione consente una stretta integrazione con l'host e una pletora di scenari di utilizzo. Nella seconda parte ci immergeremo nella gestione di una serie di contenitori e sfrutteremo la potenza offerta da Docker.