Administrando volumes no Docker

Um volume no Docker nada mais é do que um diretório compartilhado entre o host e o container ou entre um ou mais containers, com o Docker podemos gerenciar volumes utilizando o comando docker volume.No Docker basicamente existem duas formas de administrar volumes:

– Volumes criados no host para o container;
– Volumes criados de container para outros containeres;

Para montarmos um diretório simples do host para o container:

[root@notebook ~]# docker run -it -d --name=tadeu_volume -v /home/tadeu/Documentos/txt:/montado debian 
d617f07939015d227332392e3afb3a51f5e88d8bb059e96c01f8333af395da1b

Dentro do container:

[root@notebook ~]# docker attach tadeu_volume 
root@d617f0793901:/# cd montado/
root@d617f0793901:/montado# ls | head -n5 
My Clippings.txt
agendamentos_bacula.txt
anotacoes_bacula.txt
bacula.txt
compacta-etc.txt

Dessa maneira montamos o diretório /home/tadeu/Documentos/txt do meu host para o container que criamos de nome tadeu_volume.

Os volumes no Docker são montados no modo read-write, mas podemos montá-los somente leitura:

[root@notebook ~]# docker run -it -d --name=tadeu_volume -v /home/tadeu/Documentos/txt:/montado:ro debian

Para exemplificar vamos instalar um banco MariaDB.

[root@notebook ~]# docker volume create --name=mariadb

Esse comando vai criar um volume de nome mariadb. Podemos visualizá-lo com o comando:

[root@notebook ~]# docker volume ls 
local               mariadb

Agora subimos um novo container e passamos esse volume para ele passando também o path dos dados do banco:

[root@notebook ~]# docker run -it --name=tadeu2 -v mariadb:/var/lib/mysql debian /bin/bash 

Instalando o MariaDB:

root@abafabdac81e:~# cat > MariaDB.list <<
> # MariaDB 10.1 repository list - created 2017-05-15 14:06 UTC
> # http://downloads.mariadb.org/mariadb/repositories/
> deb [arch=amd64,i386] http://mirror.edatel.net.co/mariadb/repo/10.1/debian jessie main
> deb-src http://mirror.edatel.net.co/mariadb/repo/10.1/debian jessie main
EOF
root@abafabdac81e:~# apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db
root@abafabdac81e:~# apt-get -y update
root@abafabdac81e:~# apt-get install -y mariadb-server

Vamos startar o banco:

root@abafabdac81e:~# /etc/init.d/mysql start
[ ok ] Starting MariaDB database server: mysqld ..
[info] Checking for corrupt, not cleanly closed and upgrade needing tables..

Vamos logar no banco e criar um banco de teste:

root@abafabdac81e:~# mysql -u root -p 
Enter password: 

MariaDB [(none)]> create database ambrosiano; 
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> quit 
Bye

Vamos inspecionar o volume e verificar se os dados foram persistidos:

[root@notebook MariaDB]# docker volume inspect mariadb 
[
    {
        "Name": "mariadb",
        "Driver": "local",
        "Mountpoint": "/var/lib/docker/volumes/mariadb/_data",
        "Labels": {},
        "Scope": "local"
    }
]

Podemos inspecionar esse container também utilizando o “docker inspect”:

[root@notebook MariaDB]# docker inspect --format '{{ .Mounts }}' tadeu2 
[{mariadb /var/lib/docker/volumes/mariadb/_data /var/lib/mysql local z true rprivate}]

Verificamos se os arquivos foram criados no volume:

[root@notebook MariaDB]# ls /var/lib/docker/volumes/mariadb/_data 
ambrosiano        aria_log_control  ibdata1      ib_logfile1        mysql               performance_schema
aria_log.00000001  debian-10.1.flag  ib_logfile0  multi-master.info  mysql_upgrade_info

Essa abordagem é interessante que podemos simular um dump do database mesmo que esse container não esteja mais rodando porque os dados foram persistidos nesse volume. Em um outro container podemos utilizar desses mesmos dados. Exemplo:

