DOCKER SERIES: TEORIA … Containers, História e Terminologia

Particularmente, não aguentava mais esperar esse momento chegar 🙂 Uma das tecnologias mais comentadas nos últimos anos (pra não dizer década), o Docker já conquistou milhares de adeptos mundo afora e tornou-se pré-requisito para diversas vagas de emprego. Seja de infraestrutura ou desenvolvimento, você precisa SIM dominar/aprender DOCKER 😉 Mas antes, uma breve introdução … Caso você não me conheça, meu nome é Victor. Sou formado em Redes de Computadores pelo IFPB, e trabalho com TI desde 2013 quando entrei na CODATA. Criei esse blog em 2020, durante a pandemia, como um hobby. E também porque queria muito reunir e compartilhar os meus “blocos de nota”, (se é que você me entende 😛 ) frutos de anos na área, em um único lugar, acessível a toda e qualquer pessoa.

Entretanto, se o caro leitor é o oposto disso, ou seja, um longa data por aqui … Talvez já tenha percebido que sou um apaixonado por história e adoro contá-las na sua forma escrita (artigos, prosa). Muito além do que mera datas, nomes, lugares ou simplesmente “decoreba” como vários pensam e acham que é, eu penso que se você gosta de algo, vai conhecer a fundo e tudo isso que falei antes se tornará mera consequência de seus estudos 🙂

Sendo assim, com o docker não poderia ser diferente não é mesmo? Então já sabe: senta que lá vem “contexto histórico” (hahaha!)

ORIGEM & CRONOLOGIA … Before “docker” There Was “chroot

Como bons pesquisadores, é nosso dever sempre entregar os devidos créditos para as pessoas que nos antecederam e que portanto, contribuíram para o estado da arte atual. Fica a seguir, a recomendação de leitura de dois fantásticos artigos, de Lucas Santos (da freeCodeCamp) e Rani Osnat (da AquaSec), respectivamente. Graças a ambos, podemos ter um vislumbre do que foi o passado do docker, sua evolução, e como estão as coisas nos dias de hoje.

Tudo começa em 1979 com o lançamento da versão 7 do sistema operacional UNIX. A grande novidade era a introdução do recurso batizado de chroot. Até então inédito, antes qualquer programa ou processo poderia modificar acidentalmente/intencionalmente o sistema de arquivos (filesystem) hospedeiro. Agora não mais, pois ele funcionaria como uma espécie de cópia separada para o software em questão. Além disso, o mesmo também foi adicionado ao sistema operacional BSD, em 1982.

Avançando um pouco no tempo, chegamos no ano 2000, quando um pequeno e “desconhecido” (não achei o nome, tampouco a fonte) provedor de hospedagem de sites buscava por uma solução de gerenciamento de clientes. Tendo em vista que seus usuários disputavam internamente os mesmos recursos (hardware) no servidor, e não encontrando uma saída, ele criou a sua própria através do sistema FreeBSD. Assim surge o que ficou conhecido como jails (ou FreeBSD jails). No fim das contas, esse provedor conseguiu o “inimaginável” para época: uma configuração de IP e sistema por cliente.

Com o passar dos anos, outras alternativas bastante similares ao jails “original” foram surgindo. Esse foi o caso do Linux VServer (em 2001), do Solaris Containers (em 2004), do Open Virtuzzo (em 2005), e do Process Containers (em 2006).

Foi somente a partir de 2008 que as coisas começaram a ficar mais “sólidas” pois ocorreu o lançamento do LXC (LinuX Containers). De longe, a maior e mais completa implementação de um sistema de gerenciamento de containers já proposta até então. A mesma usava cgroups, namespaces e funcionava em um único kernel Linux sem exigir nenhum patch.

Outro grande marco aconteceu em 2010, quando Solomon Hykes e Sebastien Pahl criam o projeto Docker no evento Y Combinator Startup. Em 2011 a plataforma é lançada. Apenas a título de curiosidade, originalmente o projeto iniciou-se na França, como um produto da companhia dotCloud, Inc. Tratava-se de um provedor com foco em plataforma como serviço (PaaS), cujo capital foi encerrado em 2016, ao ponto que foi criada uma nova empresa de nome Docker, Inc. Você pode saber mais aqui e aqui.

A boa recepção do mercado aliada a massiva adoção por empresas gerou bons frutos, e a partir de 2013, grandes nomes como Red Hat, Microsoft, AWS, e IBM, anunciaram a padronização e uso do Docker para rodar containers em seus ambientes.

Finalmente, chegamos aos “dias atuais”, com o Docker ganhando suporte nativo no Windows através do Hyper-V, ao mesmo tempo que também é possível executá-lo no WSL2 sem máquina virtual ou Hyper-V.

MAS AFINAL … O que é Docker?

