Pesquisar conteúdos

Encontre uma trilha ou aula pelo assunto.

Experimente pesquisar por “governança”, “ITIL” ou “planejamento”.

Máquinas virtuais e contêineres: isolamento e compartilhamento

Compare hipervisores e contêineres pela forma como isolam ambientes, compartilham recursos e dependem do sistema hospedeiro.
Bancada artesanal compara máquinas virtuais com kernels próprios sobre um hipervisor e contêineres leves conectados a um único kernel compartilhado

Virtualizar é apresentar outra visão de um recurso

Virtualização cria uma representação controlada de algo físico ou global: processadores, memória, dispositivos, rede, armazenamento ou o próprio ambiente do sistema operacional. Duas técnicas podem parecer iguais para quem executa uma aplicação e ainda estabelecer fronteiras muito diferentes por baixo.

Uma máquina virtual, ou VM, recebe hardware virtual sobre o qual executa um sistema operacional convidado com kernel próprio. Um contêiner de sistema operacional reúne processos cuja visão e consumo de recursos são separados por mecanismos do kernel hospedeiro. No modelo mais comum de contêiner Linux, não existe um segundo kernel Linux escondido na imagem.

Esta aula compara arquiteturas. Ela não ensina uma plataforma específica de nuvem ou orquestração. Os conceitos de kernel, espaço de usuário e chamadas de sistema, processos e memória virtual formam a base para entender o que cada técnica separa e o que compartilha.

A máquina virtual começa pelo hardware virtual

O hipervisor, também chamado Virtual Machine Monitor, arbitra o acesso das VMs ao processador, à memória e aos dispositivos. Cada VM observa processadores virtuais, regiões de memória e dispositivos como controladores de disco e interfaces de rede. Sobre essa plataforma, o convidado inicializa firmware virtual, kernel, drivers, serviços e aplicações.

O processador moderno oferece extensões para executar código convidado e devolver controle ao hipervisor quando ocorre uma operação que precisa ser mediada. A memória exige outra tradução: o endereço virtual do processo é traduzido pelo kernel convidado para uma visão física do convidado, que por sua vez precisa corresponder à memória do hospedeiro. Recursos de tradução assistida por hardware reduzem o custo desse caminho.

E/S pode ser emulada, apresentando um dispositivo conhecido pelo convidado, ou paravirtualizada, usando drivers conscientes da plataforma virtual para cooperar com o hospedeiro. Em Hyper-V, por exemplo, partições filhas usam dispositivos virtuais e canais VMBus; no ecossistema KVM, um monitor de máquina virtual em espaço de usuário costuma complementar a interface oferecida pelo kernel. “Hipervisor” não designa necessariamente todo o conjunto de gerenciamento, emulação e armazenamento.

Classificações como hipervisor “tipo 1” e “tipo 2” ajudam a distinguir implantação direta sobre a plataforma de hardware de uma solução hospedada sobre outro sistema. Arquiteturas reais, porém, podem dividir funções entre hipervisor, kernel, partição privilegiada e processos de usuário. É mais preciso perguntar onde ficam drivers, gerenciamento e mediação do que concluir tudo pelo número do tipo.

Cada VM mantém seu próprio kernel

A fronteira de uma VM envolve um sistema convidado completo. Duas VMs no mesmo host podem executar kernels, versões e configurações diferentes, desde que a plataforma suporte a arquitetura e os dispositivos apresentados. Atualizar o kernel de uma não atualiza automaticamente o da outra.

Essa independência tem custo. Memória do kernel, serviços básicos, estruturas de página e armazenamento do sistema convidado aparecem em cada VM. Inicializar a instância inclui o boot daquele sistema. Técnicas de compartilhamento, ballooning, páginas esparsas e cache podem reduzir consumo físico, mas não tornam a sobrecarga nula nem garantem a capacidade prometida sob disputa.

