Sebbene Docker sia uno strumento utile per il confezionamento e la gestione delle applicazioni, presenta anche molte sfide uniche, come la gestione dei dati archiviati. Di solito, aggiungi volumi ai contenitori nello script di creazione, ma cosa succede se devi crearne di nuovi?
Aggiunta di un volume a un contenitore Docker in esecuzione
Sfortunatamente non è così semplice come aggiungere un nuovo volume. I contenitori devono avere i loro volumi configurati all'avvio, il che significa che per aggiungere un nuovo volume, è necessario riavviare il contenitore. Sebbene esista una soluzione hacky (ne parleremo più avanti), si consiglia vivamente di eseguire comunque un riavvio del container.
Questo per alcuni motivi. Il riavvio del contenitore è abbastanza semplice e la maggior parte degli aggiornamenti del codice richiede comunque il riavvio del servizio. Il tracciamento degli aggiornamenti in Git è un altro fattore importante, soprattutto se utilizzi Docker Compose e la modifica dello script di avvio è molto meglio che aggiungere manualmente il volume a un contenitore in esecuzione.
Se il tuo servizio è abbastanza grande da farti preoccupare per alcuni minuti (al massimo) di potenziali tempi di inattività pianificati per riavviare il contenitore, probabilmente dovresti eseguire una distribuzione di scalabilità con più istanze che possono essere aggiornate in modo indipendente. I moderni sistemi di scalabilità automatica dovrebbero essere progettati per gestirlo, poiché le distribuzioni di codice avvengono spesso.
Se vuoi aggiungere un volume, dovrai interrompere il contenitore in esecuzione:
docker stop my_container
Crea un nuovo volume se necessario:
docker volume create nginx-config
E quindi eseguilo con un comando di avvio aggiornato, aggiungendo il --mount
flag per configurare il volume di origine e la destinazione di destinazione.
docker run -d --name devtest --mount source=nginx-config,target=/etc/nginx nginx:latest
Se utilizzi Docker Compose, puoi automatizzare e tenere traccia di questo processo più facilmente, poiché la configurazione del volume viene gestita tramite un file di impostazioni. dovrai aggiungere il volume a docker-compose.yml
file:
version: "3.0" services: web: image: nginx:latest ports: - "80:80" volumes: - /docker/nginx-config/:/etc/nginx/
Quindi, puoi riavviare i servizi di Docker Compose. Compose ha un comando "riavvia", ma in realtà serve solo ad aggiornare il servizio in esecuzione senza alcuna modifica alla configurazione. Se desideri aggiornare le immagini, dovrai eseguire docker-compose up
con il --build
bandiera:
docker-compose up -d --build
Puoi anche eseguire manualmente docker-compose down
prima di interrompere i servizi, ma nella maggior parte dei casi non è necessario a meno che tu non voglia eseguirlo con il -v
flag per distruggere i volumi esistenti.
RELAZIONATO: Cos'è Docker Compose e come lo usi?
Clonazione da un container esistente
In quasi tutti i casi, non dovresti dipendere dallo stato di esecuzione corrente di un container. Tutto ciò che ti interessa, come i dati dell'applicazione, dovrebbe essere archiviato in un volume in modo che possa essere mantenuto durante i riavvii e le ricostruzioni dei container.
Questo metodo probabilmente non è una buona idea per la maggior parte delle persone, poiché richiede di creare una nuova immagine ogni volta che vuoi farlo e richiede comunque tempi di inattività. Tuttavia, se devi aggiungere un volume a un contenitore in esecuzione, puoi utilizzare docker commit
per creare una nuova immagine basata su quel contenitore, quindi clonarla con il nuovo volume.
Prendi l'ID del contenitore da docker ps
:
docker ps
E poi clonalo con commit
:
docker commit f88f33c918d2 imagename
Quindi, puoi eseguire la nuova immagine, sostituendo la vecchia immagine con quella clonata.
docker run -d --name devtest --mount source=nginx-config,target=/etc/nginx imagename
La soluzione Hacky
I volumi Docker sono in realtà solo un trucco che il runtime Docker utilizza per esporre le directory host ai contenitori e tutto dipende dalla configurazione. Per questo motivo, puoi effettivamente modificare quella configurazione direttamente e riavviare l'intero demone Docker affinché il tuo sistema applichi tali modifiche senza riavviare affatto.
Ovviamente, questo è molto più complicato del semplice riavvio di un container, quindi se riesci a gestire un minuto di inattività, ti consigliamo vivamente di farlo.
Dovrai accedere alla directory di archiviazione di Docker:
cd /var/lib/docker/containers
Qui ci saranno molte cartelle corrispondenti agli ID contenitore Docker, che puoi trovare con docker ps
. Apri quello per il contenitore che desideri modificare.
Il file di configurazione è config.v2.json
, ma è in un formato compatto e difficile da modificare. Puoi installare jq
per stampare in modo grazioso JSON sulla riga di comando e reindirizzarlo a un nuovo file per la modifica:
jq . config.v2.json > tmp.json
Dovrai scorrere verso il basso per trovare "MountPoints", che contiene la configurazione per tutti i volumi e i montaggi di binding. Puoi aggiungerne uno nuovo qui, che dovrebbe essere nel seguente formato:
"MountPoints": { "/home/container": { "Source": "/var/lib/pterodactyl/volumes/c7fb3a04-e540-48a7-9704-13987f52e933", "Destination": "/home/container", "RW": true, "Name": "", "Driver": "", "Type": "bind", "Propagation": "rprivate", "Spec": { "Type": "bind", "Source": "/var/lib/pterodactyl/volumes/c7fb3a04-e540-48a7-9704-13987f52e933", "Target": "/home/container" }, "SkipMountpointCreation": true } },
Quindi, una volta terminato, puoi ridurre nuovamente il JSON nel file di configurazione:
jq -c . tmp.json > config.v2.json
jq
è una potente utility, quindi se volessi automatizzare completamente questo processo, potresti farlo.
RELAZIONATO: Come lavorare con JSON sulla riga di comando
Quindi, riavvia semplicemente il servizio Docker per applicare le modifiche:
sudo service docker restart