Docker: Ajuste de Performance e Resolução de Problemas

Última atualização: 2026-08-26

Está enfrentando problemas com contêineres no ambiente de produção — alto uso de CPU? Sobrecarga de memória? I/O lento? Você precisa de uma abordagem sistemática de resolução de problemas.

1. O Que Você Vai Aprender



2. Uma História Sobre um Alerta de Madrugada

(1) Ponto de Dor: Latência da API disparou de 50 ms para 5 s

A latência da API no ambiente de produção disparou de 50 ms para 5 s, gerando uma enxurrada de reclamações de usuários. Alice usou docker stats para descobrir que, embora o uso da CPU não estivesse alto, os tempos de espera de I/O estavam extremamente altos, e os contêineres pareciam estar "travados."

(2) Uma Abordagem Sistemática para Resolução de Problemas

Alice usou iostat para identificar que o driver de log estava causando o I/O de disco no limite; após trocar o driver de log, o problema foi resolvido.

BASH
# Etapa 1: Verificar uso de recursos
docker stats --no-stream

# Etapa 2: Verificar I/O do host
iostat -x 1 5

# Etapa 3: Identificar o gargalo
docker system df -v

(3) Benefícios: 5 segundos → 50 milissegundos, 10 minutos de tempo de recuperação

Levou apenas 10 minutos do alerta até a resolução — a resolução sistemática de problemas é 100 vezes mais eficiente do que simplesmente "tentar reiniciar."



3. Árvore de Decisão para Resolução de Problemas de Performance

(1) Os Quatro Principais Gargalos e Suas Ferramentas Correspondentes

100%
graph TB
    START["Problema de Performance"] --> CPU{"CPU alta?"}
    CPU -->|Sim| C1["docker stats<br/>top / htop"]
    CPU -->|Não| MEM{"Uso de memória alto?"}
    MEM -->|Sim| M1["docker stats<br/>/proc/meminfo"]
    MEM -->|Não| IO{"Espera de I/O alta?"}
    IO -->|Sim| I1["iostat -x<br/>docker system df"]
    IO -->|Não| NET{"Rede lenta?"}
    NET -->|Sim| N1["iperf / ping<br/>tcpdump"]

(2) Ferramentas Comuns de Resolução de Problemas

Ferramenta Função Caso de Uso
docker stats Uso de Recursos do Contêiner Visão Geral de CPU/Memória/I/O
docker system df Uso de Disco do Docker Resolução de Disco Cheio
docker events Fluxo de Eventos do Contêiner OOM/Reinício/Saída Anormal
docker logs Logs do Contêiner Erros de Aplicação
docker inspect Configuração do Contêiner Status/Código de Saída/Rede
iostat Estatísticas de I/O de Disco Gargalos de I/O
iperf Teste de Largura de Banda de Rede Gargalos de Rede
nsenter Entrar no Namespace do Contêiner Depuração Avançada


4. Resolução de Gargalos de CPU

▶ Exemplo: Monitorando Recursos com docker stats (Dificuldade: ⭐)

BASH
# Estatísticas em tempo real para todos os contêineres
docker stats

# Snapshot único
docker stats --no-stream

# Formato personalizado
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"

▶ Exemplo: Contêiner stress simula carga de CPU (Dificuldade: ⭐⭐)

BASH
# Executar stress para simular carga de CPU
docker run --rm --name stress-test \
  --cpus=1 \
  progrium/stress --cpu 1 --timeout 30s

# Monitorar com docker stats (em outro terminal)
docker stats stress-test --no-stream


5. Resolução de Gargalos de Memória

(1) Problemas Comuns de Memória

Sintoma Código de Saída Causa Solução
OOM Kill 137 Excedeu o limite --memory Aumentar o limite ou otimizar o uso de memória
Vazamento de Memória Aumento Gradual Bug na Aplicação Analisar um Heap Dump
Alto uso de cache 0 Cache do sistema de arquivos Comportamento normal (pode ser recuperado)

▶ Exemplo: Simulando um OOM de Contêiner (Dificuldade: ⭐⭐⭐)

BASH
# Iniciar contêiner com limite de 50 MB de memória
docker run -d --name oom-test \
  --memory=50m \
  --restart=on-failure:3 \
  progrium/stress --vm 1 --vm-bytes 100M --timeout 10s