Ao mesmo tempo, o kernel separado amplia a fronteira. Uma falha dentro do kernel convidado normalmente permanece naquela VM, salvo vulnerabilidade ou configuração que atravesse o hipervisor, dispositivos compartilhados ou plano de gerenciamento. Isso não torna a VM “segura por definição”: o hipervisor possui alto privilégio, imagens podem estar vulneráveis e redes, discos, credenciais e interfaces administrativas ainda precisam de proteção.

Máquinas virtuais possuem hardware virtual, sistema convidado e kernel próprios sobre um hipervisor, enquanto contêineres possuem aplicações e bibliotecas separadas sobre um kernel hospedeiro compartilhado
A VM virtualiza uma plataforma para outro sistema operacional. O contêiner virtualiza visões e controles oferecidos pelo sistema operacional que já está em execução.

Um contêiner é formado por processos do hospedeiro

Quando um runtime inicia um contêiner Linux, ele cria ou associa processos a namespaces, cgroups e outras políticas, prepara o sistema de arquivos e executa o comando configurado. Esses processos continuam sendo escalonados pelo mesmo kernel que atende o restante do host. Ferramentas no hospedeiro podem vê-los, embora a visão de dentro seja deliberadamente diferente.

O termo runtime abrange o componente que transforma uma configuração e um sistema de arquivos em processos isolados e acompanha seu ciclo de vida. Uma ferramenta de desenvolvimento, um daemon de alto nível, um runtime compatível com OCI e o kernel cumprem responsabilidades diferentes. Dizer que “o Docker é o contêiner” mistura produto, formato, gerenciamento e instância.

O contêiner não precisa carregar um sistema operacional completo, mas sua imagem normalmente contém bibliotecas, executáveis, arquivos de configuração e uma árvore de arquivos esperada pela aplicação. Uma distribuição presente na imagem fornece espaço de usuário; o kernel continua sendo o do hospedeiro. Por isso, ver arquivos de uma distribuição dentro do contêiner não prova que seu kernel também está ali.

Namespaces mudam o que os processos enxergam

Um namespace envolve um recurso global em uma abstração que parece própria aos processos participantes. O Linux oferece namespaces para diferentes dimensões, entre elas:

NamespaceVisão que pode ser separadaO que ele não resolve sozinho
PIDidentificadores e árvore de processosconsumo de CPU ou memória
mountmontagens e árvore de arquivospermissões sobre os objetos montados
networkinterfaces, rotas, sockets e portaspolítica externa de tráfego
IPCmecanismos de comunicação entre processostoda comunicação por rede ou arquivo
UTShostname e nome de domínioidentidade de segurança
usermapeamento de usuários, grupos e capabilitieslimites de recursos
cgroupvisão da posição na hierarquia de cgroupsos limites definidos pelos controladores
timedeterminados relógios por namespacerelógio físico e todas as fontes de tempo

Namespaces são combináveis e podem ser compartilhados seletivamente. Se uma configuração omite um tipo, o processo pode herdar a visão do runtime. Portanto, “está em um contêiner” não informa sozinho quais fronteiras existem. Compartilhar o namespace de rede ou PID pode ser intencional, mas muda o modelo de isolamento e precisa ser tratado explicitamente.

Um namespace de usuário permite mapear uma identidade privilegiada dentro do ambiente para uma identidade sem privilégio fora dele. “Root no contêiner” e root no host podem então ser credenciais diferentes. Sem esse mapeamento, ou com privilégios e dispositivos excessivos, o impacto potencial aumenta.

Cgroups controlam quanto um grupo pode consumir

Namespaces tratam principalmente de visão e identidade. Control groups, ou cgroups, organizam processos hierarquicamente para contabilizar e controlar recursos. No cgroup v2, controladores podem regular CPU, memória, E/S, quantidade de processos e outros recursos conforme o suporte do sistema.

