Come dovrei accedere a un volume chiamato dall'host?

Sono nuovo al mondo Docker e sto cercando di realizzare qualcosa che si possa pensare è banale. Tuttavia, sembra che un sacco di principianti lottano per persistere i loro dati quando si utilizza Docker.

Ho costruito un'image personalizzata utilizzando un Dockerfile . Il contenitore gestisce un server MySQL e … sì, l'hai indovinato: vorrei persistere i dati .

Ecco il mio Dockerfile:

FROM debian:8.7 ENV MYSQL_ROOT_PASSWORD=test RUN apt-get update -y && apt-get install -y apt-utils && \ echo "mysql-server mysql-server/root_password password $MYSQL_ROOT_PASSWORD" | debconf-set-selections && \ echo "mysql-server mysql-server/root_password_again password $MYSQL_ROOT_PASSWORD" | debconf-set-selections && \ apt-get install -y mysql-server mysql-client && service mysql start CMD service mysql start && /bin/bash VOLUME /var/lib/mysql EXPOSE 3306 

Creo e gestisco l'image in questo modo:

 docker build -t mysql-persist-test:0.1 . docker run -dt -v database_volume:/var/lib/mysql mysql-persist-test:0.1 

Finora, tutto funziona come previsto, incluso il database.

Tuttavia, diciamo che voglio recuperare i dati sulla mia macchina host (Windows 10, ho installato Docker tramite il Docker Toolbox ).

Ho " legato " una cartella locale al volume chiamato con Kitematic (vedi sotto), il contenitore si riavvia automaticamente e … tutto è rotto! Tutti i file nella directory /var/lib/mysql sono stati rimossi . Alcuni sono stati creati con il staff proprietario anziché mysql .

Kitematic

Poi ho questi errori in /var/log/mysql/error.log :

 ... /usr/sbin/mysqld: Table 'mysql.plugin' doesn't exist 170328 16:03:13 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it. ... 170328 16:03:13 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. ... 170328 16:03:13 InnoDB: Starting an apply batch of log records to the database... InnoDB: Progress in percents: 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 InnoDB: Apply batch completed ... 170328 16:03:14 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist 

Che cosa sto facendo di sbagliato?

La gerarchia del volume

I dati in contenitori sono in una specie di gerarchia. È così.

1. parte dell'image

Questo è il livello più basso, where i dati sono nell'image di sola lettura, immutabile in sé.

2. nel livello di lettura-scrittura

Una volta avviato un contenitore da un'image, viene aggiunto un livello di lettura-scrittura sopra i livelli di image esistenti. Se qualcosa viene modificato, aggiunto o rimosso nel contenitore, per impostazione predefinita viene scritto qui.

Le modifiche in questo livello superano i dati nel livello 1.

3. Volumi Docker

Nell'esempio, hai creato un volume in Docker, con

 VOLUME /var/lib/mysql 

Questo creerà un volume all'interno di Docker, che può essere riutilizzato, persistito, condiviso tra i contenitori, ecc. Se nel livello 1 si trovava qualcosa a /var/lib/mysql , il contenuto di questo volume viene sovrascritto. Se apport modifiche nel contenitore, vengono eseguite nel volume (saltando sopra il livello 2).

4. volumi esterni

Infine, abbiamo directory esterne che puoi montare all'interno del contenitore. Questo sovrascrive tutti gli altri.

Poiché sono basati su una directory esterna, le modifiche apportte nel contenitore saranno facilmente accessibili dall'esterno. Questo è presumibilmente perché hai provato questo approccio.

Cosa ti è successo

È stato avviato con un volume Docker (livello 3) e successivamente modificato in un volume esterno (livello 4). Poiché il livello 4 supera il livello 3, ciò che accade è il contenuto della directory esterna (probabilmente nessun contenuto), sovrascrivere il volume Docker. Pertanto il contenitore vede solo una directory vuota.

I tuoi file sono ancora lì. Basta annullare il supporto esterno e tornare al volume Docker; ci aspetteranno.

Come get i tuoi file fuori

EDIT : come spiega Carlos nei commenti, il docker cp è più semplice, modificandolo per utilizzare tale metodo.

 docker cp <container-id>:/var/lib/mysql ./mydata 

Questo copierà il contenuto di /var/lib/mysql nella cartella mydata .