# Observar eventos OOM
docker events --filter event=oom --since 1m

# Verificar código de saída
docker inspect oom-test --format='ExitCode: {{.State.ExitCode}}, OOMKilled: {{.State.OOMKilled}}'


6. Resolução de Gargalos de I/O de Disco

▶ Exemplo: Análise de Disco com docker system df (Dificuldade: ⭐⭐)

BASH
# Mostrar uso de disco do Docker
docker system df

# Detalhamento completo
docker system df -v
💻 Saída:

TEXT 📖 Somente leitura
TYPE            TOTAL   ACTIVE  SIZE      RECLAIMABLE
Images          12      5       4.2GB     2.8GB (66%)
Containers      8       3       350MB     280MB (80%)
Local Volumes   5       3       1.2GB     500MB (41%)
Build Cache     45      0       800MB     800MB (100%)

▶ Exemplo: Política de Limpeza de Disco (Dificuldade: ⭐⭐)

BASH
# Remover dados não utilizados (imagens, contêineres, volumes, cache de build)
docker system prune

# Mais agressivo: remover todas as imagens não utilizadas (não apenas dangling)
docker system prune -a

# Remover apenas o cache de build
docker builder prune

# Remover volumes (AVISO: exclui dados)
docker volume prune

(1) Comparação de Drivers de Armazenamento

Driver Performance Estabilidade Recomendação
overlay2 Alta ✅ Estável ✅ Recomendação padrão
aufs Média ❌ Kernel antigo ❌ Obsoleto
devicemapper Baixa ❌ Configuração complexa ❌ Não recomendado
zfs Média ✅ Estável Cenários específicos
btrfs Média ❌ Instável ❌ Não recomendado


7. Resolução de Problemas de Rede

▶ Exemplo: Teste de Largura de Banda de Rede com iperf (Dificuldade: ⭐⭐⭐)

BASH
# Iniciar servidor iperf3 em um contêiner
docker run -d --name iperf-server --network host networkstatic/iperf3 -s

# Executar cliente iperf3 de outro contêiner
docker run --rm --network host networkstatic/iperf3 -c localhost -t 10

# Testar entre dois contêineres em redes diferentes
docker run --rm --network app-net networkstatic/iperf3 -c db -t 5

▶ Exemplo: Rastreamento de Eventos com Docker Events (Dificuldade: ⭐⭐)

BASH
# Monitorar eventos do ciclo de vida do contêiner
docker events --filter type=container

# Filtrar por eventos específicos
docker events --filter event=oom --filter event=die --filter event=restart

# Filtro baseado em tempo
docker events --since "2024-01-15T03:00:00" --until "2024-01-15T04:00:00"


8. Depuração Avançada: nsenter

▶ Exemplo: nsenter para entrar no namespace do contêiner (Dificuldade: ⭐⭐⭐)

BASH
# Obter o PID principal do contêiner
PID=$(docker inspect --format='{{.State.Pid}}' myapp)

# Entrar no namespace de rede do contêiner para depuração
nsenter -t $PID -n tcpdump -i eth0 -c 100 port 8080

# Entrar no namespace de processos do contêiner
nsenter -t $PID -p -m strace -p 1
💡 Dica: nsenter opera em um nível mais baixo que docker exec — ele entra diretamente no namespace Linux do contêiner, sem exigir um shell dentro do contêiner. É adequado para depurar imagens scratch ou distroless.



9. Guia de Resolução de Problemas: Problemas Comuns e Soluções

Sintoma Comando de Diagnóstico Causas Comuns Solução
Reinícios frequentes do contêiner docker ps -a + docker logs OOM / Falhas na aplicação Aumentar memória / Corrigir bugs / Política de restart
Espaço em disco cheio docker system df -v Acúmulo de logs/imagens/volumes docker system prune + Rotação de logs
Tempo limite de conexão de rede docker exec ping + nc Erro de configuração de rede Verificar rede/DNS/porta
Build Lento docker build --progress=plain Cache Expirado Ajustar Ordem do COPY
Falha na inicialização do contêiner docker logs + docker inspect Erro de configuração/dependências ausentes Corrigir configuração/verificar dependências
Alta Espera de I/O iostat -x Driver de log/escritas pesadas Trocar driver de log/otimizar escritas


