Por que containers Docker perdem conexão na bridge network e como resolver intermitência em produção
Por Kevin Marcondes · Publicado em · 8 min de leitura
Se os containers Docker perdem conexão na bridge network de forma intermitente, o diagnóstico certo evita horas de tentativa e erro. A causa costuma estar em MTU/PMTU, conntrack/NAT, rp_filter/ARP ou DNS interno. Abaixo mostro como identificar cada raiz e aplicar correções seguras em produção.
Sintomas e quando a intermitência aparece
Intermitência na bridge se manifesta como timeouts, resets (RST) e conexões que funcionam e, de repente, quebram. Às vezes só cargas grandes falham; pings curtos passam.
O padrão comum: serviços sob Docker ficam acessíveis via porta publicada, mas clientes internos ou externos observam falhas ocasionais, principalmente sob pico, quando muitos containers iniciam/param ou após mudanças de rede no host.
- TCP conecta, recebe alguns KB e trava até timeout.
- Uploads/downloads grandes falham; requisições pequenas funcionam.
- Mensagens no kernel sobre conntrack/ARP ou pacotes ‘martian’.
- DNS resolve lento ou intermitente dentro dos containers.
Causas técnicas mais comuns na Docker bridge
Algumas raízes aparecem repetidamente em incidentes reais de produção. Entenda o mecanismo para aplicar a correção certa.
A boa notícia: a maioria tem diagnóstico objetivo com poucas verificações no host e nos containers.
- MTU/PMTU: MTU do veth/docker0 não combina com a rede física/túneis, gerando blackhole para pacotes grandes.
- Conntrack/NAT: tabela nf_conntrack lota, portas efêmeras esgotam e sessões caem ao acaso.
- rp_filter/rotas: roteamento assimétrico, VRRP/VPN ou múltiplas NICs fazem o kernel descartar respostas legítimas.
- ARP/neighbour cache: entradas obsoletas ou GC agressivo após churn de containers.
- DNS 127.0.0.11: o DNS embutido do Docker sofre sob alto QPS ou timeouts ruins.
- Regras DOCKER-USER/iptables: políticas ‘drop’ atingem tráfego de docker0 sem exceções adequadas.
Diagnóstico rápido no host e nos containers
Faça um triagem objetiva antes de alterar configuração. Busque sinais de MTU, conntrack e quedas por firewall/roteamento.
Execute do host e de um container afetado. Guarde os horários e compare com picos de tráfego.
# 1) Sinais no kernel (conntrack, ARP/neighbor, martian)
dmesg -T | egrep -i 'conntrack|nf_conntrack|neighbor|arp|martian|FRAG'
# 2) Estado de conntrack e portas efêmeras
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
ss -s
cat /proc/sys/net/ipv4/ip_local_port_range
# 3) PMTU/MTU: teste DF e caminho
GW=$(ip route | awk '/default/ {print $3; exit}')
ping -c 3 -M do -s 1472 "$GW" || echo "Possível MTU < 1500 no caminho"
tracepath -n "$GW" | tail -n +1
# 4) ARP/neigh suspeito (incomplete/failed)
ip -s neigh | egrep -i 'FAILED|INCOMPLETE' -n || true
# 5) Regras do Docker e DOCKER-USER
iptables -S DOCKER-USER 2>/dev/null || true
iptables -t nat -S | sed -n '1,120p' 2>/dev/null || true
# 6) De dentro de um container afetado: DNS e MTU
getent hosts example.com || nslookup example.com || dig +short example.com || true
ip route show
echo $(cat /sys/class/net/eth0/mtu) MTU-no-container
MTU e PMTU: detectar e corrigir sem derrubar tudo
Falhas só com payloads grandes quase sempre indicam MTU/PMTU. Em clouds com túneis (VXLAN/GRE), a MTU efetiva costuma ser 1450/1460. Se docker0/eth0 do container ficam em 1500, surge blackhole.
Confirme com ping DF. Se menor MTU for necessária, ajuste a MTU do Docker para alinhar com a rede. Requer restart do Docker e recriação da bridge, planeje janela.
- Valide com ping -M do para o gateway/serviço.
- Ajuste MTU no daemon do Docker para propagar aos veths.
- Teste novamente e monitore erros de fragmentação.
# Teste PMTU (ajuste o destino para um serviço fora do host)
ping -c 3 -M do -s 1472 $DEST || echo "Tente 1432/1400 para descobrir a MTU segura"
# Ajuste de MTU no Docker (crie/edite /etc/docker/daemon.json)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json >/dev/null <<'EOF'
{
"mtu": 1450
}
EOF
# Reinicie com cuidado (interrompe containers)
sudo systemctl restart docker
# Verifique
aioctl=$(ip -o link show docker0 | awk '{print $2,$9,$10,$11}')
echo "docker0 ->" $ioctl
ip -o link show | grep veth | head -n 3
Conntrack, NAT e portas efêmeras: limites e tuning
Tabela nf_conntrack cheia derruba conexões novas e pode matar as existentes. Tráfego com muito NAT também sofre se o range de portas efêmeras é curto.
Ajuste limites de conntrack com parcimônia, amplie a faixa de portas e, se você gerencia o firewall manualmente, prefira MASQUERADE com random-fully para reduzir colisões de 5‑tuple.
- Monitore count vs max; mantenha folga saudável.
- Amplie ip_local_port_range em hosts de saída intensa.
- Evite regras que forcem inspeção cara em todo pacote.
# Medir e ajustar conntrack
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
# Exemplo: elevar (persistir em /etc/sysctl.d)
echo 'net.netfilter.nf_conntrack_max = 524288' | sudo tee /etc/sysctl.d/90-conntrack.conf
sudo sysctl --system
# Portas efêmeras mais amplas
sudo sysctl -w net.ipv4.ip_local_port_range="10240 65535"
echo 'net.ipv4.ip_local_port_range = 10240 65535' | sudo tee /etc/sysctl.d/90-ports.conf
sudo sysctl --system
# Se você administra NAT manualmente (fora das regras do Docker):
# iptables -t nat -C POSTROUTING -o eth0 -j MASQUERADE --random-fully || \
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE --random-fully
ARP, vizinhança e rp_filter: rotas que somem
Roteamento assimétrico (VPN, VRRP, múltiplas NICs) com rp_filter estrito faz o kernel descartar respostas legítimas. ARP/neighbour cache pequeno, sob churn, induz falhas intermitentes.
Aplique rp_filter ‘loose’ onde há assimetria e aumente os limiares do neighbour GC. Mude com cautela e registre as alterações.
- Procure ‘martian source’ nos logs.
- Confirme a rota de retorno com ip route get.
- Aumente gc_thresh em hosts com muitas peers/containers.
# rp_filter atual
sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.default.rp_filter
# Tornar ‘loose’ (2) se há assimetria/VRRP/VPN
sudo sysctl -w net.ipv4.conf.all.rp_filter=2
sudo sysctl -w net.ipv4.conf.default.rp_filter=2
echo -e 'net.ipv4.conf.all.rp_filter=2\nnet.ipv4.conf.default.rp_filter=2' | \
sudo tee /etc/sysctl.d/90-rpfilter.conf
# Neighbour cache mais folgado
sysctl net.ipv4.neigh.default.gc_thresh1 net.ipv4.neigh.default.gc_thresh2 net.ipv4.neigh.default.gc_thresh3
sudo bash -c 'cat > /etc/sysctl.d/90-neigh.conf <<EOF
net.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 16384
EOF'
sudo sysctl --system
# Limpar entradas problemáticas (impacta momentaneamente a resolução ARP)
sudo ip neigh flush dev docker0 || true
DNS 127.0.0.11 e firewall: quando não é a rede
A resolução embutida (127.0.0.11) pode virar gargalo sob alto QPS ou parâmetros ruins de timeout. Em ambientes restritos, DOCKER-USER com DROP padrão derruba tráfego da bridge.
Teste com DNS externo/cacher e ajuste dns_opt no Compose. Revise DOCKER-USER garantindo exceções claras antes de um DROP amplo.
- Use um resolvedor local (ex.: 10.0.0.53) para cache.
- Reduza timeout/attempts para falhar rápido e tentar outro DNS.
- Permita RELATED,ESTABLISHED e tráfego de docker0 no firewall.
# docker-compose.yml (trecho)
services:
app:
image: example/app
dns:
- 10.0.0.53
- 1.1.1.1
dns_opt:
- timeout:1
- attempts:3
# ... restante do serviço
Observabilidade, testes e próximos passos
Depois de aplicar correções, valide sob carga e monitore. Métricas de conntrack, quedas TCP e latência de DNS ajudam a prevenir regressões.
Implemente health checks para retirar instâncias do tráfego ao primeiro sinal de falha, e um proxy reverso bem configurado para failover/renovação de certificados.
- Colete métricas com Prometheus/Grafana e alertas úteis.
- Centralize logs (kernel, iptables, apps) para correlação.
- Automatize readiness checks e circuit breakers no app.
- Teste PMTU em pipelines de deploy e após mudanças de rede.
- Evite a bridge ‘default’; prefira redes user-defined isoladas.
Perguntas frequentes
Como saber se o problema é MTU/PMTU ou outra coisa?
Se pings pequenos funcionam e pacotes grandes com DF falham, é forte indício de MTU/PMTU. Tracepath ajuda a revelar o salto que reduz MTU. Já quedas aleatórias sob pico com mensagens de nf_conntrack apontam para conntrack/NAT. Logs de ‘martian’ sugerem rp_filter/rotas.
Aumentar nf_conntrack_max resolve definitivamente?
Ajuda a aliviar picos, mas não é bala de prata. Se o padrão de tráfego cria muitas conexões curtas, ajuste também timeouts, amplie portas efêmeras e revise o desenho (pooling/reuso de conexões). Monitore o count para evitar crescer sem necessidade.
Desativar rp_filter é seguro?
Evite desativar totalmente. Use modo ‘loose’ (2) quando há roteamento assimétrico, VRRP ou VPN. O modo estrito em hosts multi-homed causa falsos positivos e descartes. Documente a mudança e monitore logs de ‘martian’ após o ajuste.
Devo usar DNS embutido do Docker ou um resolvedor externo?
Para cargas leves, o DNS embutido funciona bem. Em alto QPS ou latências sensíveis, use um resolvedor local em cache (ex.: unbound/dnsmasq) e aponte os serviços via dns no Compose. Ajuste dns_opt para timeouts curtos e múltiplos servidores.
User-defined bridge melhora a estabilidade?
Sim. Redes user-defined isolam domínios de broadcast, têm regras mais previsíveis e DNS por serviço. Elas reduzem colisões e facilitam políticas de firewall. Evite concentrar todos os serviços na bridge ‘default’; crie redes por domínio lógico.
Quer estabilizar a rede dos seus containers?
Se você enfrenta intermitência na Docker bridge e precisa de um plano de diagnóstico e correção com baixo risco, vamos conversar sobre o seu cenário e próximos passos práticos.
Falar sobre diagnóstico DockerVeja 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 diagnosticar e capturar pacotes para intermitência de rede entre containers Docker no Debian
- 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