O que são containers e como funcionam no Windows – Erik Filippini
Publicado por Erik Filippini em 27/09/2018 27/09/2018
Olá pessoal, a missão deste post hoje é de mostrar de forma objetiva o que são containers e como estes funcionam em ambientes Windows, mãos a obra!
Vamos entender observando a imagem a seguir:
No lado da esquerda, temos um ambiente virtual tradicional, com nossas queridas máquinas virtuais (VM's), se você já criou uma VM, sabe que precisamos de um Hypervisor (Hyper-V, ESXi, Xen, etc.), é neste hypervisor que vamos trabalhar configurando uma VM e depois apontando uma .ISO para instalar um sistema operacional nesta VM, vamos observar com mais detalhes este ponto.
Quando falamos em configurar uma VM, estamos criando um hardware físico virtual (WTF?), sim, estamos basicamente pedindo ao hypervisor que minta para a VM que ela tem um hardware físico exclusivo para ela, criando assim uma emulação de CPU, memória RAM e Rede físicas e entregando de forma virtual para esta nova VM.
Neste caso, além de emular o hardware, precisaremos instalar um SO utilizando uma .ISO, a mesma usada para instalar o SO em uma máquina física, sendo assim, todos os arquivos de sistema deverão ser copiados para o HD desta VM, e estes mesmos arquivos são exclusivos desta VM e não podem ser compartilhados com outras VMs de mesmo sistema, sim, porque vale lembrar que estamos emulando hardware físico, então a VM entende que ela é uma máquina física.
Entendido como funciona o método tradicional de virtualização, vamos avançar para entender como funciona a virtualização de aplicações, os tão charmosos containers (ou Contêiner em PT-BR). Observe o lado direito da figura, podemos verificar que continuamos tendo máquinas físicas (hosts) e sistema operacional normalmente, a diferença agora é que "não" precisamos de um hypervisor agora, já que vale lembrar que a função do hypervisor é emular hardware físico para uma VM. Sem o hypervisor, como podemos virtualizar então?
Esta é a mágica dos containers, através de algumas técnicas (namespaces, c-groups…) no próprio sistema operacional do host, é possível isolar aplicações (containers) para que estes sejam executados totalmente isolados de outras aplicações que estejam rodando nesta máquina. O mais legal de tudo isso é que agora não precisamos mais mentir e emular hardware, estamos trabalhando a nível de aplicação no próprio SO do host. Não se aplica mais o uso de uma .ISO para instalar o SO, já que o SO é o que já está instalado no host, e agora sim podemos compartilhar este SO (leia-se Kernel) entre os containers, isto que podemos observar na figura, não existem mais VMs, o que temos e o Kernel do SO do host sendo compartilhado de forma isolada várias vezes (container).
Ná prática, agora você não vai mais criar uma VM, baixar uma .ISO, intalar um novo SO, instalar as aplicações neste SO… Agora você vai criar um novo container (isolar uma parte dos recursos do host) usando o Kernel do seu próprio SO e implementar sua aplicação neste container, de forma isolada. O que existem agora são as imagens (Não confunda com uma imagem de Windows ou Linux por exemplo), você vai baixar uma imagem como se fosse um .EXE, podendo ser ela uma imagem de um Nginx por exemplo, esta imagem nunca vai mudar (ela é read-only), o que vai acontecer agora é que você vai criar um ou vários container(s) acima desta imagem. Cada um destes containers criados e que estão rodando, poderão receber modificações, como edição de arquivos, porém, a imagem base nunca vai mudar, ela será sempre read-only.
Isto ocorre porque este ambiente entre imagens e containers é constituido de várias camadas, onde apenas a última camada, que trata-se do container, é read-and-write. por isso que sempre que você quiser rodar seu container em algum lugar, você vai precisar da imagem da qual o container foi criado, já que a aplicação em si esta toda nesta imagem e apenas as modificações específicas estão no container.
Simplificando, pense que você tem um computador (Representando nosso servidor) com Windows (com a feature de containers habilitada), ai você instala o Excel (Neste caso representando a imagem de um container) e depois você abre o Excel e por ele abre uma planilha .XLS (representando nosso container), você trabalha neste .XLS modifica coisas e etc., este .XLS é modificável e pode ser transportado de um computador para outro (que tenha o Excel disponível), já o Excel em si nunca vai ser modificado, será sempre read-only. Espero que a analogia tenha ajudado 🙂
Agora que entendemos o que são containers e qual a diferença entre VM e container, vamos focar nos containers em ambientes Windows.
Para explicar como os containers são implementados internamente no Windows, você precisa conhecer dois conceitos importantes: Modo do Usuário e Modo Kernel. Ambos são modos diferentes entre os quais um processador alterna continuamente, dependendo do tipo de código que deve ser executado.
O Modo Kernel de um sistema operacional foi criado para que drivers que precisam ter acesso direto e irrestrito ao hardware do computador. Programas normais (Modo de Usuário) precisam fazer uso de APIs do sistema operacional para acessar o hardware O código que está sendo executado no Modo Kernel tem acesso direto a esses recursos e compartilha os mesmos locais de memória/espaço de endereço virtual que o sistema operacional e outros drivers do kernel. A execução de código neste Modo Kernel é, portanto, muito arriscada, porque os dados que pertencem ao sistema operacional ou a outro driver podem ser comprometidos caso, por exemplo, uma operação no modo kernel grave acidentalmente os dados em um endereço virtual incorreto. Se um driver do modo kernel travar, o sistema operacional inteiro trava. A execução de código dentro do espaço do kernel deve, portanto, ser feita com o maior cuidado possível. Esta é exatamente a razão pela qual o modo de usuário foi criado.
No Modo do Usuário, o código sempre é executado em um processo separado (espaço do usuário), que possui seu próprio conjunto dedicado de locais de memória (espaço de endereço virtual privado). Como o espaço de endereço virtual de cada aplicativo é particular, um aplicativo não pode alterar os dados que pertencem a outro aplicativo. Cada aplicativo é executado isoladamente e, se um aplicativo travar, a falha é limitada a esse aplicativo. Além de ser privado, o espaço de endereço virtual de um aplicativo no modo de usuário é limitado. Um processador em execução no modo de usuário não pode acessar endereços virtuais reservados para o sistema operacional. Limitar o espaço de endereço virtual de um aplicativo no modo de usuário impede que o aplicativo altere e possivelmente danifique dados críticos do sistema operacional.
Mas o que esses modos de processador têm a ver com containers? Cada container é apenas um "modo de usuário" do processador com alguns recursos adicionais, como isolamento de namespace, controle de recursos e o conceito de um sistema de arquivos. Isso significa que a Microsoft precisou adaptar o sistema operacional Windows para permitir o suporte a vários modos de usuário. Algo que foi muito difícil, considerando o alto nível de integração entre os dois modos nas versões anteriores do Windows.
Antes do lançamento do Windows Server 2016, cada sistema operacional Windows que usávamos consistia em um único "Modo de usuário" e "Modo de kernel". Desde a introdução do Windows Server 2016, é possível ter vários modos de usuário em execução no mesmo sistema operacional. A imagem a seguir fornece uma ideia global dessa nova arquitetura de modo multiusuário.
Observando os modos de usuário do Windows Server 2016/2019, podemos identificar dois tipos diferentes: o modo do usuário do host e os modos do usuário de "container" (blocos verdes). O modo de usuário do host é idêntico ao modo de usuário normal que estamos familiarizados em versões anteriores do Windows. O objetivo deste modo de usuário é hospedar os principais serviços e processos do Windows, como o gerenciador de sessões, o gerenciador de eventos e a rede.
Um novo recurso do Windows Server 2016 é que, quando você ativa o recurso de containers, esse Modo de Usuário do Host contém algumas tecnologias adicionais de gerenciamento de containers, que garantem que os containers funcionem no Windows. O núcleo dessa tecnologia de container é a abstração de Serviços de Computadores (bloco laranja), que expõe os recursos de container de baixo nível fornecidos pelo kernel por meio de uma API pública. Na verdade, esses serviços só contêm funcionalidade para iniciar conainers do Windows, rastreá-los enquanto estão em execução e gerenciar a funcionalidade necessária para a reinicialização. O restante da funcionalidade do Container Management é implementado no Docker Engine, como acompanhar todos os contêainers, armazenar imagens de containers, volumes etc. Esse mecanismo se comunica diretamente com as APIs de containers do Compute Services e usa a "Go language binding" oferecida pela Microsoft para fazer isso.
É desta forma que é possível rodar containers no Windows, agora você sabe com tudo funciona por "baixo dos panos". Para Windows, existe também a opção de utilizar containers Hyper-V, onde é possível criar uma camada maior ainda de isolamento, porém, este é um assunto para um próximo post assim como qual a diferença entre containers Linux e Windows.
Por hoje é só, grande abraço e até a próxima.
Tags: ContainerContainersContainers vs VMsContêinerDockerHyper-V containersWindows containersWindows Server Containers