Redes em Docker: bridge, host, overlay e macvlan na Prática na Prática Já leu

Entendendo as Redes no Docker: Uma Perspectiva Prática Quando você começa a trabalhar com Docker, rapidamente percebe que a comunicação entre contêineres é fundamental. O Docker oferece quatro tipos principais de redes: bridge, host, overlay e macvlan. Cada uma delas resolve um problema específico e entender suas diferenças é crucial para arquitetar soluções robustas e eficientes. Antes de mergulhar nos detalhes técnicos, é importante compreender o problema que as redes resolvem. Um contêiner é um ambiente isolado — por padrão, ele não consegue se comunicar com outros contêineres ou com a máquina host de forma simples. As redes do Docker criam "pontes" que permitem essa comunicação de maneiras diferentes, cada uma com trade-offs específicos. Vamos explorar cada uma delas com profundidade. Bridge: A Rede Padrão e Mais Comum O Que é e Como Funciona A rede bridge é o modo padrão quando você cria um contêiner sem especificar uma rede. Ela cria uma interface virtual no host que atua como

Entendendo as Redes no Docker: Uma Perspectiva Prática

Quando você começa a trabalhar com Docker, rapidamente percebe que a comunicação entre contêineres é fundamental. O Docker oferece quatro tipos principais de redes: bridge, host, overlay e macvlan. Cada uma delas resolve um problema específico e entender suas diferenças é crucial para arquitetar soluções robustas e eficientes.

Antes de mergulhar nos detalhes técnicos, é importante compreender o problema que as redes resolvem. Um contêiner é um ambiente isolado — por padrão, ele não consegue se comunicar com outros contêineres ou com a máquina host de forma simples. As redes do Docker criam "pontes" que permitem essa comunicação de maneiras diferentes, cada uma com trade-offs específicos. Vamos explorar cada uma delas com profundidade.

Bridge: A Rede Padrão e Mais Comum

O Que é e Como Funciona

A rede bridge é o modo padrão quando você cria um contêiner sem especificar uma rede. Ela cria uma interface virtual no host que atua como um switch, conectando todos os contêineres naquela rede. Cada contêiner recebe um endereço IP dentro de uma sub-rede isolada, geralmente algo como 172.17.0.0/16 para a bridge padrão.

O importante aqui é entender que a bridge é isolada do host. Os contêineres conseguem se comunicar entre si usando seus nomes como hostnames (graças ao DNS interno do Docker), mas para acessar um serviço rodando em um contêiner a partir do host, você precisa fazer um mapeamento de portas (port mapping).

Criando e Testando uma Rede Bridge Customizada

# Criar uma rede bridge customizada
docker network create minha-rede-bridge --driver bridge

# Criar dois contêineres conectados a essa rede
docker run -d --name web-server --network minha-rede-bridge nginx:latest
docker run -d --name client --network minha-rede-bridge curlimages/curl sleep 3600

# Testar comunicação entre contêineres usando o nome
docker exec client curl http://web-server

# Verificar a rede
docker network inspect minha-rede-bridge

O output do comando inspect mostrará algo como:

{
    "Name": "minha-rede-bridge",
    "Driver": "bridge",
    "IPAM": {
        "Config": [
            {
                "Subnet": "172.18.0.0/16"
            }
        ]
    },
    "Containers": {
        "abc123...": {
            "Name": "web-server",
            "IPv4Address": "172.18.0.2/16"
        }
    }
}

Caso de Uso Real: Stack de Aplicação Web

# Criar rede para aplicação
docker network create app-network

# Banco de dados
docker run -d \
  --name postgres-db \
  --network app-network \
  -e POSTGRES_PASSWORD=senha123 \
  postgres:15-alpine

# API backend
docker run -d \
  --name api-backend \
  --network app-network \
  -p 3000:3000 \
  -e DATABASE_URL=postgresql://postgres:senha123@postgres-db:5432/myapp \
  seu-backend:latest

# Servidor web
docker run -d \
  --name nginx-frontend \
  --network app-network \
  -p 80:80 \
  -v /home/user/nginx.conf:/etc/nginx/nginx.conf:ro \
  nginx:latest

Neste cenário, o nginx consegue acessar o backend usando simplesmente http://api-backend:3000 porque estão na mesma rede bridge. O port mapping (-p) só é necessário para acessar de fora do Docker.

