Docker

Uma das novidades da versão 3.8 do kernel Linux é o superte ao LXC (Linux Containers), apesar de ser possível utilizar esse recurso diretamente, existem algumas alternativas que facilitam seu uso como o Docker.

Os Linux Containers nada mais são que uma evolução do chroot, que antigamente era muito utilizado para rodar o bind de forma isolada do sistema por questões de segurança (procedimento na wiki do Debian). O chroot simplesmente troca o root do sistema para aquela aplicação de forma que todos os caminhos absolutos comecem de um determinado diretório e não seja possível acessar os arquivos que não estiverem de baixo do mesmo. Está técnica também é conhecida por enjaulamento (chroot jail).

Apesar do isolamento na parte de sistema de arquivos pelo chroot, nem tudo do processo fica isolado, como a pilha de rede, que por exemplo ainda é compartilhada. O Linux Container veio para melhor isso e o Docker para facilitar seu uso.

Primeira coisa para se entender do Docker é que ele só funciona no kernel Linux para executar containers Linux, apesar de existir versão no site oficial para Windows e Mac, por trás é utilizado uma VM com o Linux para executá-los. A segunda que diferente de máquinas virtuais, que recriam todo o ambiente de um computador para executar o sistema operacional, ele reutiliza o kernel em execução, então a versão do kernel dentro do container será a mesma do sistema hospedeiro, então se tiver que carregar algum módulo do kernel para alguma aplicação específica, deve ser feito no hospedeiro.

Agora para entender como a mágica é feita basta voltar no gerenciador de boot. Um dos parâmetros do Linux é o root=, onde é dito para o kernel que ponto dele deve utilizar como root para o sistema assim que for iniciá-lo. No Docker é como se criássemos um processo que voltaria neste ponto e diria que o root= é outro, apenas para um grupo de processo, porém sem iniciar um novo kernel, mas com seus próprio espaço de sistema de arquivos, pila de rede, controle de processos, CPU e alocação de memória, fazendo-o parecer muito com uma VM, se não fosse pela questão do kernel ter que ser o mesmo.

Uma vez na máquina hospedeira será possível listar todos os processos dos containers com um simples ps aux, já que tudo está sobre o mesmo kenel, porém dentro do container não é possível acessar o hospedeiro diretamente devido ao isolamento feito pelo kernel, bem como outros containers.

Agora mais específico para o Docker. Ele trabalha com grupos de imagens e diferenças entre elas, você tem uma imagem básica do sistema, que pode ser o que você quiser como CentOS, Debian ou até apenas um simples BusyBox, que é possível devido ao fraco acoplamento dos programas com o kernel (sendo possível um kernel Debian e imagem CentOS), e várias pilhas de imagens até chegar ao sistema de arquivos do seu container. O funcionamento desse sistema de arquivos é devido ao Aufs, que é um sistema de arquivos voltado a mudanças, ou seja, só serão gravadas as mudanças efetuadas, assim como num repositório Git (que é um dos requisitos no Debian pelo menos). Você tem a imagem do sistema operacional básico, uma camada aonde você instalou o SSH, outra o Apache e na última sua aplicação, qualquer mudança será feita na camada da sua aplicação, porém para acessar os arquivos binários do apache, como ele não está na camada a aplicação, vai descendo até chegar nos arquivos, para acessar o bash, por exemplo terá que ir até a camada do sistema base. Se ainda ficou um pouco confuso basta lembrar dos snapshots das VMs, aonde você pode voltar para um momento específico do sistema de arquivos e normalmente só é gravado no HD a diferença do último snapshot.

Agora para começar a parte mais prática, tendo o Docker instalado conforme a documentação, precisamos de uma imagem base, por exemplo a do CentOS, que pode ser baixada do repositório oficial do Docker com o seguinte comando docker pull centos. Para iniciá-la um container com esta imagem basta executar docker run -t -i centos /bin/bash. E assim que o bash for fechado, este container parará de executar.

Para subir um WordPress por exemplo, podemos utilizar os containers das aplicações já prontas, primeiro um container com o MySQL:
docker run --name blog-db -e MYSQL_ROOT_PASSWORD=senhanovadoroot -d mysql

