Cloud

O que é um contêiner (Docker)? Guia completo

O que é um contêiner, em que ele difere de uma máquina virtual, o que são namespaces, cgroups e camadas de imagem — o conceito por trás de Docker, containerd e Kubernetes.

Redação Bytezine

Redação Bytezine

08 de setembro de 2026· 9 min de leitura

O que é um contêiner (Docker)? Guia completo

Um contêiner é uma forma de empacotar uma aplicação junto com tudo que ela precisa para rodar — código, bibliotecas, variáveis de ambiente, dependências de sistema — de um jeito que funciona igual em qualquer máquina com um runtime compatível instalado. Ele não é uma máquina virtual reduzida, não tem um sistema operacional próprio dentro dele, e não é sinônimo de Docker: Docker é só a ferramenta que popularizou o conceito.

Este texto explica o que sustenta essa ideia por baixo: o que diferencia um contêiner de uma VM, o que são namespaces e cgroups (as duas peças do kernel Linux que tornam isso possível), como uma imagem se transforma em um contêiner em execução e onde esse modelo tem limites reais. Sem isso, uma comparação entre ferramentas de orquestração de contêineres fica pela metade — dá para escolher a ferramenta certa sem entender o problema que ela resolve.

O que é um contêiner, na prática

Tecnicamente, um contêiner é um processo (ou grupo de processos) do sistema operacional do host, isolado dos demais por dois mecanismos do kernel Linux: namespaces, que limitam o que o processo consegue ver, e cgroups, que limitam quanto de CPU, memória e outros recursos ele pode consumir. A documentação do Kubernetes resume o resultado prático: um contêiner empacota uma aplicação junto com suas dependências de runtime de um jeito repetível — o mesmo contêiner se comporta do mesmo jeito no laptop do desenvolvedor, no ambiente de staging e em produção.

  • Leve: compartilha o kernel do host, então não carrega um sistema operacional completo dentro dele — só o que a aplicação precisa.
  • Portátil: a imagem que gera o contêiner roda igual em qualquer host com um runtime compatível.
  • Imutável por design: a orientação da documentação do Kubernetes é não alterar um contêiner em execução — mudanças exigem construir uma nova imagem.
  • Efêmero: por padrão, tudo que é escrito dentro do contêiner se perde quando ele é destruído, a menos que exista um volume apontando para fora dele.

Contêiner não é máquina virtual

A confusão mais comum é tratar contêiner como “uma VM mais leve”. Não é. Uma VM virtualiza hardware: cada uma roda seu próprio sistema operacional completo, isolado por um hypervisor. Um contêiner virtualiza apenas o sistema operacional — todos os contêineres em um host compartilham o mesmo kernel. É essa diferença que explica por que contêineres iniciam em milissegundos e pesam megabytes, enquanto VMs levam segundos (ou minutos) e pesam gigabytes.

  • Abstração: contêiner isola no nível da aplicação; VM isola no nível do hardware.
  • Peso típico: contêiner, dezenas de MB; VM, dezenas de GB — segundo a própria Docker.
  • Kernel: contêineres compartilham o kernel do host; cada VM roda um sistema operacional completo.
  • Inicialização: contêiner sobe em milissegundos; VM leva o tempo de um boot completo.

Regra prática: contêiner virtualiza o sistema operacional. Máquina virtual virtualiza o hardware. Uma coisa não substitui a outra — é comum rodar contêineres dentro de VMs, e boa parte dos provedores de nuvem faz exatamente isso.

O que roda por baixo: namespaces e cgroups

Namespaces são o mecanismo de isolamento: cada tipo de namespace limita o que um processo consegue ver de um recurso do sistema. Um contêiner normalmente combina vários — de PID (o contêiner só vê os próprios processos, começando do PID 1), de rede (interface e tabela de rotas próprias), de mount (sua própria visão do sistema de arquivos), de UTS (hostname próprio) e de usuário (mapeamento de UID/GID isolado do host).

Cgroups (control groups) fazem o outro lado do trabalho: não isolam visão, limitam consumo. É o cgroup que impede um contêiner de tomar toda a CPU ou memória do host — e é por isso que flags como as do exemplo abaixo existem: elas configuram cgroups por trás dos panos.

bash
docker run --memory="512m" --cpus="1.0" minha-aplicacao

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

Imagem é o pacote: um arquivo somente leitura com tudo que a aplicação precisa para rodar — código, runtime, bibliotecas, valores padrão de configuração, conforme a definição da documentação do Kubernetes. Contêiner é a instância em execução dessa imagem, com uma camada extra e gravável por cima. A mesma imagem pode gerar quantos contêineres forem necessários, cada um com sua própria camada de escrita — destruir um contêiner não afeta a imagem que o originou.

Como as imagens são construídas: camadas e union filesystem

