Monitorando containers com Docker stats
1. Introdução ao Docker stats
No ecossistema DevOps, a visibilidade sobre o comportamento dos containers em tempo real é um requisito fundamental para garantir disponibilidade, performance e uso eficiente de recursos. O comando docker stats é uma ferramenta nativa do Docker que fornece um fluxo contínuo de métricas de uso de CPU, memória, I/O de rede e I/O de bloco para containers em execução.
Diferente de logs históricos, que registram eventos passados, o docker stats oferece monitoramento em tempo real — uma janela ao vivo para o que está acontecendo agora. Enquanto logs são essenciais para análise forense e debugging, as métricas de docker stats são ideais para detectar anomalias instantâneas, como picos de consumo ou vazamentos de memória.
Para o profissional DevOps, monitorar containers não é opcional: é a base para dimensionamento adequado, otimização de custos em ambientes cloud e prevenção de falhas em produção. Sem essa visibilidade, um container que consome toda a CPU disponível pode derrubar serviços inteiros sem aviso prévio.
2. Sintaxe básica e primeiros passos
O uso mais simples do comando é executá-lo sem argumentos:
docker stats
Isso exibe uma tabela com todos os containers em execução, atualizada a cada segundo. Para monitorar um container específico, use seu ID ou nome:
docker stats meu-container-web
Opções úteis incluem:
--no-stream: exibe apenas uma única captura (útil para scripts)--format: personaliza a saída com templates Go--all(ou-a): inclui containers parados (exibe métricas zeradas)
Exemplo com --no-stream:
docker stats --no-stream meu-container-web
3. Métricas essenciais exibidas
A saída padrão do docker stats inclui as seguintes colunas:
CPU% — Percentual de uso da CPU em relação aos núcleos disponíveis. Se um container usa 150%, significa que está consumindo 1,5 núcleos completos.
MEM USAGE / LIMIT — Uso atual de memória e o limite imposto. Exemplo: 128.4MiB / 256MiB indica que metade da memória permitida está em uso.
MEM% — Percentual do limite de memória que está sendo consumido.
NET I/O — Tráfego de rede acumulado (entrada/saída) desde o início do container.
BLOCK I/O — Operações de leitura/gravação em disco acumuladas.
Exemplo prático de saída:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
a1b2c3d4e5f6 web-app 45.23% 210.5MiB / 512MiB 41.11% 1.2GB / 3.4GB 150MB / 45MB
4. Interpretação e análise das métricas
Identificar gargalos de CPU é direto: se um container mantém uso acima de 80-90% consistentemente, pode estar subdimensionado ou com um loop ineficiente. Vazamentos de memória (memory leak) se manifestam como crescimento contínuo do MEM USAGE sem liberação, mesmo sem aumento de carga.
A relação entre limites configurados e métricas exibidas é crucial. Se um container foi iniciado com --memory=256m --cpus=0.5, o docker stats respeitará esses limites:
docker run -d --name web-limited --memory=256m --cpus=0.5 nginx
docker stats web-limited
Sinais de alerta incluem:
- CPU% consistentemente acima de 90%
- MEM% próximo de 100%
- I/O de bloco excessivo (pode indicar swapping)
- NET I/O crescendo sem aumento de requisições (possível ataque ou vazamento de dados)
5. Formatação de saída para automação
O --format aceita templates Go para extrair métricas específicas. Exemplo básico:
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
Para capturar apenas valores (sem cabeçalho), remova table:
docker stats --no-stream --format "{{.Name}},{{.CPUPerc}},{{.MemPerc}}"
Campos disponíveis: .Name, .ID, .CPUPerc, .MemUsage, .MemPerc, .NetIO, .BlockIO, .PIDs.
Exemplo prático para gerar um CSV:
docker stats --no-stream --format "{{.Name}},{{.CPUPerc}},{{.MemUsage}},{{.MemPerc}}" >> metrics.csv
6. Integração com pipelines DevOps
Em pipelines CI/CD (GitHub Actions, Jenkins), o docker stats pode ser usado para validar se um container não excede limites antes de promover para produção.
Exemplo de script bash para coleta e alerta:
#!/bin/bash
CONTAINER="web-app"
THRESHOLD_CPU=80
THRESHOLD_MEM=90
while true; do
STATS=$(docker stats --no-stream --format "{{.CPUPerc}},{{.MemPerc}}" $CONTAINER)
CPU=$(echo $STATS | cut -d',' -f1 | tr -d '%')
MEM=$(echo $STATS | cut -d',' -f2 | tr -d '%')
if (( $(echo "$CPU > $THRESHOLD_CPU" | bc -l) )); then
echo "ALERTA: CPU em $CPU% - limite $THRESHOLD_CPU%"
fi
if (( $(echo "$MEM > $THRESHOLD_MEM" | bc -l) )); then
echo "ALERTA: Memória em $MEM% - limite $THRESHOLD_MEM%"
fi
sleep 5
done
Para envio a sistemas como Prometheus, um script pode expor as métricas em formato texto para um endpoint HTTP, ou usar ferramentas como cAdvisor que já coletam dados do Docker daemon.
7. Limitações e alternativas
O docker stats tem limitações importantes:
- Não monitora disco persistente (apenas I/O de bloco do container efêmero)
- Não verifica saúde da aplicação (apenas recursos do sistema)
- Não oferece histórico (apenas tempo real ou capturas únicas)
- Escalabilidade limitada em clusters grandes
Em Kubernetes, as alternativas nativas são:
kubectl top pod— métricas de CPU/memória por podkubectl top node— métricas por nó- Metrics Server — componente que coleta dados do kubelet
- Prometheus + Grafana — stack completo para monitoramento
Boas práticas: combine docker stats com healthchecks (HEALTHCHECK no Dockerfile) e logs estruturados. Para ambientes de produção, ferramentas como Datadog, New Relic ou Prometheus são mais robustas.
8. Exemplo prático completo
Cenário: Monitorar um container Nginx durante um teste de carga com ab (Apache Benchmark).
Passo 1 — Iniciar container com limites definidos:
docker run -d --name nginx-test --memory=128m --cpus=0.5 -p 8080:80 nginx:alpine
Passo 2 — Gerar carga:
ab -n 10000 -c 100 http://localhost:8080/
Passo 3 — Script de monitoramento em tempo real, registrando em CSV:
#!/bin/bash
CONTAINER="nginx-test"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
CSV_FILE="metrics_${TIMESTAMP}.csv"
echo "timestamp,cpu_perc,mem_usage,mem_perc,net_in,net_out" > $CSV_FILE
for i in {1..30}; do
STATS=$(docker stats --no-stream --format \
"{{.CPUPerc}},{{.MemUsage}},{{.MemPerc}},{{.NetIO}}" $CONTAINER)
CPU=$(echo $STATS | cut -d',' -f1)
MEM=$(echo $STATS | cut -d',' -f2)
MEM_PERC=$(echo $STATS | cut -d',' -f3)
NET=$(echo $STATS | cut -d',' -f4)
echo "$(date +%H:%M:%S),$CPU,$MEM,$MEM_PERC,$NET" >> $CSV_FILE
# Alerta simples se CPU > 80%
CPU_VAL=$(echo $CPU | tr -d '%')
if (( $(echo "$CPU_VAL > 80" | bc -l) )); then
echo "⚠️ ALERTA: CPU em $CPU_VAL%"
fi
sleep 2
done
echo "Métricas salvas em $CSV_FILE"
Passo 4 — Analisar o CSV gerado:
cat metrics_*.csv
Exemplo de saída:
timestamp,cpu_perc,mem_usage,mem_perc,net_in,net_out
14:30:01,12.45%,5.2MiB / 128MiB,4.06%,1.2kB / 2.1kB
14:30:03,78.32%,45.8MiB / 128MiB,35.78%,2.1GB / 1.3GB
14:30:05,92.10%,89.3MiB / 128MiB,69.77%,4.5GB / 2.8GB
14:30:07,45.67%,92.1MiB / 128MiB,71.95%,4.8GB / 3.1GB
O script demonstra como capturar métricas durante um evento de estresse, identificar picos e gerar alertas básicos — tudo com ferramentas nativas do Docker.
Referências
- Documentação oficial do Docker stats — Referência completa do comando
docker stats, opções e formatos de saída. - Monitoramento de containers com Docker: guia prático — Tutorial da DigitalOcean sobre monitoramento básico e avançado de containers.
- Usando docker stats em pipelines CI/CD — Artigo técnico sobre integração de métricas de containers em GitHub Actions e Jenkins.
- Métricas de containers no Kubernetes: kubectl top vs docker stats — Documentação oficial do Kubernetes sobre monitoramento de recursos e comparação com ferramentas Docker.
- Template Go para formatação de saída no Docker — Guia prático sobre templates Go, essencial para personalizar saídas do
docker stats --format. - Monitoramento de containers com Prometheus e Grafana — Documentação oficial do Prometheus sobre coleta de métricas Docker e visualização no Grafana.