Host: Máxima Performance com Máxima Exposição

Conceito e Limitações

A rede host remove completamente o isolamento de rede. O contêiner compartilha a pilha de rede (network stack) do host. Isso significa que se você rodar um serviço na porta 8080 dentro de um contêiner com network host, ele estará literalmente escutando na porta 8080 do host. Não existe mapeamento — é direto.

Isso traz ganhos de performance significativos porque elimina a overhead de tradução de endereços (NAT), mas em contrapartida você perde isolamento. Dois contêineres não conseguem usar a mesma porta se estão ambos com network host ativo.

Quando Usar e Exemplo Prático

# Rodar Prometheus com network host para máxima performance
docker run -d \
  --name prometheus \
  --network host \
  -v /home/user/prometheus.yml:/etc/prometheus/prometheus.yml:ro \
  prom/prometheus:latest \
  --config.file=/etc/prometheus/prometheus.yml

# O Prometheus agora está disponível em http://localhost:9090 
# sem necessidade de mapeamento de porta
curl http://localhost:9090

Outro caso comum é para serviços de rede que precisam capturar tráfego do sistema:

# Monitor de rede com tcpdump
docker run -d \
  --name network-monitor \
  --network host \
  --cap-add NET_ADMIN \
  tcpdump-image:latest \
  tcpdump -i eth0 -w /tmp/capture.pcap

Aviso importante: Use network host apenas quando realmente precisar de performance e estiver ciente dos riscos de isolamento. Para 99% dos casos, bridge é o suficiente e muito mais seguro.

Overlay: Comunicação Entre Hosts em Swarm

A Necessidade de Redes Distribuídas

Quando você tem um Docker Swarm (cluster de múltiplos hosts Docker), contêineres rodando em hosts diferentes precisam se comunicar. A rede overlay resolve isso criando um "túnel" encriptado entre os hosts. Ela funciona usando o protocolo VXLAN (Virtual Extensible LAN) para encapsular o tráfego.

A grande diferença em relação à bridge é que a overlay é distribuída. Quando você cria uma rede overlay, ela existe em múltiplos hosts simultaneamente. Contêineres em diferentes hosts conseguem se comunicar como se estivessem na mesma sub-rede local.

Configurando um Swarm Simples com Overlay

Primeiro, você precisa de um Docker Swarm ativo. Para fins educacionais, vamos usar máquinas virtuais ou múltiplos hosts:

# No primeiro host (manager)
docker swarm init --advertise-addr 192.168.1.10

# Output inclui o token. No segundo host (worker), execute:
docker swarm join --token SWMTKN-1-xxx 192.168.1.10:2377

# De volta ao manager, criar rede overlay
docker network create \
  --driver overlay \
  --subnet 10.0.9.0/24 \
  minha-rede-overlay

# Criar um serviço
docker service create \
  --name web-service \
  --network minha-rede-overlay \
  --replicas 3 \
  -p 80:80 \
  nginx:latest

# Listar serviços
docker service ls
docker service ps web-service

Inspecionando a Rede Overlay

docker network inspect minha-rede-overlay

O output revelará que a rede existe em múltiplos nós:

{
    "Name": "minha-rede-overlay",
    "Driver": "overlay",
    "Scope": "swarm",
    "Containers": {
        "container-id-1": {
            "Name": "web-service.1.xxx",
            "IPv4Address": "10.0.9.2/24"
        }
    }
}

Caso de Uso: Stack Multi-Host

# Criar arquivo docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
  database:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: senha123
    networks:
      - backend
    deploy:
      placement:
        constraints: [node.role == manager]

  api:
    image: seu-backend:latest
    environment:
      DATABASE_URL: postgresql://postgres:senha123@database:5432/app
    networks:
      - backend
    depends_on:
      - database
    deploy:
      replicas: 3

  frontend:
    image: seu-frontend:latest
    ports:
      - "80:80"
    networks:
      - frontend
    deploy:
      replicas: 2

networks:
  backend:
    driver: overlay
  frontend:
    driver: overlay
EOF

# Deploy da stack
docker stack deploy -c docker-compose.yml minha-aplicacao

# Verificar status
docker stack services minha-aplicacao

O Docker vai automaticamente criar as redes overlay e distribuir os contêineres pelos nós do swarm. Um contêiner de API rodando no nó A consegue acessar o banco de dados no nó B usando simplesmente postgresql://database:5432.