O termo docker pode significar várias coisas ao mesmo tempo, ou talvez apenas uma, dependendo do interlocutor. Explico, quem sabe você está se referindo a toda comunidade envolvida no projeto. Ou não, está querendo dizer a ferramenta propriamente dita. Ou ainda talvez, fazendo alusão à empresa que criou a tecnologia. Também há possibilidade de estar englobando tudo, a famosa: TODAS AS ALTERNATIVAS ANTERIORES (rsrs) Bem, para facilitar e evitar maiores confusões, associaremos cada palavra-chave com um referido link (URL). Quando falamos em:

  • “Software” docker – usamos a tecnologia de conteinerização que ativa e cria os chamados Linux Containers (clique pra ver)
  • “Comunidade” docker – interagimos com outras pessoas que desenvolvem, contribuem e também utilizam o docker no dia-a-dia (clique para ver)
  • “Docker, Inc.” – nos referimos a companhia/empresa por trás do projeto (clique para ver)

CERTO … E os outros termos?

Além da palavra docker, em sentido generalista e por vezes ambíguo, nos deparamos também com outras nomenclaturas mais específicas. Igualmente importantes para o pleno entendimento, cabe aqui explicá-las melhor. Vamos uma a uma:

>_ Containers Refere-se apenas, e tão somente, a tecnologia que ficou conhecida como LXC (ou LinuX Containers). Lançada em 2008, conforme já dito, seu trunfo era baseado no fato de isolar partes do Kernel como se fossem processos únicos. Simulando assim, e enganando o hospedeiro, um mini e completamente “novo” computador para cada software em tempo de execução. Tudo isso, é claro, dentro da mesma máquina.

>_ Dockerfile Muito antes das imagens, containers, engine e afins … Tudo, absolutamente tudo no Docker começa com este arquivo. Trata-se na verdade de um simples e legível script, que contém instruções/comandos para construir uma imagem “Docker”. Sua aparência, e exemplo, poderia ser tranquilamente assim:

FROM debian:buster 
RUN sudo apt update \ 
    && sudo apt upgrade -y \ 
    && sudo apt install -y curl \ 
    && curl -sL https://deb.nodesource.com/setup_14.x | bash - \ 
    && sudo apt install -y nodejs

>_ Docker image Consequência ou produto final de um dockerfile. Seria um tipo de modelo (template) a ser usado mais tarde, em outro momento, na construção de um ou mais containers. Podemos fazer um paralelo e dizer que, uma imagem está para um container assim como um snapshot está para uma máquina virtual. Ou seja, ambos são imutáveis e arquivos de leitura (read-only).

>_ Docker container Fruto direto de uma imagem estática, containers são objetos de natureza viva, dinâmica e efêmera. Somos totalmente capazes de interagir com seu conteúdo, podendo até modificá-lo e salvá-lo posteriormente.

>_ Docker Engine Motor, núcleo ou sistema de tempo de execução, responsável por criar e gerenciar containers. Pode ser divido e compreendido em três componentes:

  • Server – Também chamado de daemon, é o serviço que de fato cria e executa os containers.
  • Rest API – Mensageiro entre os outros programas e o próprio Docker, além de instruir o que o mesmo deve ou precisa fazer.
  • Command Line Interface (CLI) – Usada para operar a tecnologia via comandos.

>_ Docker Hub Definiu … Criou … E já testou seu container? Que tal compartilhá-lo com outras pessoas? Esse é o principal repositório para hospedar imagens docker mantido pela própria Docker, Inc.

>_ Docker Desktop Na prática, é a união de duas versões da ferramenta: Docker for Windows e Docker for Mac. Formalmente conhecido por ser uma aplicação que permite criar e executar containers em poucos minutos, e que é suportado em ambos. Seu empacotamento já inclui de fábrica: Docker Engine, Docker Compose, Docker CLI, Kubernetes e outros.

POR QUE? … Containers x VMs

Após um panorama geral sobre Docker, talvez a maior pergunta ainda seja: mas por que eu deveria usá-lo? Já não existem as máquinas virtuais pra tal fim? Sim e não! SIM, compreendo que você é livre e portanto não é obrigado a migrar seus apps e cargas de trabalho para esse novo ambiente chamado containers … NÃO, por favor, peço que não os enxergue como concorrentes diretos. Mas sim como duas tecnologias que podem muito bem se complementar e coexistir pacificamente em seu parque de servidores. Pelo próximos parágrafos tentarei explicar o porquê.

Hypervisors são a vanguarda do que ficou conhecido como virtualização de sistemas. Eles são a base fundamental para rodar uma ou mais VMs dentro de um único sistema hospedeiro (ou HOST, em inglês). É ele quem inspeciona constantemente e garante que o operador humano não fará nenhuma bobagem durante todo o processo. Para ilustrar:

Vamos imaginar que você tenha 8 GB de RAM. Seu sistema operacional usa em média 3 GB nas suas atividades cotidianas mais básicas. Restando então apenas 5 GB, você decide rodar duas máquinas Windows para testes de um laboratório. Cada uma terá 2 GB pois você quer deixar uma folga de pelo menos 1 GB para o SO principal. No decorrer suponhamos que esqueça e abra um editor de vídeos … Bem, caso o seu HOST seja Linux com partição SWAP, haverá uma pequena “sobrevida” pois a troca constante e paginação entre as mesmas acaba mascarando tal deslize. Mas a médio/longo prazo o desempenho do computador será sim afetado. E se for Windows? Más notícias, pois na falta do conceito de SWAP o que ocorrerá é o imediato e completo “travamento” da máquina.

Em suma, o que o hypervisor faz é garantir que não se atribua mais hardware do que realmente se tem. Não importa se diz respeito ao número de núcleos dedicados, quantidade de memória RAM, ou espaço em disco disponível … Caso você extrapole o limite real ainda na etapa de criação da VM, o hypervisor irá sim barrá-lo e informá-lo que não é possível dada a configuração atual.

Tendo ciência de tudo isso, e saltado “tamanho” obstáculo inicial, cabe entender o próximo: funcionamento interno das máquinas virtuais. Cada VM necessita de um Kernel próprio, muitas vezes chamado de sistema convidado (ou GUEST, em inglês). Somente acima dele é que reside os outros programas, bibliotecas e dependências para se trabalhar. Na prática, isso ocasiona uma série de camadas a serem superadas até chegarmos aonde o programador/administrador tanto deseja: seu serviço ou aplicação de fato. E como resultado, o que teremos serão uns bons gigabytes de dados e outros parâmetros a se preocupar e manter.

É por isso que no mundo Docker isso não acontece. Por serem considerados uma abstração da camada de aplicação, os containers são plenamente capazes de compartilhar um mesmo Kernel entre si. Ou seja, cada container já embarca todo o código, bibliotecas e dependências necessárias para rodar aquela determinada aplicação/serviço. Proporcionando assim, tanto um software “neutro” quanto um desenvolvedor mais “agnóstico”. Na prática você deixa de se preocupar com o tipo de SO suportado e outras questões de compatibilidade. É por isso que containers quase sempre são mais leves, rápidos e eficientes do que VMs. Em sua jornada inteira, talvez o maior e mais pesado dos containers fique entre 400 e 600 MB de tamanho.

Figura 01. https://phoenixnap.com/kb/wp-content/uploads/2021/04/container-vs-virtual-machine.png
Figura 02. https://www.freecodecamp.org/news/content/images/2020/12/image-68.png

QUANDO USAR? … Casos e exemplos

1. Banco de dados temporário

Antigamente você instalava primeiro o banco de dados e só depois executava o aplicativo. Com o Docker você só precisa executar o container do banco de dados. Vamos executar um MongoDB simples:

docker run -p 27017:27017 --name my-ephemeral-db mongo
2. Banco de dados persistente

A solução anterior cai por terra se você simplesmente remover o container, pois todos os seus dados serão perdidos. Então vem a pergunta, e se quiser mantê-los mesmo após a exclusão? Você pode vincular o Docker a um volume!

Quando você faz isso, está basicamente montando seu sistema de arquivos no container ou vice-versa. Veja como:

docker run -p 27017:27017 -v /home/my/path/to/db:/data/db --name my-persistent-db mongo
3. Ferramentas de uso único

Outra coisa que todo desenvolvedor faz bastante é instalar aplicativos usados uma única vez. Por exemplo, aquela CLI simples para acessar aquele banco de dados antigo, ou aquela GUI simples para algum servidor de CI.

Muitas ferramentas já possuem containers no Docker, e você pode usá-los assim, para não precisar instalar mais uma ferramenta em seu notebook.

O melhor exemplo é o Redis. Ele tem o redis-cli embutido em outro container, então você não precisa instalar o redis-cli em seu shell se você mal o usa.

docker run --rm -it --network container:redis redis-cli -h 127.0.0.1
4. Pilhas inteiras

Se você precisar testar um aplicativo que depende de outro aplicativo, como faria isso? O Docker facilita fornecendo o docker-compose. É outra ferramenta inbox que permite codificar um arquivo docker-compose.yml que descreve seu ambiente.

O arquivo ficaria assim:

version: "3.8"
services:
  web:
    build: .
    ports:
      - "5000:5000"

  redis:
    image: "redis:alpine"
    ports:
      - "6379:6379"

REFERÊNCIAS:

https://docs.docker.com/get-started/overview/

https://opensource.com/resources/what-docker

https://www.ibm.com/cloud/learn/docker

https://aws.amazon.com/pt/docker/

https://www.freecodecamp.org/news/what-is-docker-used-for-a-docker-container-tutorial-for-beginners/

https://blog.aquasec.com/a-brief-history-of-containers-from-1970s-chroot-to-docker-2016

https://phoenixnap.com/kb/what-is-docker

1 Comment

Deixe uma resposta

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.