Docker & Kubernetes

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

14 min de leitura

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

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

<h2>Entendendo as Redes no Docker: Uma Perspectiva Prática</h2>

<p>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.</p>

<p>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 &quot;pontes&quot; que permitem essa comunicação de maneiras diferentes, cada uma com trade-offs específicos. Vamos explorar cada uma delas com profundidade.</p>

<h2>Bridge: A Rede Padrão e Mais Comum</h2>

<h3>O Que é e Como Funciona</h3>

<p>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.</p>

<p>O importante aqui é entender que a bridge é <strong>isolada do host</strong>. 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).</p>

<h3>Criando e Testando uma Rede Bridge Customizada</h3>

<pre><code class="language-bash"># 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</code></pre>

<p>O output do comando <code>inspect</code> mostrará algo como:</p>

<pre><code class="language-json">{

&quot;Name&quot;: &quot;minha-rede-bridge&quot;,

&quot;Driver&quot;: &quot;bridge&quot;,

&quot;IPAM&quot;: {

&quot;Config&quot;: [

{

&quot;Subnet&quot;: &quot;172.18.0.0/16&quot;

}

]

},

&quot;Containers&quot;: {

&quot;abc123...&quot;: {

&quot;Name&quot;: &quot;web-server&quot;,

&quot;IPv4Address&quot;: &quot;172.18.0.2/16&quot;

}

}

}</code></pre>

<h3>Caso de Uso Real: Stack de Aplicação Web</h3>

<pre><code class="language-bash"># 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</code></pre>

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

<h2>Host: Máxima Performance com Máxima Exposição</h2>

<h3>Conceito e Limitações</h3>

<p>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.</p>

<p>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.</p>

<h3>Quando Usar e Exemplo Prático</h3>

<pre><code class="language-bash"># 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</code></pre>

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

<pre><code class="language-bash"># 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</code></pre>

<blockquote><p><strong>Aviso importante</strong>: 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.</p></blockquote>

<h2>Overlay: Comunicação Entre Hosts em Swarm</h2>

<h3>A Necessidade de Redes Distribuídas</h3>

<p>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 &quot;túnel&quot; encriptado entre os hosts. Ela funciona usando o protocolo VXLAN (Virtual Extensible LAN) para encapsular o tráfego.</p>

<p>A grande diferença em relação à bridge é que a overlay é <strong>distribuída</strong>. 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.</p>

<h3>Configurando um Swarm Simples com Overlay</h3>

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

<pre><code class="language-bash"># 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</code></pre>

<h3>Inspecionando a Rede Overlay</h3>

<pre><code class="language-bash">docker network inspect minha-rede-overlay</code></pre>

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

<pre><code class="language-json">{

&quot;Name&quot;: &quot;minha-rede-overlay&quot;,

&quot;Driver&quot;: &quot;overlay&quot;,

&quot;Scope&quot;: &quot;swarm&quot;,

&quot;Containers&quot;: {

&quot;container-id-1&quot;: {

&quot;Name&quot;: &quot;web-service.1.xxx&quot;,

&quot;IPv4Address&quot;: &quot;10.0.9.2/24&quot;

}

}

}</code></pre>

<h3>Caso de Uso: Stack Multi-Host</h3>

<pre><code class="language-bash"># Criar arquivo docker-compose.yml

cat &gt; docker-compose.yml &lt;&lt; &#039;EOF&#039;

version: &#039;3.8&#039;

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:

  • &quot;80:80&quot;

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</code></pre>

<p>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 <code>postgresql://database:5432</code>.</p>

<h2>Macvlan: Atribuindo Endereços MAC ao Contêiner</h2>

<h3>Uso e Casos de Uso</h3>

<p>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.</p>

<p>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.</p>

<h3>Configurando Macvlan na Prática</h3>

<pre><code class="language-bash"># 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 &#039;&quot;Networks&quot;&#039;</code></pre>

<h3>Verificando Conectividade Real</h3>

<pre><code class="language-bash"># 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 &quot;ping 192.168.1.100&quot;

O serviço está acessível como um host real

curl http://192.168.1.100</code></pre>

<h3>Limitação Importante: Comunicação Host-Contêiner</h3>

<pre><code class="language-bash"># 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</code></pre>

<p>Uma solução comum é usar um contêiner &quot;gateway&quot; ou simplesmente aceitar que a comunicação host→macvlan requer configuração adicional de roteamento.</p>

<h3>Caso Real: Servidor de Impressão em Rede</h3>

<pre><code class="language-bash"># 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.</code></pre>

<h2>Comparativo Prático: Quando Usar Cada Uma</h2>

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

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

<h3>Exemplo: Testando Performance</h3>

<pre><code class="language-bash">#!/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 &quot;Bridge: %{time_total}s\n&quot; http://server-bridge &amp;

Host

docker run -d --name server-host --network host nginx:latest

curl -w &quot;Host: %{time_total}s\n&quot; http://localhost:8080 &amp;

wait

docker stop server-bridge server-host

docker network rm teste-bridge</code></pre>

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

<h2>Conclusão</h2>

<p>Você aprendeu que as quatro redes do Docker servem propósitos distintos: <strong>bridge</strong> é versátil e isolada para a maioria dos casos; <strong>host</strong> oferece performance máxima ao custo do isolamento; <strong>overlay</strong> conecta contêineres distribuídos em swarms; <strong>macvlan</strong> 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.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://docs.docker.com/network/" target="_blank" rel="noopener noreferrer">Docker Official Documentation: Networking</a></li>

<li><a href="https://docs.docker.com/network/overlay/" target="_blank" rel="noopener noreferrer">Docker Swarm Mode: Overlay Networks</a></li>

<li><a href="https://docs.docker.com/network/drivers/overlay/" target="_blank" rel="noopener noreferrer">VXLAN and Docker: Deep Dive</a></li>

<li><a href="https://docs.docker.com/network/macvlan/" target="_blank" rel="noopener noreferrer">Macvlan Network Driver</a></li>

<li><a href="https://docs.docker.com/compose/networking/" target="_blank" rel="noopener noreferrer">Networking in Docker Compose</a></li>

</ul>

<p>&lt;!-- FIM --&gt;</p>

Comentários

Mais em Docker & Kubernetes

Service Mesh: Conceitos, Sidecar Proxy e Por que Usar na Prática
Service Mesh: Conceitos, Sidecar Proxy e Por que Usar na Prática

Service Mesh: O que é e por que existe Um Service Mesh é uma camada de infrae...

O que Todo Dev Deve Saber sobre Kubernetes Events e Auditoria: Rastreando Mudanças no Cluster
O que Todo Dev Deve Saber sobre Kubernetes Events e Auditoria: Rastreando Mudanças no Cluster

Introdução: Por que Rastrear Mudanças no Kubernetes? No dia a dia de um clust...

Boas Práticas de ConfigMaps e Secrets em Kubernetes: Injeção por Env e Volume para Times Ágeis
Boas Práticas de ConfigMaps e Secrets em Kubernetes: Injeção por Env e Volume para Times Ágeis

ConfigMaps e Secrets em Kubernetes: Uma Abordagem Prática Quando desenvolvemo...