Macvlan: Atribuindo Endereços MAC ao Contêiner

Uso e Casos de Uso

A rede macvlan é menos comum, mas extremamente poderosa em cenários específicos. Ela faz o contêiner aparecer como um dispositivo físico na rede. Cada contêiner recebe um endereço MAC próprio e aparece na rede local como um host independente, não como um cliente atrás de um NAT.

Isso é particularmente útil quando você precisa que aplicações legadas, ferramentas de descoberta de serviço ou protocolos específicos de rede enxerguem o contêiner como um peer real na rede, não como algo isolado.

Configurando Macvlan na Prática

# Identificar a interface de rede do host
ip addr show

# Criar rede macvlan (assumindo interface eth0)
docker network create \
  -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  minha-rede-macvlan

# Rodar contêiner na rede macvlan
docker run -d \
  --name meu-servidor \
  --network minha-rede-macvlan \
  --ip=192.168.1.100 \
  nginx:latest

# O contêiner agora tem endereço IP real na rede
docker inspect meu-servidor | grep -A 5 '"Networks"'

Verificando Conectividade Real

# Do host, você consegue fazer ping diretamente
ping 192.168.1.100

# E de máquinas na rede local também
ssh usuario@192.168.1.50 "ping 192.168.1.100"

# O serviço está acessível como um host real
curl http://192.168.1.100

Limitação Importante: Comunicação Host-Contêiner

# Isto NÃO funciona por padrão
docker exec meu-servidor curl http://192.168.1.1

# Você precisa criar uma sub-interface e conectá-la ao host
docker network create \
  -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  minha-rede-macvlan

# Conectar container
docker run -d \
  --name servidor-macvlan \
  --network minha-rede-macvlan \
  --ip=192.168.1.100 \
  nginx:latest

Uma solução comum é usar um contêiner "gateway" ou simplesmente aceitar que a comunicação host→macvlan requer configuração adicional de roteamento.

Caso Real: Servidor de Impressão em Rede

# Alguns serviços de impressão requerem descoberta de rede real
docker run -d \
  --name cups-server \
  --network minha-rede-macvlan \
  --ip=192.168.1.200 \
  -p 631:631 \
  baruwa/cups:latest

# Agora dispositivos na rede conseguem descobrir via SNMP, Bonjour, etc.

Comparativo Prático: Quando Usar Cada Uma

A escolha da rede correta é uma decisão arquitetural. Aqui está um guia rápido:

Cenário Rede Recomendada Por Quê
Aplicação monolítica com alguns contêineres Bridge Simples, isolada, performance suficiente
Microsserviços em um único host Bridge customizada Comunicação por nome, isolamento
Serviço que precisa máxima performance Host Sem overhead de NAT
Múltiplos hosts em Swarm Overlay Distribuída, escalável
Aplicação legada que precisa ser host real Macvlan Endereço MAC/IP próprio

Exemplo: Testando Performance

#!/bin/bash

# Bridge
docker network create teste-bridge --driver bridge
docker run -d --name server-bridge --network teste-bridge nginx:latest
docker run --rm --network teste-bridge curlimages/curl \
  curl -w "Bridge: %{time_total}s\n" http://server-bridge &

# Host
docker run -d --name server-host --network host nginx:latest
curl -w "Host: %{time_total}s\n" http://localhost:8080 &

wait
docker stop server-bridge server-host
docker network rm teste-bridge

Na prática, para Nginx e bancos de dados, a diferença entre bridge e host é negligenciável (< 5% em cenários reais). Use host apenas se tiver medições comprovando necessidade.

Conclusão

Você aprendeu que as quatro redes do Docker servem propósitos distintos: bridge é versátil e isolada para a maioria dos casos; host oferece performance máxima ao custo do isolamento; overlay conecta contêineres distribuídos em swarms; macvlan faz contêineres parecerem hosts reais na rede. A escolha correta depende do seu caso de uso específico. Comece sempre com bridge customizada e só considere as outras quando tiver um problema claro que elas resolvem. Finalmente, entenda que networking é um tópico profundo — este artigo é o alicerce, mas ferramentas como service discovery, load balancing e security policies ainda são fronteiras importantes a explorar.

Referências


Artigos relacionados