Primeiro vamos criar uma imagem desse container:

[root@notebook MariaDB]# docker commit abafabdac81e debian:MariaDB
sha256:80a97e3062b605721c7dafff4c96477850344ae3ae324451a91fbbfda1e8bb1b

Vamos matar esse container:

[root@notebook MariaDB]# docker rm -f tadeu2 
tadeu2

E vamos subir um outro container utilizando a imagem commitada do passo anterior:

[root@notebook MariaDB]# docker run -it --name=tadeu-teste -v mariadb:/var/lib/mysql debian:MariaDB /bin/bash 

Startamos o banco no container novo:

root@a23b4d62b195:/# /etc/init.d/mysql start 
[ ok ] Starting MariaDB database server: mysqld ..
[info] Checking for corrupt, not cleanly closed and upgrade needing tables..

Logamos no banco:

root@a23b4d62b195:/# mysql -u root -p 
Enter password: 

E verificamos que o banco criado (ambrosiano) no container antigo está lá! 🙂

MariaDB [(none)]> show databases; 
+--------------------+
| Database           |
+--------------------+
| ambrosiano         |
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)

Essa foi uma forma de compartilhar os volumes para o banco MariaDB utilizando o nosso Docker-host para armazenar os dados do nosso container. Uma outra forma de utilizarmos os volumes é criando um container somente para dados e compartilhando esse container de dados para outros containers, ou seja, um data-only container, cuja única função é prover volumes para os outros containers. Exemplo:

Vamos criar um container de nome dados e expor o /var/lib/mysql:

[root@notebook MariaDB]# docker run -d --name dados -v /var/lib/mysql debian true

Agora executamos um outro container (uma imagem do mysql) passando a opção –volumes-from:

[root@notebook ~]# docker run -it --name=tadeu_mysql -e MYSQL_ROOT_PASSWORD=admin -P --volumes-from dados mysql /bin/bash

Startamos o banco e criamos um database para verificar se os dados estão persistindo no container de volume:

root@2fb0904ccd23:/# /etc/init.d/mysql start

root@2fb0904ccd23:/# mysql -u root -padmin 
...
...
...
mysql> create database ambrosia; 
Query OK, 1 row affected (0.00 sec)
...
...
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| ambrosia           |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> quit
Bye

Vamos inspecionar o container dados:

[root@notebook MariaDB]# docker volume ls 
DRIVER              VOLUME NAME
local               d0b337b8187e9d76d35b30af915ca90f4733d7e10bd2e10eac8c74278364d022
[root@notebook MariaDB]# docker inspect dados | grep -A 10 Mounts
        "Mounts": [
            {
                "Name": "d0b337b8187e9d76d35b30af915ca90f4733d7e10bd2e10eac8c74278364d022",
                "Source": "/var/lib/docker/volumes/d0b337b8187e9d76d35b30af915ca90f4733d7e10bd2e10eac8c74278364d022/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

Agora vamos verificar se os arquivos criados pelo outro container mysql persistiu os dados nesse container dados:

[root@notebook MariaDB]# ls /var/lib/docker/volumes/d0b337b8187e9d76d35b30af915ca90f4733d7e10bd2e10eac8c74278364d022/_data
2fb0904ccd23.err  ca-key.pem       client-key.pem  ib_logfile0  mysql               public_key.pem   sys
ambrosia          ca.pem           ib_buffer_pool  ib_logfile1  performance_schema  server-cert.pem
auto.cnf          client-cert.pem  ibdata1         ibtmp1       private_key.pem     server-key.pem

Referências:
https://docs.docker.com/engine/admin/volumes/volumes/
https://downloads.mariadb.org/mariadb/repositories/#mirror=edatel
https://mariadb.com/kb/en/library/installing-and-using-mariadb-via-docker/
https://hub.docker.com/_/mysql/