Cada instrução de um Dockerfile que muda o sistema de arquivos — RUN, COPY, ADD — gera uma nova camada. Um union filesystem (na prática, o driver overlay2 é o mais usado hoje) empilha essas camadas e apresenta ao contêiner uma visão só, mesclada. As camadas da imagem (lowerdir) são somente leitura; a camada do contêiner (upperdir) é a única gravável. Isso tem duas consequências práticas: camadas idênticas entre imagens diferentes são armazenadas uma única vez no disco, e escrever dentro de um contêiner só copia o arquivo modificado para a camada de cima — o chamado copy-on-write —, enquanto o resto continua compartilhado.

dockerfile
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]

A ordem das instruções importa por causa do cache de camadas: copiar primeiro o que muda menos (aqui, requirements.txt) e instalar as dependências antes de copiar o código-fonte permite que o Docker reaproveite a camada de dependências já construída sempre que só o código da aplicação mudar.

O padrão por trás do Docker: OCI, runc e containerd

Docker não é o único jeito de rodar contêineres — e não é mais uma peça obrigatória. Em junho de 2015, Docker, CoreOS e outras empresas da indústria criaram a Open Container Initiative (OCI) sob a Linux Foundation, para evitar que o formato de contêiner e o runtime que os executa ficassem fragmentados entre fornecedores concorrentes. A OCI mantém hoje três especificações: a Runtime Specification (como um contêiner é executado a partir de um pacote já descompactado em disco), a Image Specification (o formato de uma imagem — manifesto, configuração e camadas) e a Distribution Specification (como imagens são distribuídas entre registries).

runc é a implementação de referência da runtime-spec — o programa que de fato cria os namespaces, aplica os cgroups e inicia o processo do contêiner. containerd fica uma camada acima: cuida do ciclo de vida completo (baixar imagem, gerenciar armazenamento, supervisionar o contêiner em execução) e usa o runc por baixo. Docker Engine é a camada mais alta, com a experiência de linha de comando, rede e build de imagem — mas, segundo a própria Docker, o código relacionado à OCI é uma fração pequena da plataforma completa. Isso explica por que containerd (usado pelo próprio Docker e por boa parte dos clusters Kubernetes) e CRI-O (runtime enxuto criado especificamente para Kubernetes) conseguem rodar as mesmas imagens sem depender do Docker Engine.

Fontes desta seção: anúncio de criação da Open Container Initiative (Linux Foundation, junho de 2015) e o artigo oficial da Docker sobre as especificações OCI — ver seção de fontes ao final.

Onde os contêineres falham

O mesmo motivo que torna contêineres leves — compartilhar o kernel do host — é a limitação mais séria do modelo: o isolamento é mais fraco que o de uma VM. Segundo análises de segurança da Wiz e da Aqua Security, uma vulnerabilidade no kernel ou no runtime pode, em tese, ser usada para escapar do contêiner e alcançar o host ou outros contêineres — o chamado “container escape”. Uma VM tem o hypervisor como fronteira extra; um contêiner não tem esse segundo muro.

  • É stateless por padrão: qualquer coisa gravada dentro do contêiner some quando ele é recriado; dados que precisam sobreviver exigem volumes explícitos.
  • Não é a unidade certa para aplicações com interface gráfica ou que dependem de acesso direto e completo ao hardware do host.
  • Imagens mal construídas acumulam camadas desnecessárias e ficam pesadas — o problema que um Dockerfile bem escrito, com camadas ordenadas corretamente, evita.
  • Rodar como root dentro do contêiner reduz a eficácia do isolamento por namespace de usuário — a prática recomendada é rodar a aplicação com um usuário sem privilégios dentro da imagem.

Isolamento por contêiner não é uma fronteira de segurança equivalente à de uma VM. Não trate contêineres como sandbox suficiente para executar código não confiável sem camadas adicionais de isolamento (como gVisor ou Kata Containers).

De um contêiner isolado à orquestração

Rodar um contêiner isolado é simples. O problema aparece em produção: o que acontece quando ele trava, quando é preciso escalar de uma para cinquenta réplicas, quando um deploy precisa trocar a versão sem downtime? Isso deixa de ser trabalho manual e passa a ser trabalho de um orquestrador — que decide onde cada contêiner roda, reinicia o que falhou e distribui carga entre réplicas. É exatamente o problema que ferramentas de orquestração resolvem, e é o ponto em que comparar orquestradores passa a fazer sentido — mas essa já é outra pergunta, para outro texto.

Perguntas frequentes

Não. Contêiner é o conceito — um processo isolado por namespaces e cgroups, empacotado com suas dependências. Docker é uma plataforma que implementa esse conceito e virou sinônimo popular dele, mas containerd, CRI-O e Podman também criam e executam contêineres, inclusive usando o mesmo formato de imagem padronizado pela OCI.

#Docker#Contêineres#Kubernetes#Namespaces#Cgroups#OCI#containerd#runc#DevOps#Cloud#Infraestrutura#OverlayFS

Artigos relacionados

TODO DIA · 08:00

Receba o melhor da tecnologia direto no seu e-mail

O que saiu de novo em IA, programação e cloud, resumido. Só chega quando há artigo novo — sem spam e sem e-mail vazio.

bytezine — subscribe

Concordo em receber a newsletter do Bytezine no meu e-mail e posso cancelar quando quiser.