Um limite de CPU não cria processadores. Ele restringe o tempo que o grupo pode receber; sob capacidade ociosa, políticas de peso podem permitir uso flexível. Um limite de memória também não reserva necessariamente todos os bytes antecipadamente. Pressão, recuperação de páginas e encerramento por falta de memória dependem dos limites e da carga real.

Dois erros opostos são comuns: iniciar contêineres sem limites e presumir que o isolamento visual impedirá exaustão; ou configurar um limite e tratá-lo como garantia de desempenho. Limite reduz o máximo permitido. Reserva, prioridade, afinidade, capacidade física e disputa respondem perguntas diferentes.

A aula de monitoramento e diagnóstico de recursos mostrou por que processos de um serviço devem ser observados como grupo. Em ambientes com contêineres, métricas do host, do cgroup e de dentro da instância podem discordar porque medem escopos diferentes.

O kernel compartilhado aplica várias barreiras

Contêiner seguro não nasce de um único mecanismo. Além de namespaces e cgroups, uma configuração Linux pode combinar:

  • identidade não privilegiada e namespace de usuário;
  • conjunto mínimo de capabilities, dividindo poderes tradicionalmente associados ao superusuário;
  • filtro seccomp para reduzir chamadas de sistema permitidas;
  • políticas de Linux Security Modules, como SELinux ou AppArmor;
  • sistema de arquivos somente leitura onde possível;
  • montagens, dispositivos e segredos estritamente necessários;
  • opção que impede ganhar novos privilégios durante exec;
  • correções no kernel, runtime e componentes de gerenciamento.

Essas camadas não são intercambiáveis. Seccomp reduz superfície de syscall, mas não limita memória. Cgroups limitam recursos, mas não decidem quais arquivos podem ser abertos. Namespace de montagem muda a visão, mas uma montagem ampla do host pode reintroduzir acesso sensível.

Um modo “privileged”, capabilities amplas, dispositivos do host, socket do gerenciador ou diretórios críticos montados dentro da instância podem atravessar barreiras que o leitor imaginava existir. O risco não se resume à aplicação: o daemon e a API de gerenciamento possuem autoridade para criar ambientes e merecem proteção equivalente.

Processo de contêiner passa por namespaces, cgroups e redução de autoridade antes de usar o kernel compartilhado
Namespaces separam visões; cgroups contabilizam e controlam recursos; identidade, capabilities, seccomp, LSM e sistema de arquivos reduzem autoridade. Nenhuma camada substitui as demais.

Imagem e contêiner não são a mesma coisa

Segundo a especificação OCI, uma imagem reúne manifesto, configuração e camadas do sistema de arquivos. As camadas registram adições, alterações e remoções em relação às anteriores; a configuração informa parâmetros como executável, argumentos, ambiente, usuário e diretório de trabalho. Conteúdo identificado por digest muda de identidade quando seus bytes mudam.

A imagem é um artefato usado para criar instâncias. O contêiner é a execução preparada a partir desse artefato e de uma configuração concreta. Vários contêineres podem partir da mesma imagem e ainda receber redes, limites, segredos e volumes diferentes.

Uma tag legível pode ser movida para outro manifesto; um digest identifica conteúdo específico. Para reprodutibilidade, saber exatamente qual imagem foi verificada é mais forte do que confiar apenas em um nome mutável. Isso não garante que o conteúdo seja seguro: procedência, assinatura, inventário, atualização e análise continuam necessários.

“Imagem imutável” também exige precisão. As camadas referenciadas são tratadas como conteúdo fixo; a instância normalmente ganha uma camada gravável e pode alterar seu estado durante a execução. Descartar o contêiner pode remover essa camada. Dados que precisam sobreviver devem usar armazenamento com ciclo de vida deliberado e backup compatível.

Disco virtual, camada gravável e volume têm ciclos diferentes

