Máquinas Virtuais e Containers


A virtualização permite, essencialmente, desacoplar recursos lógicos dos recursos físicos subjacentes. Existem vários níveis de virtualização, ou desse tipo de abstração se assim preferir, nos sistemas computacionais. A própria definição de Sistema Operacional é a de oferecer uma máquina virtual padronizada aos usuários e aplicações. No funcionamento do computador utilizam-se memória virtual e volumes lógicos (LVM). E poderíamos esticar bastante esta lista.

Mas o tipo de máquina virtual que nos interessa aqui, os chamados hipervisores, tem sua história iniciada na década de 60 e foram se desenvolvendo para solucionar alguns problemas, ou gerar determinadas comodidades, como permitir retrocompatilidade e isolar aplicações e usuários, garantindo maior segurança e melhor utilização dos recursos. A partir de 1999, a virtualização ganhou novo impulso com a chegada à arquitetura x86 por meio da VMware e, em especial, com o acréscimo de suporte à virtualização em hardware nessa arquitetura promovidos pela Intel e AMD ao longo da década de 2000. Mais recentemente os containers se juntaram ao leque de opções para virtualização.

Além das aplicações mencionadas, explorarmos outras, e também algumas implicações da virtualização e conteinerização, bem como alguns de seus principais conceitos a seguir. Se você ainda não se convenceu da importância do tema, pode começar conferindo a lista de aplicações no último tópico "contextualizando".

Máquinas Virtuais

As máquinas virtuais são criadas através dos hipervisores, consistindo em uma abstração do hardware físico, ou seja, uma máquina puramente lógica, que se comporta como um computador real. Do ponto de vista do usuário, a máquina virtual (VM) é um sistema computacional como outro qualquer. Um usuário não tem como saber se está interagindo com uma máquina virtual ou com uma máquina física (bare metal). Do ponto de vista do kernel que executa a máquina virtual, a máquina virtual é um sistema puramente lógico e se constitui de uma série de arquivos que armazenam a configuração da máquina virtual, seu estado de memória, os conteúdo dos discos (memória secundária) da máquina virtual, arquivo de log e eventuais "instantâneos" da máquina virtual, os snapshots, uma espécie de "backup a quente" do sistema, que armazena o conteúdo da memória secundária e da memória principal, com todos os processos em execução, permitindo que se possa retornar àquele ponto posteriormente, clonar a VM, fazer com que a VM possa ser executada em outro host físico, etc.

A "mágica" é feita por um software chamado hipervisor (hypervisor) que é executado no sistema operacional da máquina física, juntamente com o monitor de máquinas virtuais (Virtual Machine Monitor). Como a máquina virtual é do ponto de vista lógico um computador como outro qualquer, ele também precisa de um sistema operacional, chamado de guest, ou convidado. Que pode ser diferente do sistema operacional da máquina física. Aliás, é possível haver múltiplas máquinas virtuais em execução em uma máquina física, todas com sistemas operacionais distintos. O que se precisa respeitar é a arquitetura computacional (x86, ARM) e a capacidade do sistema físico.

Há dois tipos de hipervisores. Os hipervisores tipo 1, também chamados de bare metal, que se constituem basicamente de um kernel de SO com as funções de hipervisor. É o tipo mais usado em servidores e datacenters. Nessas máquinas não usamos os recursos da máquina física, apenas das máquinas virtuais. A lista de exemplos inclui as soluções principais da VMware, Xen, versões do Microsoft Hyper-V e Linux KVM.



Os hipervisores tipo 2, ou hosted (hospedados), rodam como uma aplicação sobre um sistema operacional instalado em uma máquina física (host, ou hospedeira). Isso é feito porque normalmente também queremos rodar aplicações no sistema operacional host. Por exemplo, colocamos um servidor web na máquina virtual e usamos o navegador da máquina física para acessá-lo. A lista de exemplos aqui inclui o VMware workstation, a versão específica do Microsoft Hyper-V, Gnome Boxes e o VirtualBox.



Por se tratar de um software open source, gratuito, multiplataforma, fácil de usar e muito bom. O VirtualBox acaba sendo a melhor recomendação para quem deseja se iniciar no mundo da virtualização e, mesmo para os mais avançados, ainda é uma das melhores opções. Ele está disponível em https://www.virtualbox.org/.


Containers de Sistema - Linux Containers (LXC/LXD)


Site oficial do projeto: https://linuxcontainers.org/

 

Na prática eles possuem um comportamento muito similar ao de uma máquina virtual, mas na verdade são como que novas instâncias do sistema, implementando todas as técnicas disponíveis para isso. Tratam-se de "full system" containers, ou containers de máquina. Os containers Linux compartilham o kernel da máquina real, de modo a oferecer um isolamento do sistema sem todo o overhead de uma VM tradicional, tanto que vem sendo chamados de "lightervisors". Uma limitação dos containers é que ao compartilhar o kernel da máquina física (ou virtual) onde são executados, tratam-se de containers Linux rodando em máquinas Linux em com o mesmo kernel do host. Você pode trocar todas as bibliotecas e frameworks do seu container, mas o kernel será sempre o mesmo do host.



 

O kernel é compartilhado, mas é possível executar distribuições diferentes do sistema base no container. As imagens de sistema disponíveis oficialmente se encontram no link https://images.linuxcontainers.org e também é possível criar suas próprias imagens e publicá-las em um repositório público, ou mantê-las apenas para uso local.

 

Para isolar o container são usados recursos de segurança já existentes no mundo Unix/Linux, como chroot, cgroups, namespaces, etc. Embora em teoria esse isolamento seja inferior ao proporcionado por uma VM, na prática não há restrições para a maioria das aplicações.

 

