Como uma imagem de container vira um sistema de arquivos executável?
Se o container é um processo isolado, de onde surgem /bin, /etc, bibliotecas e todos os arquivos que ele acredita serem seu computador?
namespaces · cgroups · mounts · signalsVOCABULÁRIO VISUAL
As peças do kernel que entram em cena.
No Linux, arquivos de vários dispositivos e pseudo-filesystems aparecem numa única árvore. O rootfs é a árvore que o processo passa a enxergar como /. Isso conecta a série ao RaizFS: diretórios organizam nomes, enquanto mounts ligam árvores diferentes.
| Objeto | O que é | Ciclo de vida |
|---|---|---|
| Imagem | camadas imutáveis + manifesto | reutilizável |
| Container | configuração + processo + camada gravável | até remoção |
| Volume | dados externos montados | independente do container |
chroot muda um caminho, não cria uma fronteira completa.chroot altera a resolução de caminhos para um processo, mas não separa mounts, PIDs, rede nem recursos; processos privilegiados podem escapar em cenários conhecidos. No Casulo, preparamos a árvore num mount namespace e usamos pivot_root para tornar a raiz nova ativa e abandonar a antiga.
ANTES DEPOIS DO pivot_root
host / imagem /
└─ /var/lib/casulo/merged ├─ /bin
├─ /etc
├─ /proc ← montado no namespace
└─ /.old ← desmontado e removidoMontamos /proc depois de entrar no PID namespace, garantindo que a árvore de processos combine com a visão interna.
Como no artigo do compactador, precisamos de manifesto, conteúdo e integridade. O formato didático .cas guarda uma configuração e uma lista ordenada de hashes.
{
"format": "casulo.image.v1",
"entrypoint": ["/bin/servidor"],
"env": ["MODO=producao"],
"layers": ["sha256:91af...", "sha256:3b02..."]
}Cada camada é endereçada pelo hash de seu conteúdo. Dois manifestos com a mesma base referenciam os mesmos bytes. O Casulo calcula o hash ao importar e antes de montar; corrupção não vira uma camada silenciosa.
# Casulo.toml
base = "./bases/minima.tar"
copy = [["./servidor", "/bin/servidor"]]
entrypoint = ["/bin/servidor", "--porta", "8080"]
env = ["MODO=producao"]Não copiamos Dockerfile: nosso formato possui apenas as operações explicadas. O construtor valida destinos relativos à raiz, rejeita .., normaliza permissões, empacota cada mudança e grava atomicamente em store/blobs/sha256/.
$ casulo build -f Casulo.toml -t servidor:1
camada 91af… reutilizada
camada 3b02… criada (184 KiB)
imagem servidor:1 → manifestos/7d9c….json
$ casulo images
NOME ID CAMADAS TAMANHO ÚNICO
servidor:1 7d9c… 2 184 KiBmerged/ ← visão entregue ao processo ▲ ├─ upper/ alterações deste container ├─ work/ área técnica do OverlayFS └─ lower/ camada app : camada base (somente leitura) leitura: procura de upper para lower escrita: copia o arquivo para upper e modifica a cópia
Ao remover o container, upper pode desaparecer; as camadas da imagem permanecem. Whiteouts representam remoções na visão superior sem apagar a camada inferior.
Um volume gerenciado vive em diretório validado do Casulo e é montado dentro do rootfs. Um bind mount expõe caminho explícito do host. O segundo é mais perigoso: o Casulo exige caminho absoluto permitido e modo ro ou rw.
container A ── /dados ─┐
├── volume clientes
container removido ────┘ │ permanece
container B ── /dados ─────────┘resolver nome → verificar manifesto → verificar hashes → criar upper/work/merged → montar OverlayFS → montar volumes e /proc → pivot_root → executar entrypoint → desmontar em ordem inversa
$ sudo casulo run servidor:1 --volume clientes:/dados
[casulo] image=7d9c… layers=2 writable=01J…
servidor ouvindo em :8080O mesmo hash é reutilizado por duas imagens; alterar arquivo cria cópia somente em upper; a camada original mantém hash; volume sobrevive à remoção; falha após o terceiro mount desmonta exatamente três recursos.
O Casulo 0.2 monta um rootfs isolado e gravável, mas o processo ainda pode consumir toda CPU e memória e sua rede não possui topologia própria. O próximo capítulo adicionará cgroups, redução de privilégios, network namespace e ciclo de vida observável.
Fontes: pivot_root(2), documentação oficial do OverlayFS e OCI Image Specification.
PROJETO COMPLETO · ESTADO EXATO DESTE CAPÍTULO
Baixe o Casulo 0.2.
Pacote exclusivo deste artigo, com código Rust, exemplos, testes condicionais para Linux e roteiro de limpeza. Não execute em produção nem use imagens desconhecidas.