E depois o WordPress:
docker run --name blog-wp --link blog-db:mysql -d wordpress

Vale notar que caso você não tenha as imagens, a mesma será baixada automaticamente do repositório oficial do Docker e que executar o banco em um container diferente permite simplesmente trocar o containder do WordPress para atualizar e manter o mesmo banco, assim como escalar para várias instâncias do WordPress conectando no mesmo banco.

O Docker também tem uma vantagem para quem faz aplicações, você pode pegá-la e gerar um container, com o sistema que mais desejar, assim como as versões específicas das bibliotecas, e sempre rodará sem problema em qualquer distribuição, atualizada ou não. Há algum tempo no meu GitHub, fiz um exemplo/tutorial de como criar um container e executar uma aplicação WSGI dentro do Docker (https://github.com/eduardoklosowski/Exemplo-Docker-para-WSGI). Para visualizar melhor as camadas do sistema de arquivos basta olhar o arquivo Dockerfile, cada comando presente no arquivo gera uma camada, e caso tenha algum erro nesse processo não é necessário executar novamente os comandos que não tiveram erro, apenas os demais.

Deixo o vídeo do Allisson Azevedo (https://www.youtube.com/watch?v=vb2k8jOlHkA) para quer quiser saber mais ou ter outra explicação para comparar, além de aconselhar a leitura da documentação oficial.

Vagrant

Vagrantfile

Sempre gostei de deixar o meu sistema operacional o mais limpo possível, sem instalar muitos pacotes e depois removê-los, dou uma olhada nos arquivos de configuração antigos para limpar o home. Máquinas virtuais são perfeitas para testar programas, porém é muito chato ter que ficar gerenciando tudo na mão, normalmente já tinha uma VM instalada com o básico que servia de base, mas ainda assim leva um tempo até conseguir testar e depois, quando apaga para liberar espaço, não lembra de tudo que foi feito.

Um programa que estou utilizando no trabalho para fazer a configuração inicial do servidor é o Vagrant. A ideia é criar uma máquina virtual com a nossa instalação padrão e depois instalar os pacotes das soluções na primeira vez que ligar a VM de forma automática, funcionando muito bem.

Existem vários boxs (VM com o sistema operacional instalado) prontos na internet para o Vagrant, porém não sei como foram gerados e nem tudo que foi feito neles antes de eu poder usar, então resolvi fazer um box que eu conseguiria controlar melhor.

Os passos seguidos foram:

  • Instalar o sistema operacional
  • Configurar os usuários, por padrão o usuário utilizado é “vagrant” e sua senha também é, porém pode ser outro usuário e senha desde que configurados no Vagrantfile.
  • Configurar a interface de rede para DHCP, utilizando o NAT do VirtualBox.
  • Configurar o acesso ssh, interessante se for autenticação por chave, existe uma padrão, porém como é pública não deve ser utilizada se necessita de segurança.
  • Configurar o sudo para o usuário do vagrant sem senha e com “env_keep=SSH_AUTH_SOCK”.
  • Instalar os componentes adicionais do VirtualBox na VM.
  • Exportar o box com: vagrant package –output arquivo.box –base nome_da_vm
  • Adicionar o box no Vagrant: vagrant box add nome_da_vm arquivo.box

* Não coloquei os comandos que podem variar de acordo com a distribuição, porém os passos são esses, só testar para identificar se necessita de algum ajuste.

Depois disso só dar um “vagrant init nome_da_vm”, editar o Vagrantfile para instalar os pacotes adicionais, que podem ser via shell script mesmo, configurar os caminhos dos programas para /vagrant no servidor que é a pasta aonde está o Vagrantfile, executar um “vagrant up” e pronto. Caso tenha apagado a VM e ainda tiver o Vagrantfile só executar “vagrant up” novamente e ela será refeita, inclusive se a box estiver numa versão mais atualizada.

Vale muito a pena dar uma olhada nesse programa, suas vantagens para desenvolvimento são enormes, mas todos podem aproveitar deste que saiba como usar e não precisa guardar VMs de 10G, só um arquivo de 10 linhas de texto.