Como diagnosticar e capturar pacotes para intermitência de rede entre containers Docker no Debian
Por Kevin Marcondes · Publicado em · 9 min de leitura
Intermitência de rede entre containers Docker no Debian costuma ser difícil de reproduzir. O caminho mais curto é confirmar a hipótese com captura de pacotes no ponto certo e testes controlados. Veja como diagnosticar e capturar pacotes para intermitência de rede entre containers Docker no Debian com tcpdump/tshark, nsenter, tc netem e checagens de MTU.
Sinais de intermitência entre containers que valem captura imediata
Intermitência real quase sempre aparece como tempo de resposta variável, resets esporádicos ou DNS falhando às vezes. Se você vê um desses sinais, priorize captura próxima aos containers afetados antes que o problema desapareça.
Use esta lista para decidir onde capturar e o que anotar enquanto reproduz o erro.
- Picos de latência em rotas internas (p99 sobe, média estável)
- Erros TCP RST ao abrir conexão ocasionalmente
- DNS resolve às vezes e falha em outras (NXDOMAIN/timeout)
- Requisições gRPC/HTTP2 com streams quebrados intermitentes
- Logs mostram retries e timeouts sem padrão claro
- Diferença entre tráfego intra‑host vs. inter‑host (Swarm/K8s)
Mapa de causas prováveis e como verificar rápido
Use o mapeamento abaixo para ir direto à hipótese mais provável e ao comando que produz evidência objetiva. Capture no host e no namespace do container quando possível para comparar.
Se você já viu quedas em bridge networks, aprofunde em por que containers perdem conexão na bridge e soluções em causas e solução na Docker bridge.
| Sintoma | Hipótese | Onde capturar | Comando de checagem |
|---|---|---|---|
| Timeout intermitente sem logs no servidor | MTU/MSS e PMTUD bloqueado (ICMP Frag Needed) | eth0 do host e veth do container | ping -M do -s 1472 <dest> | tcpdump icmp |
| Falha só em nomes específicos | DNS intermitente (ndots/search, cache) | Loopback do container e saída para DNS | getent hosts nome; tcpdump port 53 |
| RST logo após SYN, às vezes | Conntrack lotado ou healthchecks competindo | Host (docker0/bridge) | ss -s; conntrack -S; tcpdump 'tcp[tcpflags] & tcp-rst != 0' |
| Lento dentro do host, normal fora | Contenção no veth/bridge (qdisc), offloads | veth do container e docker0 | tc -s qdisc; ethtool -k <iface> |
| Só quebra inter-host | Overlay MTU/encapsulamento | Iface underlay e overlay | tracepath <IP> e tcpdump gre/vxlan |
| IPv6 falha, IPv4 normal | RA/NDP, política de firewall IPv6 | Iface interna e externa IPv6 | ping6 -s 1232 -M do; tcpdump icmp6 |
Como saber se a intermitência é de DNS, rota ou MTU?
Separe por camada. Primeiro DNS, depois conectividade/rota, por fim MTU/MSS. Meça cada hipótese com um teste determinístico que possa ser repetido sob captura.
Para IPv6 em containers e bridge network no Debian, veja o passo a passo dedicado em habilitar e depurar IPv6.
- DNS: meça tempo de resolução e diferencie NXDOMAIN vs timeout.
- Rota: use tracepath/mtr e compare intra‑host vs inter‑host.
- MTU: teste ICMP com DF e observe “Frag needed” na captura.
# DNS (mede apenas resolução)
time getent hosts api.internal.svc || echo "falha DNS"
# Rota e MTU (Linux)
tracepath -n 10.0.0.25 | sed -n '1,6p'
# PMTUD: DF (do not fragment) e payload próximo a 1500
ping -M do -s 1472 10.0.0.25 -c 3
# TCP handshake cronometrado
TIMEFORMAT=%R; time bash -c 'exec 3<>/dev/tcp/10.0.0.25/443; echo ok >&3; exec 3<&- 3>&-'
Qual comando usar para capturar pacotes dentro do container?
A forma mais confiável é entrar no namespace de rede do container com nsenter e rodar tcpdump/tshark lá. Assim você evita mapear manualmente o par veth no host.
Se preferir capturar no host, identifique a veth correta e use filtros por IP/porta do container.
# 1) Descubra o PID do container
eval PID=$(docker inspect -f '{{.State.Pid}}' nome_ou_id)
# 2) Entre no netns do container e capture (arquivo rotativo)
sudo nsenter -t "$PID" -n \
tcpdump -ni any -w /tmp/cap.pcap -C 50 -W 5 \
'host 10.0.0.25 and (tcp port 80 or 443)'
# Alternativa: tshark em modo texto
sudo nsenter -t "$PID" -n tshark -i any -Y 'tcp.analysis.retransmission or tcp.flags.reset==1' -T fields \
-e frame.time -e ip.src -e ip.dst -e tcp.analysis.retransmission -e tcp.flags.reset
Workflow seguro para reproduzir e capturar sem derrubar produção
Reproduza o erro com tráfego controlado, capture com buffer em disco e delimite a janela do teste. Assim você cruza timestamps de aplicação e rede com precisão.
Configure filtros de captura antes de iniciar o teste para reduzir volume e ruído.
- Defina alvo: IP/porta e cenário (intra‑host ou inter‑host).
- Crie janela curta de 2–5 minutos para o teste.
- Use ring buffer (-C/-W) para não encher disco.
- Anote timestamps de início/fim e IDs de requisição.
# Terminal A: captura rotativa no namespace do cliente
PID_CLIENT=$(docker inspect -f '{{.State.Pid}}' svc_a)
sudo nsenter -t "$PID_CLIENT" -n tcpdump -ni any -w /tmp/cap_a.pcap -C 25 -W 4 'host 10.0.0.25 and tcp'
# Terminal B: tráfego de reprodução (baixa taxa para isolar)
for i in $(seq 1 200); do
TS=$(date -Is)
curl -sS --max-time 2 https://10.0.0.25/health || echo "$TS FAIL" >&2
sleep 0.2
done
# Terminal C: marcação de eventos
echo "START $(date -Is)" >> /tmp/marks.log; sleep 150; echo "END $(date -Is)" >> /tmp/marks.log
# Depois: analisar
sudo nsenter -t "$PID_CLIENT" -n tshark -r /tmp/cap_a.pcap -qz io,stat,1,'COUNT(tcp.flags.reset) tcp.flags.reset==1'
Quando usar tc netem para simular perda e latência?
Use tc netem para reproduzir perda/latência e verificar se a aplicação falha sob condições semelhantes às observadas. Aplique no namespace do container ou na bridge para isolar o escopo.
Importante: netem afeta tráfego real. Aplique em ambiente de teste ou durante janela controlada e remova a regra ao final.
# Aplicar latência e perda no netns do container servidor
PID_SRV=$(docker inspect -f '{{.State.Pid}}' svc_b)
nsenter -t "$PID_SRV" -n bash -lc '
IF=$(ip -o -4 route show default | awk "/default/ {print \$5; exit}")
tc qdisc add dev "$IF" root netem delay 80ms 20ms loss 1%
tc -s qdisc show dev "$IF"
'
# Remover nsenter -t "$PID_SRV" -n bash -lc 'tc qdisc del dev $(ip -o -4 route show default | awk "/default/ {print \$5; exit}") root || true'
MTU e MSS: por que causam intermitência e como medir
Encapsulamento e caminhos assimétricos podem reduzir a MTU efetiva. Se o ICMP “Fragmentation Needed” não chega, o handshake quebra de forma intermitente. Valide a MTU com ICMP DF e ajuste MSS quando necessário.
Se usar overlay, considere MTU menor para a bridge do Docker ou ajuste TCPMSS no host. Reiniciar o Docker altera redes: planeje janela, pois interfaces e containers podem reconectar.
- Teste PMTUD: procure “Frag needed” na captura.
- Ajuste provisório: TCPMSS clamp na saída.
- Ajuste definitivo: MTU consistente nas interfaces Docker/host.
# Medir MTU efetiva (ICMP com DF)
ping -M do -s 1472 10.0.0.25 -c 2 || echo "tente tamanhos menores: 1464, 1452, 1432"
# Clamp MSS (temporário) no host
sudo iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN \
-o docker0 -j TCPMSS --clamp-mss-to-pmtu
# Definir MTU da bridge do Docker (requer restart do serviço)
# /etc/docker/daemon.json
# {
# "mtu": 1450
# }
# sudo systemctl restart docker # ATENÇÃO: interrompe redes do Docker momentaneamente
Como confirmar que resolveu e evitar regressões
Valide com medições lado a lado: sem erro por tempo suficiente, latências estáveis e ausência de resets/retransmissões anômalas. Em seguida, institucionalize testes e observabilidade para não voltar ao ponto cego.
Health checks e readiness bem configurados evitam cascatas de erro em momentos de degradação.
- Rodar mtr/tracepath por 15–30 minutos sem perda.
- Capturar 5 minutos e confirmar 0 RST inesperados.
- Adicionar synthetic checks internos (curl com timeout).
- Configurar health/readiness com backoff e circuit breaker.
- Documentar PMTUD/MTU alvo no runbook.
# Métrica rápida de retransmissão (deveria ser 0 ou baixo)
sudo tshark -r /tmp/cap_a.pcap -Y tcp.analysis.retransmission -T fields -e frame.number | wc -l
# Health/readiness em apps PHP (exemplos e práticas)
# Veja: health checks e readiness em Docker Compose
# Link: /health-checks-readiness-docker-compose-php
Perguntas frequentes
Preciso instalar tcpdump dentro do container?
Não. É melhor usar nsenter para entrar no namespace de rede do container e rodar tcpdump a partir do host. Assim você evita alterar a imagem e garante acesso a qualquer interface no netns. A captura no host também funciona, mas exige mapear a veth correta.
Qual interface devo capturar: docker0, veth ou any?
Para isolar um container, capture dentro do namespace com -i any. No host, docker0 vê tráfego bridgeado; a veth do container mostra pacotes específicos daquele serviço. Em redes overlay, capture também na interface underlay para ver encapsulamento e checar MTU.
Tráfego TLS atrapalha a análise?
TLS cifra o conteúdo, mas metadados ajudam: observando handshake, SNI, resets, latência de troca de chaves e retransmissões você confirma intermitência na camada de transporte. Combine tcpdump/tshark com logs de aplicação e synthetic checks para fechar o diagnóstico.
Rodar tcpdump em produção impacta desempenho?
O impacto é baixo quando você usa filtros e escreve em pcap com buffer rotativo. Evite capturas sem filtro em interfaces muito movimentadas. Monitore I/O de disco e CPU durante o teste e limite a janela de captura a poucos minutos.
Como confirmar problema de MTU entre containers?
Use ping com DF (-M do) variando o tamanho (-s) e capture ICMP; “Frag needed” confirma que a MTU efetiva é menor. Em TCP, observe SYN/SYN-ACK seguidos de RST ou handshake incompleto. Corrija com MTU consistente ou clamp de MSS no caminho.
Quando usar tc netem em vez de testes reais?
Use tc netem para reproduzir condições difíceis de capturar ao vivo, como perda baixa e jitter. Aplique no namespace do container afetado e remova ao final. Ele não substitui tráfego real, mas valida a resiliência da aplicação sob degradação controlada.
Quer ajuda para estruturar o diagnóstico sem arriscar produção?
Converse sobre seu cenário e montamos um plano de captura, reprodução controlada e validação de correções em Debian com Docker.
Falar sobre meu casoVeja também
- 502 Bad Gateway intermitente em Docker Compose com Nginx e PHP‑FPM: como diagnosticar e corrigir timeouts e excesso de conexões
- Como reduzir tempo de build e evitar artefatos duplicados em CI para monólitos PHP grandes
- Como detectar e corrigir inconsistências de SKU duplicados entre WooCommerce e ERP sem perder pedidos
- Como reduzir tempo de recuperação após crash de servidor Linux com playbook Ansible e runbook de recuperação