Introduzione
Docker è un popolare strumento di containerizzazione utilizzato per fornire alle applicazioni software un filesystem che contiene tutto ciò di cui hanno bisogno per essere eseguite. L'utilizzo dei container Docker garantisce che il software si comporti allo stesso modo indipendentemente da dove viene distribuito, poiché il suo ambiente di runtime è coerente.
In generale, i contenitori Docker sono temporanei e funzionano solo per il tempo necessario al completamento del comando emesso nel contenitore. A volte, tuttavia, le applicazioni devono condividere l'accesso ai dati o rendere persistenti i dati dopo l'eliminazione di un contenitore. Database, contenuto generato dagli utenti per un sito Web e file di registro sono solo alcuni esempi di dati che è poco pratico o impossibile includere in un'immagine Docker ma a cui le applicazioni devono accedere. L'accesso permanente ai dati è fornito con Docker Volumes.
I volumi Docker possono essere creati e allegati nello stesso comando che crea un contenitore, oppure possono essere creati indipendentemente da qualsiasi contenitore e allegati in un secondo momento. In questo articolo, esaminerai quattro modi diversi per condividere i dati tra contenitori.
Prerequisiti
Per seguire questo articolo, avrai bisogno di un server Ubuntu 22.04 con quanto segue:
- Un utente non root con privilegi sudo. La guida alla configurazione iniziale del server con Ubuntu 22.04 spiega come configurarla.
- Docker installato con le istruzioni del Passaggio 1 e Passaggio 2 di Come installare e utilizzare Docker su Ubuntu 22.04
Nota: Anche se i Prerequisiti forniscono istruzioni per l'installazione di Docker su Ubuntu 22.04, la docker
i comandi per i volumi di dati Docker in questo articolo dovrebbero funzionare su altri sistemi operativi purché Docker sia installato e l'utente sudo sia stato aggiunto alla docker
gruppo.
Fase 1:creazione di un volume indipendente
Introdotto nella versione 1.9 di Docker, il docker volume create
Il comando permette di creare un volume senza metterlo in relazione con nessun contenitore particolare. Utilizzerai questo comando per aggiungere un volume denominato DataVolume1
:
- docker volume create --name DataVolume1
Viene visualizzato il nome, che indica che il comando è andato a buon fine:
OutputDataVolume1
Per utilizzare il volume, creerai un nuovo contenitore dall'immagine di Ubuntu, usando il --rm
flag per eliminarlo automaticamente quando esci. Utilizzerai anche -v
per montare il nuovo volume. -v
richiede il nome del volume, due punti, quindi il percorso assoluto in cui il volume dovrebbe apparire all'interno del contenitore. Se le directory nel percorso non esistono come parte dell'immagine, verranno create quando viene eseguito il comando. Se lo fanno esiste, il volume montato nasconderà il contenuto esistente:
- docker run -ti --rm -v DataVolume1:/datavolume1 ubuntu
Mentre sei nel contenitore, scrivi alcuni dati nel volume:
- echo "Example1" > /datavolume1/Example1.txt
Perché hai usato il --rm
flag, il tuo container verrà automaticamente eliminato quando esci. Il tuo volume, tuttavia, sarà ancora accessibile.
- exit
Puoi verificare che il volume sia presente sul tuo sistema con docker volume inspect
:
- docker volume inspect DataVolume1
Output[
{
"CreatedAt": "2018-07-11T16:57:54Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/DataVolume1/_data",
"Name": "DataVolume1",
"Options": {},
"Scope": "local"
}
]
Nota: Puoi anche guardare i dati sull'host nel percorso indicato come Mountpoint
. Dovresti evitare di alterarlo, tuttavia, poiché può causare il danneggiamento dei dati se le applicazioni o i contenitori non sono a conoscenza delle modifiche.
Quindi, avvia un nuovo contenitore e allega DataVolume1
:
- docker run --rm -ti -v DataVolume1:/datavolume1 ubuntu
Verifica i contenuti:
- cat /datavolume1/Example1.txt
OutputExample1
Esci dal contenitore:
- exit
In questo esempio, hai creato un volume, l'hai collegato a un contenitore e ne hai verificato la persistenza.
Fase 2:creazione di un volume che persiste quando il container viene rimosso
Nell'esempio successivo, creerai un volume contemporaneamente al contenitore, eliminerai il contenitore, quindi allegherai il volume a un nuovo contenitore.
Utilizzerai docker run
comando per creare un nuovo contenitore usando l'immagine di base di Ubuntu. -t
ci darà un terminale e -i
ci permetterà di interagire con esso. Per chiarezza, utilizzerai --name
per identificare il contenitore.
Il -v
flag ci permetterà di creare un nuovo volume, che chiamerai DataVolume2
. Utilizzerai i due punti per separare questo nome dal percorso in cui il volume deve essere montato nel contenitore. Infine, specificherai l'immagine di base di Ubuntu e ti baserai sul comando predefinito nel file Docker dell'immagine di base di Ubuntu, bash
, per farci cadere in una shell:
- docker run -ti --name=Container2 -v DataVolume2:/datavolume2 ubuntu
Nota: Il -v
bandiera è molto flessibile. Può effettuare il binding o assegnare un nome a un volume con una leggera regolazione della sintassi. Se il primo argomento inizia con un /
o ~/
stai creando un bindmount. Rimuovilo e stai nominando il volume. Ad esempio:
-v /path:/path/in/container
monta la directory host,/path
nel/path/in/container
-v path:/path/in/container
crea un volume denominatopath
senza alcuna relazione con l'host.
Per ulteriori informazioni sul binding di una directory dall'host, vedere Come condividere i dati tra un contenitore Docker e l'host
Mentre sei nel contenitore, scriverai alcuni dati nel volume:
- echo "Example2" > /datavolume2/Example2.txt
- cat /datavolume2/Example2.txt
OutputExample2
Esci dal contenitore:
- exit
Quando riavvii il contenitore, il volume verrà montato automaticamente:
- docker start -ai Container2
Verifica che il volume sia effettivamente montato e che i tuoi dati siano ancora in posizione:
- cat /datavolume2/Example2.txt
OutputExample2
Infine, esci e ripulisci:
- exit
Docker non ci consentirà di rimuovere un volume se è referenziato da un contenitore. Per vedere cosa succede, prova:
- docker volume rm DataVolume2
Il messaggio ci dice che il volume è ancora in uso e fornisce la versione lunga dell'ID contenitore:
OutputError response from daemon: unable to remove volume: remove DataVolume2: volume is in use - [d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63]
Puoi utilizzare l'ID nel messaggio di errore sopra riportato per rimuovere il contenitore:
- docker rm d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
Outputd0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
La rimozione del contenitore non influirà sul volume. Puoi vedere che è ancora presente sul sistema elencando i volumi con docker volume ls
:
- docker volume ls
OutputDRIVER VOLUME NAME
local DataVolume2
E puoi usare docker volume rm
per rimuoverlo:
- docker volume rm DataVolume2
In questo esempio, hai creato un volume di dati vuoto nello stesso momento in cui hai creato un contenitore. Nel tuo prossimo esempio esplorerai cosa succede quando crei un volume con una directory contenitore che contiene già dati.
Passaggio 3:creazione di un volume da una directory esistente con dati
In genere, creare un volume in modo indipendente con docker volume create
e crearne uno durante la creazione di un contenitore sono equivalenti, con un'eccezione. Se crei un volume contemporaneamente crei un contenitore e fornisci il percorso a una directory che contiene dati nell'immagine di base, tali dati verranno copiati nel volume.
Ad esempio, creerai un contenitore e aggiungerai il volume di dati in /var
, una directory che contiene dati nell'immagine di base:
- docker run -ti --rm -v DataVolume3:/var ubuntu
Tutto il contenuto dell'immagine di base /var
viene copiata nel volume e puoi montare quel volume in un nuovo contenitore.
Esci dal contenitore corrente:
- exit
Questa volta, invece di fare affidamento sul bash
predefinito dell'immagine di base comando, emetterai il tuo ls
comando, che mostrerà il contenuto del volume senza entrare nella shell:
- docker run --rm -v DataVolume3:/datavolume3 ubuntu ls datavolume3
La directory datavolume3
ora ha una copia del contenuto dell'immagine di base /var
directory:
Outputbackups
cache
lib
local
lock
log
mail
opt
run
spool
tmp
È improbabile che tu voglia montare /var/
in questo modo, ma può essere utile se hai creato la tua immagine e desideri un modo semplice per preservare i dati. Nel tuo prossimo esempio dimostrerai come un volume può essere condiviso tra più contenitori.
Fase 4:condivisione dei dati tra più contenitori Docker
Finora, hai collegato un volume a un contenitore alla volta. Spesso vorrai collegare più contenitori allo stesso volume di dati. Questo è relativamente semplice da realizzare, ma c'è un avvertimento critico:in questo momento, Docker non gestisce il blocco dei file. Se hai bisogno di più contenitori per scrivere sul volume, le applicazioni in esecuzione in quei contenitori devono essere progettato per scrivere in archivi di dati condivisi al fine di prevenire il danneggiamento dei dati.
Crea Container4 e DataVolume4
Usa docker run
per creare un nuovo contenitore denominato Container4
con un volume di dati allegato:
- docker run -ti --name=Container4 -v DataVolume4:/datavolume4 ubuntu
Successivamente creerai un file e aggiungerai del testo:
- echo "This file is shared between containers" > /datavolume4/Example4.txt
Quindi, uscirai dal contenitore:
- exit
Questo ci riporta al prompt dei comandi dell'host, dove creerai un nuovo contenitore che monta il volume di dati da Container4
.
Crea Container5 e monta volumi da Container4
Stai per creare Container5
e monta i volumi da Container4
:
- docker run -ti --name=Container5 --volumes-from Container4 ubuntu
Verifica la persistenza dei dati:
- cat /datavolume4/Example4.txt
OutputThis file is shared between containers
Ora aggiungi del testo da Container5
:
- echo "Both containers can write to DataVolume4" >> /datavolume4/Example4.txt
Infine, uscirai dal container:
- exit
Successivamente, verificherai che i tuoi dati siano ancora presenti in Container4
.
Visualizza le modifiche apportate in Container5
Ora, controlla le modifiche che sono state scritte nel volume di dati da Container5
riavviando Container4
:
- docker start -ai Container4
Verifica le modifiche:
- cat /datavolume4/Example4.txt
OutputThis file is shared between containers
Both containers can write to DataVolume4
Ora che hai verificato che entrambi i contenitori erano in grado di leggere e scrivere dal volume di dati, uscirai dal contenitore:
- exit
Ancora una volta, Docker non gestisce alcun blocco dei file, quindi le applicazioni devono account per il blocco del file stesso. È possibile montare un volume Docker come di sola lettura per garantire che il danneggiamento dei dati non avvenga per errore quando un container richiede l'accesso in sola lettura aggiungendo :ro
. Ora darai un'occhiata a come funziona.
Avvia Container 6 e monta il volume in sola lettura
Una volta che un volume è stato montato in un contenitore, invece di smontarlo come faresti con un tipico file system Linux, puoi invece creare un nuovo contenitore montato nel modo desiderato e, se necessario, rimuovere il contenitore precedente. Per rendere il volume di sola lettura, aggiungi :ro
alla fine del nome del contenitore:
- docker run -ti --name=Container6 --volumes-from Container4:ro ubuntu
Verificherai lo stato di sola lettura provando a rimuovere il file di esempio:
- rm /datavolume4/Example4.txt
Outputrm: cannot remove '/datavolume4/Example4.txt': Read-only file system
Infine, uscirai dal contenitore e ripulirai i contenitori e i volumi di prova:
- exit
Ora che hai finito, ripulisci i contenitori e il volume:
- docker rm Container4 Container5 Container6
- docker volume rm DataVolume4
In questo esempio, hai mostrato come condividere i dati tra due contenitori utilizzando un volume di dati e come montare un volume di dati in sola lettura.
Conclusione
In questa esercitazione è stato creato un volume di dati che ha consentito ai dati di persistere tramite l'eliminazione di un contenitore. Hai condiviso volumi di dati tra contenitori, con l'avvertenza che le applicazioni dovranno essere progettate per gestire il blocco dei file per prevenire il danneggiamento dei dati. Infine, hai mostrato come montare un volume condiviso in modalità di sola lettura. Se sei interessato a informazioni sulla condivisione dei dati tra i container e il sistema host, consulta Come condividere i dati tra il container Docker e l'host.