Containers (Docker)¶
Máquinas virtuais x Containers¶
Definição: Máquina Virtual (VM)
Permite executar sistemas operacionais completos de forma isolada, garantindo segurança e compatibilidade entre ambientes diferentes — cada VM roda seu próprio Guest OS completo sobre um hypervisor. Exige mais recursos (cada VM precisa de um SO inteiro) e tem inicialização lenta (minutos).
Definição: Container
Alternativa mais leve e rápida às VMs: compartilha o kernel do sistema hospedeiro, isolando apenas processos e dependências — sem precisar de um sistema operacional Guest completo por unidade. Ideais para microsserviços, pipelines de CI/CD e aplicações que precisam escalar rapidamente, além de oferecerem portabilidade e fácil replicação.
| Característica | Máquinas virtuais (VMs) | Containers |
|---|---|---|
| Isolamento | Completo, com sistema operacional próprio | Compartilham o kernel do host, isolamento a nível de processo |
| Desempenho | Maior sobrecarga devido à virtualização | Mais leves e rápidos para iniciar |
| Consumo de recursos | Alto (cada VM precisa de um SO completo) | Baixo (apenas a aplicação e suas dependências) |
| Portabilidade | Portáveis, mas mais pesados para mover | Altamente portáveis e fáceis de replicar |
| Tempo de inicialização | Lento (minutos) | Rápido (segundos) |
| Persistência de dados | Persistente por padrão | Necessário configurar volumes de persistência |
| Uso ideal | Ambientes que exigem isolamento total ou SOs diferentes | Microsserviços, pipelines de CI/CD, aplicações escaláveis |
Definição: Quando escolher cada abordagem
VMs são recomendadas quando há necessidade de isolamento total, ou execução de sistemas operacionais diferentes entre si. Containers oferecem maior agilidade no desenvolvimento e na implantação. A escolha depende do contexto: nível de isolamento necessário e objetivos de escalabilidade.
Por baixo dos panos: namespaces, cgroups e LXC¶
Todo tipo de virtualização trata de dividir recursos e isolar os inquilinos (tenants).
- Virtualização completa: o hypervisor emula uma máquina (BIOS, drivers, memória). Os guests podem ser PV (paravirtualização: o guest conhece o host e usa o kernel para acessar dispositivos, com boa performance) ou HVM (extensões de hardware e camadas de software, como o QEMU, emulam os dispositivos).
- Virtualização em nível de sistema operacional (contêineres): isolam mais de uma instância de user space sobre o mesmo kernel. No Linux, o isolamento vem dos namespaces (cada contêiner vê só os seus processos, rede, sistema de arquivos, usuários) e o controle de consumo vem dos cgroups (control groups).
Definição: cgroups
Recurso do kernel Linux que agrupa processos e limita/contabiliza CPU, memória, E/S e rede. Ao passar do limite de memória do grupo, o kernel tenta recuperar memória e, em último caso, o OOM Killer mata o maior processo do grupo — é o que acontece com um contêiner que excede o seu limite. Os cgroups também servem fora de contêineres.
- Um contêiner não é uma VM completa: é um sistema de arquivos raiz (root filesystem) mais processos
isolados; não carrega kernel nem drivers. Por isso inicia em segundos e sobrecarrega muito menos. O
LXC é o conjunto de ferramentas para manipular contêineres diretamente (
lxc-create,lxc-start,lxc-console); do host se veem os processos do contêiner, mas de dentro dele só o que o isolamento permite. Docker, Kubernetes e Mesos constroem sobre esses mesmos princípios. - VMs e contêineres não se anulam: dividem recursos de formas complementares.
Camadas e princípios do Docker: cada instrução do Dockerfile (FROM, RUN, ADD/COPY, CMD) gera
uma camada do sistema de arquivos da imagem, reutilizável e versionada em repositórios; as imagens só
contêm arquivos. A convenção é um processo por contêiner (sem SSH): contêineres pequenos se compõem
em arquiteturas maiores (composability), orquestrados por Compose/Kubernetes. Portas: -p porta_do_host:porta_do_container;
docker run -d executa em segundo plano; docker ps, docker inspect, docker kill.
Docker¶
Definição: Docker
Ferramenta principal para criação e gerenciamento de containers, usando imagens compostas por camadas reutilizáveis, armazenadas em repositórios remotos (registries).
Definição: docker run -p host:container imagem
Executa um container a partir de uma imagem, expondo uma porta do container para
o host — no exemplo, quem acessa http://localhost:8080 no host chega à porta 80
dentro do container rodando Nginx. Outros exemplos comuns: bancos de dados
(docker run --name mysql-db -e MYSQL_ROOT_PASSWORD=senha -d -p 3306:3306 mysql) ou
um cache Redis (docker run -d -p 6379:6379 redis) — o Docker elimina a necessidade
de instalar esses softwares diretamente no sistema operacional.
Definição: Docker Hub
Repositório central (registry) onde é possível encontrar e compartilhar imagens de containers — o equivalente, para imagens Docker, de um repositório de código-fonte. Permite buscar imagens oficiais e compartilhadas pela comunidade, publicar imagens próprias, e integrar com pipelines de CI/CD.
Docker Compose¶
Definição: Docker Compose
Ferramenta que permite definir e coordenar, de maneira simplificada, todas as etapas
necessárias para a execução de uma ou mais aplicações Docker — configurando todos os
serviços, dependências e configurações num único arquivo YAML
(docker-compose.yaml), facilitando o gerenciamento e a automação do ciclo de vida
da aplicação.
version: '3.8'
services:
web:
image: nginx
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
db:
image: postgres
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
version: define a versão da especificação do Docker Compose usada.services: define os containers que farão parte da aplicação.image: define a imagem Docker que será utilizada.ports: mapeia as portas entre o host e o container.volumes: mapeia os diretórios para persistência de dados.environment: define as variáveis de ambiente para o container.
| Comando | Descrição |
|---|---|
docker-compose up |
Inicia todos os serviços definidos no arquivo docker-compose.yaml |
docker-compose stop |
Para todos os serviços |
docker-compose down |
Para e remove todos os serviços, redes e volumes criados |
docker-compose ps |
Lista todos os containers gerenciados pelo Docker Compose |
docker-compose logs |
Exibe logs de todos os serviços |
docker-compose build |
Constrói ou reconstrói os serviços |
docker-compose exec nome_servico comando |
Executa um comando dentro de um container gerenciado pelo serviço definido |
Rede entre containers¶
Definição: Containers são isolados uns dos outros por padrão
Por padrão, o Docker executa cada container em redes isoladas e independentes
entre si — mesmo dois containers rodando na mesma máquina host não conseguem se
comunicar diretamente usando localhost, porque cada um entende localhost como
o próprio container que fez a requisição, não o host nem outros containers.
# 1. Criar uma rede
docker network create minha-rede
# 2. Executar os containers na mesma rede
docker run --network minha-rede --publish 8280:8280 --detach --name echoservice echoservice:1.0
docker run --network minha-rede --publish 8180:8180 --detach --name callerservice callerservice:1.0
Definição: Comunicação entre containers pelo nome
Colocar dois ou mais containers na mesma rede Docker permite que eles se
comuniquem entre si usando o nome do container como hostname, em vez de
localhost ou um IP fixo — um callerservice configurado para chamar
http://echoservice:8280/echo (usando o nome do outro container) funciona
corretamente dentro da rede, mesmo que http://localhost:8280/echo não funcionasse.
No Docker Compose, todos os serviços de um mesmo arquivo docker-compose.yaml
compartilham automaticamente a mesma rede, então essa comunicação por nome já
funciona pronta, sem precisar criar a rede manualmente.
Kubernetes¶
Docker Compose resolve bem o desenvolvimento local, mas levanta questões novas em produção: o que acontece se a máquina cair? Como garantir que os serviços mais acessados tenham mais réplicas rodando, balanceando a carga entre elas? Como conseguir deploys isolados por aplicação, escalar automaticamente com base em métricas, ou substituir uma versão por outra gradualmente, sem indisponibilidade?
Definição: Kubernetes (K8s)
Plataforma open source para orquestração de containers, projetada para automatizar a implantação, o dimensionamento, a gestão e a operação de aplicações em escala — coordenando centenas ou milhares de containers de forma resiliente e escalável. Originalmente desenvolvido pelo Google (inspirado no sistema interno Borg), foi doado publicamente em 2014 à Cloud Native Computing Foundation (CNCF). Adotado por todos os grandes provedores de nuvem (Amazon EKS, Google GKE, Microsoft AKS), oferecendo portabilidade entre eles e evitando vendor lock-in.
Definição: Componentes principais do Kubernetes
O cluster é composto por um nó mestre (control plane) e múltiplos nós de trabalho (worker nodes): o mestre gerencia o estado desejado do sistema, decidindo onde e como os containers devem ser executados; os nós de trabalho hospedam os containers de fato. O Pod é a menor unidade de implantação — geralmente encapsula um ou mais containers com recursos e rede compartilhados. Por meio de objetos declarativos como Deployments, Services, ConfigMaps, Secrets, Volumes e Ingresses, é possível definir o comportamento desejado da aplicação e deixar que o Kubernetes tome as decisões necessárias para manter esse estado.
Definição: Self-healing
Um dos grandes diferenciais do Kubernetes: ele monitora constantemente o estado das aplicações e toma ações corretivas automáticas quando necessário — reiniciar containers falhos, mover pods para outros nós em caso de falha de hardware, ou escalar aplicações com base em métricas definidas — sem intervenção manual.
| Recurso / Benefício | Kubernetes | Docker Compose |
|---|---|---|
| Escalabilidade horizontal automática | Permite self-scaling baseado em métricas de CPU, memória e métricas customizadas | Não possui suporte nativo para self-scaling |
| Alta disponibilidade (HA) | Distribui pods em múltiplos nós, garantindo continuidade mesmo com falhas de máquinas | Limitado a um único host, sem HA nativo |
| Self-healing | Reinicia ou reprograma containers automaticamente em caso de falhas | Não possui self-healing por padrão |
| Deploys e rollbacks com estratégia | Suporta rolling updates e rollbacks controlados | Apenas substitui containers, sem controle de versão de deploy |
| Service discovery e load balancing | DNS interno e balanceamento de carga automático entre réplicas | Requer configuração manual ou ferramentas externas |
| Observabilidade integrada | Integra-se facilmente com Prometheus, Grafana, Loki, Tempo e outros | Não possui controle de acesso nativo |
| Segurança e controle de acesso (RBAC) | Controle de permissões por usuário, namespace ou recurso | Sem suporte a RBAC |
| Gerenciamento declarativo via YAML | Configuração como código para facilitar CI/CD e versionamento | Tem suporte a YAML, mas com menos granularidade e recursos limitados |
| Orquestração em múltiplas máquinas | Gerencia aplicações em clusters com múltiplos nós | Limitado a um único host (Swarm está obsoleto) |
| Compatibilidade com cloud e híbrido | Suporte nativo para GKE, EKS, AKS, OpenShift e outros provedores | Não é usado em ambientes cloud-native empresariais |
Definição: Extensibilidade e CRDs
Outro ponto forte do Kubernetes é sua extensibilidade: suporta plugins e integrações com sistemas de monitoramento, segurança, autenticação, redes e storage, além de permitir a criação de CRDs (Custom Resource Definitions) para adaptar o cluster a casos de uso específicos — um marco na consolidação do conceito de infraestrutura como código (IaC) e no movimento cloud-native.
Definição: Minikube — Kubernetes local
Para estudo e desenvolvimento local, o Minikube é um emulador que permite instalar e rodar um cluster Kubernetes de nó único na própria máquina, sem exigir acesso a um provedor de nuvem.