Docker - Perguntas Frequentes

Após uma conversa dentro da OCTO sobre Docker versus LXC e Virtual Machines (VMs), este post contem algumas perguntas e respostas sobre os conceitos e as principais diferenças entre essas tecnologias.

Pergunta: Qual é a diferença entre VMs e containers LXC?

Uma Virtual Machine (VM) consiste em rodar diversos Sistemas Operacionais (SOs) clientes completos (Linux, Windows, BSD, ...) em recursos de hardware compartilhados. Tais SOs podem ser diferentes em cada VM e também pode ser diferente do sistema operacional base, onde rodam as VMs. Cada kernel do Sistema Operacional virtualizado considera sua execução em um hardware comum, sendo ele genérico ou um driver hypervisor específico.

Os Containers são isolamento de recursos: processos, sistema de arquivos, interfaces de rede e outros recursos do kernel (memória compartilhada, mutexes, semáforos, ...) sendo executando dentro de um sistema operacional, com algumas limitações (CPU, memória, iops). Os Containers são comumente descritos como "chroot on steroids". O FreeBSD jails ou o Solaris zones/containers possuem o mesmo objetivo.

Padrão VirtualizaçãoPadrão Virtualização

Padrão ContainerPadrão Container

Pergunta: Um container LXC pode rodar diversas distribuições Linux em um mesmo host?

Resposta direta: Sim.

Resposta elaborada: Os containers compartilham o kernel de seus sistemas operacionais hosts. Logo, eles são capazes de coletar dados desses sistemas, porém possuem seu próprios grupo de processos, configurações de rede e sistemas de arquivo. É possível incializar um container LXC Debian em um host LXC CentOS: neste caso o comando uname retorna a informação do kernel do host, exceto o hostname, dado que o arquivo /etc/*-release contem a informação do Debian sendo executado. Neste caso, o sistemas de gerenciamento de pacotes será o RPM para o host e o DPKG para o container.

Pergunta: Então, se containers são nada mais do que isolamento, porque compará-los a VMs?

No mundo Linux, incializar um container com um conjunto de processos de um sistema operacional completo (init, systemd, upstart, ssh) com um sistema de arquivos dedicado, dá acesso a um sistema isolado o qual realmente se comporta como uma VM, de uma perspectiva do usuário. É possível "logar" na máquina através de ssh em um IP dedicado, executar comandos como sudo, ps, top, yum/apt-get install, keill, service apache2 restart. OpenStack, libvirt, vagrant se conectam com LXC com uma outra maneira de prover VMs, mesmo que o termo não se encaixe.

Pergunta: E como fica o consumo de memória?

O consumo de memória consiste somente no total consumido pelo processo. Isto faz com que containers sejam tão leves que é possível lançar vários containers no mesmo host.

Pergunta: O que são Dockerfiles?

Assim como um Makefile ou um Vagrantfile, um Dockerfile é um arquivo texto utilizado para descrever a maneira como construir uma imagem Docker. A sintaxe de um Dockerfile é bem simples e contém somente alguns comandos auto-explicativos (FROM, RUN, CMD, USER, EXPOSE).

# Imagem incial
FROM ubuntu:latest

# Os comandos a serem executados para construção do container
RUN apt-get -y install python-software-properties
RUN add-apt-repository -y ppa:nginx/stable
RUN apt-get update
RUN apt-get install -y nginx

ADD nginx.conf /etc/nginx/
ADD nginx.sh /

# qual porta de rede será acessível para este container
EXPOSE 80

# o comando a ser executado sempre que o container for iniciado
CMD ["/nginx.sh"]

Perguntas: Que tipo de combinação VM vs Containers são possíveis?

VMs sobre VMs

Faz sentido em poucos casos, por exemplo quando testes de deployment de OpenStack sobre o OpenStack. A degradacão de performance é uma questão a ser tratada.

Container sobre VMs

Este é provavelmente o caso que faz mais sentido, principalmente quando é realmente complicado obter um VM do time de infraestrutura. Isto permite manter a VM limpa e completamente separada do ciclo de vida do container. A reinstalação do container pode ser executada a qualquer momento. E pode haver problemas relacionados com NAT, MASQUERADE, PAT para expor os serviços do container.

Containers sobre Containers

Não há problemas em executar este tipo de alinhamento. O container host deve possuir privilégios LXC para rodar. Muitos container sobre containers não fazem sentido e não há casos reais desses cenários.

VMs sobre Containers

Não deve-se fazer isso. Teoricamente, pode aplicar em hypervisors que rodem em um kernel Linux real (kvm por exemplo). Não há benefícios nesta abordagem.

Perguanta: Com relação ao Puppet / Chef / Salt / Ansible, faz sentido usar essas ferramentas junto ao Docker? Dentro ou fora de um container Docker?

Do lado do host faz sentido. É possível encontrar módulos puppet para gerenciar containers Docker.

Do lado do cliente, não há nada ainda muito definido. Há basicamente duas situações onde o gerenciamento de configuração pode ser utilizado:

  • No momento da construção - criação do container
  • No momento de inicialização - para finalizar a configuração, aplicando parâmetros específicos de ambiente, antes de inicializar o processo.

Como exemplo, pode-se imaginar um Dockerfile onde o puppet é utilizado, sem o master, para executar algumas configurações do container (momento de construção):

# Aqui é considerado que há uma imagem Centos com o Puppet disponível
FROM centos:puppet
ADD conf /etc/puppet/
RUN puppet apply -v -e 'include tomcat7_rhel'

Utilizar tal ferramenta no momento de incialização ou até no momento de execução pode ser útil, caso seja necessário executar alguma configuração de ambiente bem complicada.

Ainda se está longe de um consenso sobre o assunto. De qualquer forma, isso implica em dividir as classes / cookbooks para claramente separar em duas execuções, o que é um grande refactoring.

Mas, e agora?

Há ainda diversas questões a serem respondidas, como uso de local registry, gerenciamento de configuração, administração / operação, rede, storage, entre outras.

Caso tenha alguma dúvida, entre em contato conosco.