Redes no Docker
Todo container nasce conectado a alguma rede. É isso que permite um container falar com outro, com o host e com a internet. Este capítulo mostra como o Docker monta essa conectividade, quais são os drivers de rede disponíveis e como inspecionar e depurar o que está acontecendo.
O modelo de rede
O Docker implementa o CNM (Container Network Model) através da biblioteca
libnetwork. Três conceitos importam:
- Sandbox — o isolamento de rede de um container: sua própria pilha TCP/IP,
tabela de rotas, interfaces (
eth0,lo) e regras deiptables. Na prática é um network namespace do Linux. - Endpoint — a "ponta de cabo" que liga um sandbox a uma rede. Um container pode ter vários endpoints, um para cada rede em que está conectado.
- Network — um grupo de endpoints que conseguem se enxergar. Uma rede
bridgeno host normalmente corresponde a uma ponte Linux (docker0oubr-xxxx) e a um par de interfacesvethpor container.
container A container B
┌───────────────┐ ┌───────────────┐
│ sandbox │ │ sandbox │
│ eth0 ────────┤ endpoint │ ────── eth0 │
└───────┬───────┘ └───────┬───────┘
veth│ veth │
┌───┴──────────────────────────────────┴───┐
│ bridge br-1a2b3c │ ← user-defined network
└────────────────────┬─────────────────────┘
│ NAT (iptables MASQUERADE)
┌─────┴─────┐
│ host eth0 │ → internet
└───────────┘
Drivers de rede
O driver define como a rede é implementada. Os principais que já vêm com o Docker:
bridge- Rede padrão para containers em um único host. Cria uma ponte Linux e usa NAT para dar saída à internet. É o driver usado quando você não pede nada. Detalhado em Rede bridge.
host- Remove o isolamento de rede: o container compartilha a pilha de rede do host. Sem NAT, sem publicação de portas, latência mínima. Ver host, none, macvlan e overlay.
none- O container fica só com a interface
lo. Nenhuma conectividade externa. Útil para tarefas puramente offline ou quando outra ferramenta vai montar a rede. overlay- Liga containers em hosts diferentes numa mesma rede L2 virtual, via túnel
VXLAN. É a base do Docker Swarm e serve para comunicação multi-host sem Swarm
com
--attachable. macvlan- Dá ao container um endereço MAC próprio, fazendo ele aparecer como um dispositivo físico na rede local. Bom para sistemas legados que esperam estar "na LAN".
ipvlan- Parecido com
macvlan, mas os containers compartilham o MAC do host e se diferenciam por IP (L3) ou por VLAN tag (L2). Útil quando o switch limita o número de MACs por porta.
Ainda existem drivers de terceiros (Weave, Calico, Cilium, etc.) instaláveis como plugins.
Qual driver usar?
- Um host só, vários containers conversando → rede bridge definida pelo usuário.
- Precisa de performance máxima de rede e não se importa com isolamento → host.
- Vários hosts → overlay (com Swarm) ou um orquestrador como Kubernetes.
- O container precisa de um IP roteável na sua LAN → macvlan/ipvlan.
Comandos essenciais
Listar as redes existentes:
docker network ls
Saída típica logo após instalar o Docker:
NETWORK ID NAME DRIVER SCOPE
0a1b2c3d4e5f bridge bridge local
6f7e8d9c0b1a host host local
2a3b4c5d6e7f none null local
Essas três redes (bridge, host, none) são criadas pelo Docker e não
podem ser removidas.
Criar uma rede definida pelo usuário:
docker network create my-net
Com opções mais explícitas:
docker network create \
--driver bridge \
--subnet 172.28.0.0/16 \
--gateway 172.28.0.1 \
--ip-range 172.28.5.0/24 \
backend
--subnet— faixa de IPs da rede.--gateway— IP do gateway (default: primeiro IP útil da subnet).--ip-range— restringe de qual sub-faixa o Docker aloca IPs automaticamente.--internal— rede sem saída para fora do host (sem NAT).--label— metadados, úteis para filtrar depois.
Conectar e desconectar containers de uma rede em tempo de execução:
docker network connect backend my-container
docker network disconnect backend my-container
Já subir o container conectado a uma rede:
docker container run -d --name api --network backend my-api:1.0
Um container pode estar em várias redes ao mesmo tempo — uma prática comum é ter
uma rede frontend (exposta) e uma backend (interna) e colocar a aplicação
nas duas.
Inspecionando uma rede
docker network inspect backend
Trecho relevante da saída:
[
{
"Name": "backend",
"Driver": "bridge",
"IPAM": {
"Config": [
{ "Subnet": "172.28.0.0/16", "Gateway": "172.28.0.1" }
]
},
"Internal": false,
"Containers": {
"3f2a...": {
"Name": "api",
"IPv4Address": "172.28.5.2/16",
"MacAddress": "02:42:ac:1c:05:02"
}
}
}
]
Isso responde perguntas comuns: qual o IP de cada container, qual a subnet, quais containers estão de fato ligados ali.
Publicação de portas
Containers em uma rede bridge não são acessíveis a partir do host (ou da rede externa) até que você publique uma porta:
docker container run -d -p 8080:80 nginx
Lê-se -p HOST:CONTAINER. O tráfego que chega em localhost:8080 do host é
encaminhado (via iptables/docker-proxy) para a porta 80 do container.
Variações:
-p 80:80 # host port 80 → container port 80
-p 127.0.0.1:8080:80 # publishes only on the host loopback (not exposed on the LAN)
-p 8080:80/udp # UDP protocol
-p 80 # random host port (see it with "docker port")
-P # publishes ALL EXPOSE ports on random ports
Ver o mapeamento efetivo:
docker port my-container
-p fura o firewall
Em muitas distribuições o Docker insere regras direto no iptables e o
mapeamento de porta pode passar por cima do ufw/firewalld. Se precisa
expor só localmente, use -p 127.0.0.1:PORTA:.... Para produção, controle o
acesso na camada de infraestrutura (security group, proxy reverso).
Depurando conectividade
Rodar um container "canivete suíço" na mesma rede do serviço com problema:
docker container run --rm -it --network backend nicolaka/netshoot
Dentro dele você tem dig, curl, ping, nc, tcpdump, ip, ss,
nmap... Checklist rápido:
dig api # does the internal DNS resolve the other container's name?
ping -c1 api # is there an L3 route to it?
curl -v http://api:8080/health # does the app respond on the expected port?
ip route # is the sandbox routing table as expected?
Do lado do host:
docker network inspect backend # is the container really on this network?
docker exec api ss -tlnp # is the app listening on 0.0.0.0?
Escutar em 127.0.0.1 dentro do container é uma armadilha
Se a aplicação faz bind em 127.0.0.1, ela só aceita conexões de dentro do
próprio container. Para receber tráfego de outros containers ou do host, ela
precisa escutar em 0.0.0.0 (todas as interfaces).
Removendo redes
docker network rm backend # removes a specific network (with no containers)
docker network prune # removes all networks with no containers