Geralmente, o espaço de armazenamento padrão do contêiner pode não ser suficiente para o objetivo. Nesses casos, podemos utilizar a criação de volumes para contornar esse problema.
Volumes são espaços para armazenamento de dados, que são persistentes, sendo compartilhados entre o host e o contêiner, ou entre os próprios contêineres, assegurando os dados para que não seja excluídos junto com contêineres ou imagens.
Há diversas maneiras de trabalhar com volumes no Docker. Neste artigo, trataremos do uso do AUFS (Another Union File System), que é o mais utilizado. O sistema é responsável pelo gerenciamento de múltiplos diretórios, empilhando-os uns sobre os outros e fornecendo uma visão unificada, como se todos juntos fossem apenas um diretório.
Esse único diretório é utilizado para apresentar o contêiner e funciona como se fosse um único sistema de arquivos comum. Cada diretório usado na pilha corresponde a uma camada e é dessa forma que o Docker as unifica e proporciona a reutilização entre contêineres.
Com exceção da camada correspondente ao contêiner, todas as outras são montadas com permissão de leitura, caso contrário, as mudanças de um contêiner poderiam interferir em outro. Caso seja necessário modificar um arquivo nas camadas referentes às imagens, o arquivo será copiado para a camada do contêiner para fazer todas as modificações nesse nível. Dessa forma, o arquivo original da camada inferior é sobreposto nessa pilha, ou seja, o contêiner em questão sempre verá apenas os arquivos das camadas mais altas.
Compartilhamento entre uma pasta padrão do Docker e o Contêiner
Para mapear o volume de um contêiner a uma pasta padrão do host, execute o comando:
docker run -it --name container -v /pasta-volume imagem
Seguindo o exemplo anterior, utilizando Debian, ficaria:
docker run -it --name debian1 -v /volume debian0:vim_auto
Dentro do contêiner, podemos verificar as pastas da raíz, pelo comando
cd e veremos a pasta "volume" criada. Se entrarmos nela e criarmos um arquivo de teste com o comando
touch teste, esse arquivo poderá ser acessado posteriormente no host.
Para visualizar o local, devemos sair do contêiner, com o atalho
Ctrl+p+q e buscar o endereço com o comando:
docker inspect -f {{.Mounts}} contêiner ID
Compartilhamento de uma pasta específica do host para o Contêiner
Caso necessário utilizar uma pasta específica do host para mapeamento, o comando seria:
docker run -it --name container -v /pasta-host:/pasta-volume imagem
Compartilhamento de volumes entre Contêineres
É possível criar um contêiner com um volume que pode ser compartilhado com demais contêineres, para que tenhamos alguma persistência de dados e que não fique dependente do host onde o contêiner está.
O comando será o seguinte:
docker create -v /data --name container image
Utilizaremos a imagem do Ubuntu neste exemplo. Agora precisamos compartilhar o volume "dados" com outro volume:
docker run -it --volumes-from container-volume --name container imagem
Subindo novamente outro contêiner, agora com o Debian, teremos:
A pasta "dados" está agora acessível neste contêiner. Essa prática pode ser aplicada a quantos contêineres forem necessários, dependendo da sua necessidade. Para maiores informações, visite o site oficial
Docker Volumes.
Serviços de DHCP e DNS Server em contêineres
Para exemplificar a utilização dos serviços do Docker, vamos criar um servidor com os serviços de DHCP e DNS Server, em contêineres separados. Após realizar a instalação do Docker no host, vamos prosseguir subindo os contêineres dos serviços necessários.
DHCP Server
Vamos utilizar a imagem "networkboot/dhcpd" do Docker Hub, que utiliza o serviço ISC DHCP Server rodando no Ubuntu LTS.
Caso queira especificar parâmetros ou configurações diferentes, confira e altere o arquivo "Dockerfile", para criar um contêiner com o build. Para que o servidor provenha o DHCP na rede do host, devemos criar um arquivo de configuração para o servidor DHCP e iniciar o contêiner com o parâmetro "--net host", especificando a interface que será utilizada. Para criar o arquivo, vamos utilizar os comandos:
mkdir data
vim data/dhcpd.conf
Para o arquivo de configuração do DHCP, neste artigo, utilizaremos uma configuração bem básica do serviço, apenas para distribuir os endereços, sem maiores configurações avançadas. Para informações mais completas sobre o "dhcpd.conf", que saem do escopo deste artigo, acesse a página da ISC, que contém o manual completo de configuração do serviço.
No exemplo, utilizaremos o seguinte:
#dhcpd.conf
default-lease-time 600;
max-lease-time 7200;
authoritative;
subnet 10.0.0.0 netmask 255.255.255.0 {
range 10.0.0.10 10.0.0.20;
option domain-name-servers 10.0.0.2;
option routers 10.0.0.2;
}
Com o arquivo de configuração editado, vamos iniciar o contêiner com o seguinte comando:
docker run -it --init --net host -v /root/data/:/data networkboot/dhcpd eth0
Feito isso, o servidor DHCP já está funcionando, de acordo com os parâmetros do arquivo de configuração "dhcpd.conf". Apertando
Ctrl+p+q, podemos voltar ao terminal do host e manter o contêiner em execução.
Servidor Bind (DNS)
Para iniciar o servidor DNS, utilizaremos uma imagem disponibilizada no Hub por um usuário, ou seja, não oficial, chamada "sameersbn/bind", disponível no Docker Hub. Esta imagem utiliza os serviços BIND e Webmin no Ubuntu.
Caso queira especificar parâmetros ou configurações diferentes, confira e altere o arquivo "Dockerfile", para criar um contêiner com o build. Utilizando o seguinte comando, subiremos o contêiner com os serviços ativos:
docker run --name dns -d --restart=always --publish 53:53/tcp --publish 53:53/udp --publish 10000:10000/tcp --volume /srv/docker/bind:/data -e ROOT_PASSWORD=pass sameersbn/bind:latest
- --dns=127.0.0.1 : Configura o dns do contêiner para 127.0.0.1;
- --publish 53:53/udp : deixa o servidor DNS acessível na porta 53;
- --publish 10000:10000 : deixa o Webmin acessível pela porta 10000;
- -e "'ROOT_PASSWORD=pass" : Atribui valor à variável ROOT_PASSWORD, configurando a senha de acesso root ao painel Webmin.
Após isso, acessando pelo navegador, através do endereço:
https://endereço-do-servidor:10000
...poderemos acessar o Webmin, com o usuário root, e a senha de acordo com o que foi colocada no comando, no caso do exemplo, "pass". Para atestarmos que o servidor DNS está ativo e funcionando, podemos utilizar o comando no terminal do host:
# host www.google.com 10.0.0.2
Se tudo estiver correto, o comando deverá retornar o endereço de IP correspondente ao endereço digitado. Assim atestamos o funcionamento do Bind.
Visto que o foco deste artigo baseia-se apenas no Docker, a configuração do servidor Bind pelo Webmin não será detalhada. Para maiores informações, temos um bom artigo no
Medium (Santos, 2016), que trás um passo a passo da configuração do serviço.
Conclusão
O Docker apresenta diversas imagens oficiais e da comunidade, com uma ampla gama de serviços já pré-configurados, de fácil implantação e alta portabilidade, sendo portanto, um serviço muito viável para quem não dispõe de um hardware potente, e precisa de uma infraestrutura modular e ágil.
Referências Bibliográficas
GET STARTED. Docker. Disponível em:
O QUE É DOCKER. Mundo Docker. Disponível em:
O QUE É CONTAINER LINUX. RedHat. Disponível em:
DOCKER PARA DESENVOLVEDORES. Github. Disponível em:
SANTOS, Ruben. Como configurar um servidor de DNS no CentOS7 através do Webmin. Disponível em:
USE VOLUMES. Docker. Disponível em:
SAMEERSBNS/BIND. Docker. Disponível em:
NETWORKBOOT/DHCPD. Docker. Disponível em:
PURE-FTPD ON DOCKER. Github. Disponível em:
ISC DHCP 4.4 MANUAL PAGES. ISC. Disponível em:
DOCKER DOCUMENTS. Docker. Disponível em:
KASIREDDY, Preethi. A Beginner-Friendly Introduction to contêineres, VMs and Docker. Disponível em:
ROMERO, Daniel. contêineres com Docker: Do Desenvolvimento à Produção. Casa do Código, 2015.
MATTHIAS, K.; KANE, S.P. Docker Up & Running. Estados Unidos: O?Reilly, 2015