10. Exemplo Completo: Resolvendo Problemas de OOM em Contêineres

BASH
# ============================================
# Passo a passo completo: Diagnóstico e correção de OOM
# Abrange: stats, events, logs, inspect, correção
# ============================================

# 1. Implantar o contêiner problemático
docker run -d \
  --name leaky-app \
  --memory=100m \
  --restart=on-failure:5 \
  -p 8080:8080 \
  myapp:1.0

# 2. Monitorar uso de recursos
docker stats leaky-app --no-stream

# 3. Simular vazamento de memória (acionar OOM)
docker exec leaky-app python -c "
import itertools
data = []
for i in itertools.count():
    data.append('x' * 1024 * 1024)  # 1 MB cada
    if i % 10 == 0:
        import time; time.sleep(0.1)
"

# 4. Capturar evento OOM
docker events --filter container=leaky-app --filter event=oom --since 1m

# 5. Verificar código de saída e status OOM
docker inspect leaky-app --format='
ExitCode: {{.State.ExitCode}}
OOMKilled: {{.State.OOMKilled}}
Memory Limit: {{.HostConfig.Memory}}
'

# 6. Verificar logs da aplicação para padrões de memória
docker logs --tail 100 leaky-app 2>&1 | grep -i "memory\|alloc\|oom"

# 7. Corrigir: aumentar limite de memória
docker stop leaky-app && docker rm leaky-app
docker run -d \
  --name leaky-app \
  --memory=512m \
  --restart=on-failure:5 \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  -p 8080:8080 \
  myapp:1.0

# 8. Configurar alerta de monitoramento
docker events --filter event=oom | while read event; do
  echo "ALERT: OOM detected at $(date)" >> /var/log/docker-alerts.log
done

❓ Perguntas Frequentes

P: Como resolver problemas de performance de contêineres em camadas? R: Um método de quatro etapas: ① Use docker stats para ver uma visão geral de CPU, memória e I/O; ② Selecione a ferramenta apropriada com base na métrica mais alta (CPU → top, memória → smem, I/O → iostat, rede → iperf); ③ Identifique o contêiner ou processo específico; ④ Analise os logs da aplicação para encontrar a causa raiz.

P: Qual é melhor, overlay2 ou aufs? R: overlay2 é melhor; é o driver de armazenamento padrão e único recomendado do Docker. aufs foi descontinuado e não é mais suportado no Docker 24 e posteriores. overlay2 oferece melhor performance, implementação mais simples e suporte comunitário mais ativo.

P: Como liberar espaço quando o disco do contêiner está cheio? R: docker system df -v Verifique o que está ocupando mais espaço → Limpe de acordo: ① Imagens: docker image prune -a; ② Cache de build: docker builder prune; ③ Contêineres: docker container prune; ④ Volumes: docker volume prune (Proceda com cautela — isso excluirá dados); ⑤ Tudo: docker system prune -a.

P: Como resolver problemas de I/O lento em contêineres? R: ① docker stats Verifique a coluna BlockIO; ② No host iostat -x 1, verifique %util e await; ③ docker system df -v Verifique o uso do driver de armazenamento; ④ Causas comuns: o driver de log encheu o disco, muitas camadas overlay2 ou um bind mount para um disco lento.

P: Como testar a latência de rede para contêineres? R: Use iperf3: contêiner servidor iperf3 -s, contêiner cliente iperf3 -c server. Teste taxa de transferência e latência. Para testar entre contêineres, eles devem estar na mesma rede ou usar a opção --network host.


📖 Resumo


📝 Exercícios

  1. Exercício Básico (Dificuldade: ⭐): Use o contêiner stress para simular carga de CPU e use docker stats para monitorar as mudanças no uso da CPU.
  2. Exercício Avançado (Dificuldade: ⭐⭐): Use docker system df -v para analisar o uso de disco, execute docker system prune -a para limpar e compare a diferença de espaço em disco antes e depois da limpeza.
  3. Desafio (Dificuldade: ⭐⭐⭐): Use iperf3 para testar a largura de banda de rede entre dois contêineres e compare as diferenças de performance entre redes bridge e host.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%