Como criar o seu próprio Docker?
Hoje em dia é muito comum o uso de containers em projetos de software, porém o que poucas pessoas sabem é como funciona a tecnologia por trás.
Containers isolam o processo do resto dos recursos do sistema operacional como a rede, filesystem, cgroup (linux control group), Process ID, usuários, entre outros.
Isolar processos em containers possui 2 objetivos principais: 1 - Garantir que o processo executará no mesmo ambiente e com as mesmas dependências independente de onde seja executado; 2 - Impedir que um processo possa afetar de alguma forma a execução de um outro processo, trazendo mais segurança e estabilidade para a aplicação.
Esses 2 objetivos são essenciais para que possamos utilizar serviços Cloud, aliás, todos estamos com nossas aplicações em mainframes compartilhados com outras aplicações.
Outra forma de atingir esses objetivos é através de máquinas virtuais.
As máquinas virtuais simulam a estrutura completa de uma máquina e traduz instruções para a máquina host, a grande diferença aqui é que os containers continuam compartilhando o mesmo kernel e não dependem de softwares que realizam a tradução de instruções, isso por si só garante a economia de recursos e o ganho de desempenho.
Todo esse isolamento do processo com o resto do sistema operacional ocorre através da funcionalidade do linux chamada de namespace. Com o namespace podemos isolar os recursos do sistema operacional para um determinado processo e com isso o processo isolado não sabe da existência dos recursos da máquina. É criado um mundo de mentirinha somente para ele.
Todo Dockerfile inicia com a instrução FROM onde indicamos alguma imagem disponível no hub.docker.com. Com isso podemos utilizar imagens de diferentes distribuições linux independente da distribuição sendo usada na máquina.
Isso só é possível pois com o isolamento dos recursos do sistema operacional todo o sistema de arquivos também é isolado. Dessa forma, dentro do container podemos montar uma nova distribuição com o comando mount e trocar a raiz do sistema operacional (diretório /) usando a system call pivot_root. A partir desse momento, o processo dentro do container passa a utilizar o sistema de arquivos da distribuição que foi montada. Detalhe importante, nenhuma dessas alterações afetam os recursos fora do container.
Outra coisa que também gera curiosidade, é a capacidade de limitar a quantidade de RAM e de CPU que um container pode utilizar (muito comum ao configurar PODs no Kubernetes). Isso só é possível por conta do namespace cgroup que nos dá o poder de isolar e limitar recursos como memória, CPU, uso de disco, uso de rede, etc.
Utilizar o Docker em outro S.O exige que exista uma VM com uma disto Linux. No caso do windows, isso é feito com o hyperV/WSL. No Mac isso pode ser feito utilizando o Lima.
Caso queira realmente implementar o seu próprio sistema de containers depois dessa introdução, recomendo que leia a fundo essa monografia com exemplos em Go.
Você sabia que toda a magia por trás dos containers é responsabilidade do linux?
Aonde me encontrar
Parabéns, excelente explicação