É possível usar containers dentro de VMs e containers dentro de containers também. Também é possível fazer live migration de containers, tirar snapshots, gerar imagens de containers personalizadas, etc.

 

Ao se criar um container, ele compartilha exatamente os mesmos recursos da máquina real. Na verdade é uma aplicação rodando em bare metal mesmo! Mas é possível restringi-los da mesma forma que em um hipervisor tradicional. Por exemplo limitar a quantidade de CPUs vista pelo container, a memória, ou o espaço em disco.

 

Note que a ideia aqui é de um container de sistema completo, com "n" aplicações, diferentemente de containers de aplicação como Docker e Rocket (CoreOS), onde há um container para cada aplicação. Esse tipo de container também é chamado de container de processo. O conceito também é diferente de sistemas de distribuição de aplicação como o snap, que por vezes são referenciados como containers de pacotes, ou containers de pacotes de software, que encapsulam uma única aplicação em específico.


Os containers Linux funcionam excelentemente bem para a maioria das aplicações de servidores, mas ainda possuem limitações para configurações avançadas de rede e para a utilização de periféricos da máquina física dentro dos containers.


Acesse o Microtutorial de Containers LXC/LXD!



Containers de Aplicação


Conforme mencionado no item anterior, plataformas como Docker e Rkt são containers de aplicação. A ideia básica é que cada aplicação rode em um container, de forma a isolá-la do sistema operacional e das demais aplicações. E no caso estamos falando de cada aplicação mesmo ou, mais precisamente, de cada processo. Um sistema comercial que possua um banco de dados e mais três módulos rodaria em 4 containers, um para cada módulo e outro para o banco. A Docker firmou uma parceria com a Microsoft e agora suporta containers de aplicação Windows e Linux. Sim, você pode instalar Docker no Windows e talvez por isso ela tenha se tornado sinônimo de container. A plataforma Docker também cuida das máquinas virtuais necessárias para garantir que containers Windows e Linux possam ser executados em um mesmo SO host. Os containers de aplicação podem ser executados em bare metal, em uma máquina virtual, ou em um container de sistema. Outra plataforma relacionada é a Kubernetesque gerencia containers de aplicação, realizando sua orquestração. Lembre que uma máquina virtual compartilha os recursos físicos (hardware), enquanto containers compartilham o sistema operacional e os recursos físicos subjacentes, muito embora isolando as aplicações.


Há um outro tipo de container de aplicação em Linux que se consiste basicamente em encapsular uma aplicação com todas as suas dependências, de forma que ela possa ser instalada em qualquer distribuição e conviver com aplicações em um mesmo sistema mesmo que tenham dependências conflitantes. Há principalmente três dessas soluções hoje: Snapcraft, Flatpak e AppImage.



Contextualizando


Hipervisores tipo 1 são muito usados em servidores e datacenters para garantir maior segurança e disponibilidade, aproveitar melhor os recursos computacionais e financeiros, facilitar e centralizar o gerenciamento, etc. São essenciais para a infraestrutura moderna, da consolidação de servidores à viabilização da computação em nuvem.


O uso de máquinas virtuais e, especialmente, de containers, também viabilizou que as equipes de desenvolvimento e de operações pudessem trabalhar com a mesma infraestrutura e agilizar grandemente o processo de teste e entrega do software, viabilizando o DevOps (Development + Operations). Um desenvolvedor pode trabalhar com o mesmo ambiente onde o software será executado, sem surpresas. Aliás, o desenvolvedor pode definir o ambiente em que o software será executado.


Hipervisores tipo 2, que usamos em nossas máquinas no dia a dia, viabilizam uma série de aplicações que já bastariam para justificar conhecer e utilizar essa tecnologia. A saber:

  • Testar novos sistemas operacionais, ou novas versões de um sistema operacional;
  • Executar um servidor e deixar o sistema host atuar como cliente, o que pode ser muito útil para redes e desenvolvimento;
  • Desenvolver, ou testar, software para outro sistema operacional, ou outra versão do sistema operacional;
  • Testar softwares sem impactar o sistema em uso;
  • Realizar testes de segurança sem comprometer o sistema em uso;
  • Executar aplicações que necessitem de maior segurança ou que possam comprometer o desempenho do sistema em uso. Por exemplo, aqueles famigerados módulos de segurança para acesso a bancos;
  • Criar uma rede virtual;
  • Testar configurações impossíveis de se executar no hardware real como, por exemplo, um RAID 5 ou 6 quando se tem um único HD;
  • Etc!

A maioria dessas aplicações também se aplicam a containers sendo executados em um computador pessoal.


Outro detalhe relevante é que o desempenho de uma máquina virtual, ou container, é essencialmente o mesmo da máquina física. O assunto merece uma discussão mais aprofundada, mas é possível iniciá-la verificando os seguintes artigos de Iniciação Científica que este professor pôde orientar:

  • OLIVEIRA, E. J. A.; FARIAS, T. K.; COSTA, W. S. C.; OLIVEIRA, W. S.; VALIANTE FILHO, F. Análise de Desempenho de Máquinas Virtuais. 2016. [Artigo apresentado]
  • OLIVEIRA, E. J. A.; FARIAS, T. K.; COSTA, W. S. C.; VALIANTE FILHO, F. Análise de Desempenho de Máquinas Virtuais Executadas Simultaneamente em um Mesmo Sistema Hospedeiro. In: Seminário em Tecnologia da Informação Inteligente (SETII), 2016, São Paulo. Anais do SeTII 2016. São Paulo: Universidade Nove de Julho, 2016. v. 01. p. 103-110.



Referências


  • EMC Corporation. Information Storage and Management (ISM) v3. 2015.
  • TANENBAUM. Andrew. Sistemas Operacionais Modernos – 4ª ed. São Paulo: Pearson, 2016.