Aprenda a criar, localizar e fazer backups de volumes no Docker!

Agora vamos criar os volumes da maneira mais elegante e atual. Hoje temos a possibilidade de realizar o gerenciamento de volumes de maneira muito simples e inteligente.

Sempre que criamos um volume, ele cria um diretório com o mesmo nome dentro de "/var/lib/docker/volumes/".

No exemplo a seguir, o volume "giropops" seria então criado em "/var/lib/docker/volumes/giropops"; com isso, todos os arquivos disponíveis nesse diretório também estariam disponíveis no local indicado no container. Vamos aos exemplos! :D

É possível fazer a criação de volumes e toda a sua administração através do comando:

# docker volume create giropops

É possível removê-lo através do comando:

# docker volume rm giropops

Para verificar detalhes sobre esse volume:

# docker volume inspect giropops

Para remover os volumes que não estão sendo utilizados (use com extrema moderação! :D):

# docker volume prune

Para que você possa montar o volume criado em algum container/service, basta executar o seguinte comando:

# docker container run -d --mount type=volume,source=giropops,destination=/var/opa nginx

Onde:

  • --mount -- Comando utilizado para montar volumes.

  • type=volume -- Indica que o tipo é "volume". Ainda existe o tipo "bind", onde, em vez de indicar um volume, você indicaria um diretório como source.

  • source=giropops -- Qual o volume que pretendo montar.

  • destination=/var/opa -- Onde no container montarei esse volume.

Simples como voar, não?

Localizando volumes

Caso você queira obter a localização do seu volume, é simples. Mas para isso você precisa conhecer o comando "docker volume inspect".

Com o "docker volume inspect" você consegue obter detalhes do seu container, como, por exemplo, detalhes do volume.

A saída do comando "docker volume inspect" retorna mais informação do que somente o path do diretório no host. Vamos usar a opção "--format" ou "-f" para filtrar a saída do "inspect".

docker volume inspect --format {% raw %}'{{ .Mountpoint }}'{% endraw %} giropops
/var/lib/docker/volumes/giropopos/_data

Criando e montando um data-only container

Uma opção bastante interessante em relação aos volumes diz respeito ao data-only container, cuja principal função é prover volumes para outros containers. Lembra do NFS server e do Samba? Ambos centralizavam diretórios com a finalidade de compartilhar entre outros servidores. Pois bem, o data-only container tem a mesma finalidade: prover volumes a outros containers.

Um dos grandes baratos do Docker é a portabilidade. Um container criado no seu laptop deve ser portátil a ponto de rodar em qualquer outro ambiente que utilize o Docker, em todos os cantos do universo!

Sendo assim, o que acontece se eu criar um ambiente em Docker que diz para os containers montarem um diretório do host local? Depende. Depende de como está esse tal host local. Perguntas como "o diretório existe?" "as permissões estão ajustadas?", entre outras mais, definirão o sucesso na execução dos containers, o que foge completamente do escopo do Docker.

Vamos ver como funciona isso na prática! :)

Para o nosso exemplo, primeiro vamos criar um container chamado "dbdados", com um volume chamado "/data", que guardará os dados de um banco PostgreSQL.

Para que possamos criar um container especificando um nome para ele, utilizamos o parâmetro "--name", conforme veremos no exemplo a seguir:

# docker container create -v /data --name dbdados centos

Com isso, apenas criamos o container e especificamos um volume para ele, mas ainda não o iniciamos.

Sabemos que no container o volume se encontra montado em "/data". Porém, qual a localização desse volume no host?

Lembra do "docker inspect"? Vamos utilizá-lo novamente:

root@linuxtips:~# docker inspect -f {% raw %}{{.Mounts}}{% endraw %} dbdados

[{46255137fe3f6d5f593e9ba9aaaf570b2f8b5c870f587c2fb34f29b79f97c30c /var/lib/docker/volumes/46255137fe3f6d5f593e9ba9aaaf570b2f8b5c870f587c2fb34f29b79f97c30c/_data /data local true }]

Perceba que agora utilizamos o nome do container em vez do "CONTAINER ID". Totalmente possível e muito mais intuitivo.

Quando executamos o "docker inspect", ele nos retornou o caminho do nosso volume. Vamos ver se existe algum conteúdo dentro dele:

root@linuxtips:~# ls \
 /var/lib/docker/volumes/46255137fe3f6d5f593e9ba9aaaf570b2f8b5c870f587c2fb34f29b79f97c30c/_data

Como vimos, o diretório ainda não possui conteúdo.

Agora vamos criar os containers que rodarão o PostgreSQL utilizando o volume "/data" do container "dbdados" para guardar os dados.

Para que possamos fazer o exemplo, precisamos conhecer mais dois parâmetros superimportantes:

  • --volumes-from -- É utilizado quando queremos montar um volume disponibilizado por outro container.

  • -e -- É utilizado para informar variáveis de ambiente para o container. No exemplo, estamos passando as variáveis de ambiente do PostgreSQL.

Pronto, agora estamos preparados! Vamos criar os containers com o PostgreSQL:

# docker run -d -p 5432:5432 --name pgsql1 --volumes-from dbdados \
    -e POSTGRESQL_USER=docker -e POSTGRESQL_PASS=docker \
    -e POSTGRESQL_DB=docker kamui/postgresql

# docker run -d -p 5433:5432 --name pgsql2 --volumes-from dbdados \
   -e POSTGRESQL_USER=docker -e POSTGRESQL_PASS=docker \
   -e POSTGRESQL_DB=docker kamui/postgresql

Para verificar os dois containers com o PostgreSQL em execução, utilize o "docker container ls".

Pronto, agora temos os dois containers com PostgreSQL em execução! Será que já temos algum dado no volume "/data" do container "dbdados"?

Vamos verificar novamente no host se o volume agora possui algum dado:

root@linuxtips:~# ls /var/lib/docker/volumes/46255137fe3f6d5f593e9ba9aaaf570b2f8b5c870f587c2fb34f29b79f97c30c/_data

base pg_clog pg_ident.conf pg_notify pg_snapshots pg_stat_tmp pg_tblspc PG_VERSION postgresql.conf postmaster.pid server.key global pg_hba.conf pg_multixact pg_serial pg_stat pg_subtrans pg_twophase pg_xlog postmaster.opts server.crt

root@linuxtips:~#

Sensacional! Como percebemos, os dois containers do PostgreSQL estão escrevendo seus dados no volume "/data" do container "dbdados". Chega a ser lacrimejante! :D

Sempre é bom um backup...

Outra coisa bem bacana é a possibilidade de fazer backups dos seus containers de dados de forma muito simples e rápida.

Digamos que você queira fazer o backup do diretório "/data" do container "dbdados" que nós criamos há pouco; como faríamos?

root@linuxtips:~# cd backup/
root@linuxtips:~/backup# docker run -ti --volumes-from dbdados -v $(pwd):/backup debian tar -cvf /backup/backup.tar /data

Quando executamos o comando anterior, é criado um novo container montando o(s) volume(s) do container "dbdados" (que no caso é o "/data", lembra?). Além disso, será montado o diretório corrente do host no volume "/backup" do container, e em seguida será executado o comando do tar para empacotar o diretório "/data" dentro do diretório "/backup". Bem simples, né?

root@linuxtips:~/backup# ls
backup.tar
root@linuxtips:~/backup#

Lembrando que os volumes são sempre criados dentro de "/var/lib/docker/volumes". Caso queira fazer o backup de todos os volumes, basta tratar esse diretório em suas rotinas de backup. ;)

Deixe um comentário