Uma VM costuma enxergar um ou mais discos virtuais. Eles podem ser arquivos, volumes ou dispositivos fornecidos por outra camada, mas o convidado os trata como dispositivos de bloco e mantém seus próprios sistemas de arquivos. Clonar um disco-base, criar snapshot ou anexar outro volume são operações da plataforma e não substituem backup consistente da aplicação.

No contêiner, a raiz pode ser composta por camadas da imagem mais uma camada gravável da instância. Um volume ou montagem externa liga dados cujo ciclo não deve depender daquele contêiner. Apagar a instância e criar outra da mesma imagem não recupera automaticamente dados que estavam apenas na camada descartada.

Persistência não define sozinha a arquitetura. Há contêineres com volumes duráveis e VMs descartáveis. A pergunta correta é: qual estado existe, quem o possui, onde é persistido, como é protegido e como será restaurado? A aula sobre atualizações, backup, recuperação e tolerância a falhas trata esse ciclo de forma canônica.

Imagem em camadas cria um contêiner com camada gravável e volume externo, enquanto um modelo cria uma máquina virtual com disco próprio e armazenamento persistente
Artefatos originam instâncias, mas dados persistentes precisam de ciclo de vida próprio. Recriar uma instância não equivale a restaurar seu estado.

Rede virtual continua sendo rede

VMs e contêineres podem receber interfaces virtuais conectadas a bridges, switches virtuais, roteamento, tradução de endereços ou redes sobrepostas. A fronteira de execução não elimina conceitos de endereço, porta e rota. Eles continuam canônicos na trilha de Redes de Computadores.

Um namespace de rede dá à instância sua própria visão de interfaces e sockets, mas conectividade surge da configuração feita ao redor. Publicar uma porta normalmente instala algum caminho entre a rede externa e o processo; não copia a porta nem transforma automaticamente o serviço em seguro. Da mesma forma, uma interface virtual de VM ainda depende do switch virtual, das políticas e do caminho físico.

Portabilidade depende de kernel, arquitetura e ambiente

Uma imagem de contêiner empacota o espaço de usuário e seus padrões de execução, mas não leva qualquer kernel para qualquer destino. O manifesto possui plataforma, sistema operacional e arquitetura. O runtime e o host precisam oferecer ABI e recursos compatíveis. Dispositivos, capabilities, módulos, montagem e políticas podem variar.

Uma VM transporta um ambiente mais completo, inclusive kernel convidado, mas ainda depende de arquitetura suportada, formato de disco, firmware, dispositivos virtuais e recursos do hipervisor. Migrar entre plataformas pode exigir conversão ou drivers. Emulação de outra arquitetura é uma técnica distinta e pode impor custo relevante.

Assim, “funciona em qualquer lugar” deve significar “o artefato e seus requisitos foram declarados e validados nos destinos suportados”, não ausência de dependências. Quanto mais a aplicação exige características específicas do host, menor a portabilidade prática.

Leveza e velocidade são resultados, não definições

Contêineres frequentemente iniciam mais rápido e ocupam menos memória porque não precisam inicializar outro kernel e podem compartilhar camadas de imagem. Essa tendência não garante menor consumo para qualquer aplicação. Um processo pesado continua pesado, a camada de rede pode adicionar custo e limites mal ajustados podem causar contenção.

VMs carregam mais componentes, mas oferecem kernel próprio, compatibilidade com outro sistema convidado e uma fronteira útil para cargas com requisitos diferentes. A aceleração por hardware e drivers paravirtualizados pode entregar desempenho próximo do nativo em muitos cenários, sem torná-lo idêntico em toda operação.

Compare com medidas que representem a carga: tempo de inicialização, memória residente, latência, vazão, densidade, interferência entre vizinhos, tempo de atualização e recuperação. Um benchmark sem versão, configuração e condição de disputa não decide a arquitetura.

VMs e contêineres podem trabalhar juntos

A escolha não precisa ser exclusiva. É comum executar contêineres dentro de VMs: o hipervisor separa grupos ou locatários com kernels próprios; dentro de cada convidado, contêineres padronizam aplicações e controlam processos. Essa composição adiciona camadas de observação, rede, armazenamento e atualização, mas pode corresponder melhor ao risco e à operação.

Uma decisão responsável considera:

NecessidadeTendência a favorecerCondição a verificar
kernel ou sistema operacional diferenteVMarquitetura e suporte do hipervisor
alta densidade de processos semelhantescontêinerlimites e compatibilidade com o kernel
fronteira entre cargas pouco confiáveisVM ou sandbox reforçadomodelo de ameaça e tecnologia concreta
distribuição reproduzível da aplicaçãoimagem de contêinerprocedência, plataforma e configuração externa
dispositivo ou driver específicodependeforma de exposição e impacto no isolamento
combinação de locatários e microsserviçoscontêineres em VMscusto e responsabilidade de cada camada

Não escolha apenas pela popularidade. Identifique a fronteira de confiança, o kernel necessário, o estado persistente, a capacidade, o tempo de inicialização e quem atualizará cada camada.

Observe a fronteira antes de confiar nela

No Linux, consultas somente de leitura ajudam a reconhecer namespaces e cgroups do processo atual:

readlink /proc/self/ns/*
cat /proc/self/cgroup
cat /proc/self/status
cat /proc/self/mountinfo

Entradas de namespace exibem identificadores; o arquivo de cgroup mostra a posição visível na hierarquia; status inclui identidades e conjuntos de capabilities em formato codificado; mountinfo descreve a visão de montagens. Acesso, campos e interpretação dependem do kernel e das permissões.

Essas saídas não certificam isolamento. Elas ajudam a confirmar o que o processo vê. A avaliação completa exige também a configuração externa do runtime, limites efetivos, montagens, dispositivos, rede, políticas de segurança e autoridade do plano de gerenciamento.

Erros comuns

  • “Contêiner é uma VM pequena.” No modelo de sistema operacional, ele é um conjunto de processos isolados sobre o kernel hospedeiro.
  • “A imagem contém seu próprio kernel.” Imagens comuns carregam espaço de usuário; o kernel vem do host.
  • “Namespace limita CPU e memória.” Visão e controle de consumo são responsabilidades diferentes; cgroups cumprem a segunda.
  • “Cgroup reserva desempenho.” Limite, peso, reserva e capacidade física não são sinônimos.
  • “Root dentro sempre é root fora.” Namespace de usuário pode mapear identidades, mas isso depende da configuração.
  • “Contêiner impede qualquer acesso ao host.” Privilégios, devices, capabilities e montagens podem enfraquecer a fronteira.
  • “VM é invulnerável porque tem kernel próprio.” Hipervisor, gerenciamento, imagens e integrações também possuem risco.
  • “Tag identifica conteúdo imutável.” Tags podem mudar; digest identifica o conteúdo referenciado.
  • “Apagar um contêiner não afeta dados.” Estado na camada gravável pode desaparecer; volumes têm outro ciclo.
  • “Snapshot é backup.” Ele pode depender da origem e capturar estado inconsistente; recuperação precisa ser planejada e testada.
  • “Contêiner sempre é mais rápido.” O resultado depende da carga, configuração e recurso medido.
  • “VM e contêiner são alternativas incompatíveis.” Eles podem formar camadas complementares.

O que você deve guardar

Máquinas virtuais recebem uma plataforma virtual e executam sistemas convidados com kernels próprios. Contêineres de sistema operacional executam processos sobre um kernel compartilhado, combinando namespaces para separar visões, cgroups para controlar consumo e políticas adicionais para reduzir autoridade.

Imagem é artefato; contêiner é instância. Disco-base é artefato; VM é instância. Camadas graváveis, discos e volumes possuem ciclos de persistência diferentes. Nem a imagem nem o isolamento substituem procedência, atualização, limites, monitoramento e backup.

Referências