Conecte containers com redes Docker
Vá além da publicação de portas e aprenda como os containers de fato conversam entre si. Explore a bridge padrão, crie uma rede personalizada com DNS automático e prove a comunicação container-a-container pelo nome com testes reais de ping e wget.
Problema
Você já sabe rodar um container e publicar uma porta para o navegador. Mas aplicações reais nunca são um container só — um app web conversa com um banco, um cache, uma fila. No momento em que você tem dois containers que precisam se alcançar, surge uma nova pergunta: **como um container acha e conversa com o outro?** Iniciantes apelam para endereços IP fixos, e funciona — até um container reiniciar, ganhar um IP novo e tudo quebrar. A resposta do Docker são as *redes*: redes virtuais que conectam containers e, numa rede personalizada, te dão **DNS automático** para que um container alcance o outro simplesmente pelo nome, não importa qual IP ele receba. Neste lab você vai ver exatamente por que a rede `bridge` padrão não basta, criar sua própria rede, rodar dois containers nela e provar que eles se resolvem pelo nome com saída real de `ping` e `wget`. Você também vai aprender a inspecionar redes, conectar e desconectar containers em tempo real e usar redes separadas para isolar grupos de serviços — o exato mecanismo que o Compose usa por baixo dos panos.
Objetivos
- Explicar o modelo de rede do Docker e quando usar os drivers
bridge,hostenone - Explorar a bridge padrão com
docker network lsedocker network inspect, e ver por que containers ali só se alcançam por IP - Criar uma rede bridge personalizada com
docker network createe entender o DNS automático que ela oferece - Rodar dois containers numa rede personalizada e provar que eles se resolvem pelo nome usando saída real de
ping,wgetecurlde dentro de um container - Conectar e desconectar containers de redes em tempo de execução com
docker network connect/disconnect - Usar redes separadas para isolar grupos de serviços e depois ligá-las de propósito com uma rede compartilhada — e limpar tudo
Pré-requisitos
- Docker instalado e rodando (Docker Desktop no Windows/macOS, ou Docker Engine no Linux). Rode
docker version— uma seção Client e uma Server significa que você está pronto. - Familiaridade com o ciclo básico de containers (
docker run,docker ps,docker exec,docker stop,docker rm) — este é o Lab 4 de Docker, então os labs anteriores são pressupostos. - Um terminal (PowerShell, bash ou zsh) e acesso à internet para baixar as imagens
nginxebusybox - Git instalado, para entregar seu deliverable no fim
- Nenhuma teoria de redes prévia é exigida — cada conceito é introduzido quando você precisa dele
O que você vai construir
Você não vai escrever código de aplicação neste lab. Em vez disso, vai conectar dois containers
para que eles conversem entre si pelo nome — a habilidade de rede mais importante para apps
reais, multi-serviço. Você primeiro vai ver a bridge padrão falhar em resolver nomes, depois
criar sua própria rede onde isso funciona, e provar com saída real de ping e wget capturada
de dentro de um container.
O modelo mental essencial: containers ficam isolados até uma rede conectá-los
Por padrão um container é uma caixa lacrada. Publicar uma porta com -p abre uma porta para o
host, mas não diz nada sobre como dois containers se alcançam entre si. É isso que uma
rede Docker é: um switch virtual no qual os containers se plugam. Dois containers na mesma rede
podem conversar; dois containers em redes diferentes não podem (a menos que você os ligue de
propósito).
Os três drivers de rede que você vai encontrar
| Driver | O que faz | Quando usar |
|---|---|---|
| bridge | O padrão. Uma rede virtual privada num único host; containers ganham IPs internos e podem conversar entre si | Quase sempre — a escolha padrão para containers numa máquina |
| host | Remove o isolamento de rede; o container compartilha diretamente a pilha de rede do host (sem precisar de -p) |
Raro — quando você precisa de desempenho máximo de rede ou o container precisa ligar em portas do host diretamente |
| none | Desabilita a rede por completo; o container tem só uma interface de loopback | Quando um container precisa ficar totalmente isolado de qualquer rede |
Existe também a overlay, usada para conectar containers em múltiplos hosts num Swarm/cluster
— fora do escopo deste lab de host único, mas vale saber que ela existe.
A sacada principal: bridge padrão vs bridge personalizada
Ambas são redes "bridge", mas se comportam de forma diferente, e isso pega quase todo mundo:
- Na rede
bridgepadrão (aquela que os containers entram automaticamente), containers só se
alcançam por endereço IP — não há resolução de nomes automática. - Numa rede bridge personalizada (uma que você cria com
docker network create), o Docker
roda um servidor DNS embutido para que os containers se resolvam pelo nome. Essa é toda
a razão para criar suas próprias redes.
Você vai ver os dois comportamentos em primeira mão. Faça os passos em ordem — cada um se apoia no
anterior, e você vai coletar as saídas que precisa para a entrega do Passo 6.
Passos
-
Entenda o modelo de rede do Docker e os drivers
Antes de criar qualquer coisa, tenha o mapa na cabeça: o que é uma rede Docker e qual driver
faz o quê.Por que redes existem
Um container é isolado por padrão. Quando você rodou
docker run -d -p 8080:80 nginx, a flag
-pabriu um caminho do seu host até o container — mas isso é host-para-container. Não diz
nada sobre como um segundo container alcançaria o primeiro. Para isso, ambos os containers
precisam compartilhar uma rede.Liste as redes que o Docker já tem
Uma instalação nova do Docker vem com três redes. Olhe para elas:
docker network lsVocê verá ao menos:
NETWORK ID NAME DRIVER SCOPE xxxxxxxxxxxx bridge bridge local xxxxxxxxxxxx host host local xxxxxxxxxxxx none null localElas mapeiam diretamente para os três drivers que você vai usar num único host:
-
bridge — a rede privada padrão. Todo container iniciado sem
--networkentra nesta.
Containers aqui ganham um IP interno e se alcançam por IP. -
host — sem isolamento; o container usa a rede do host diretamente. Inicie um container
com--network hoste suas portas são as portas do host (sem mapeamento-p). Rápido, mas
você perde o isolamento e não pode rodar dois containers que querem a mesma porta. -
none — rede desabilitada.
--network nonedá ao container só uma interface de loopback.
Útil para um job que não pode tocar a rede de jeito nenhum.
A decisão em uma linha
Use bridge (quase sempre), apele para host só quando precisar da rede crua do host, e
use none quando um container precisa ficar isolado da rede. Para clusters multi-host
existe a overlay, que este lab não cobre.Checkpoint
- Qual driver os containers usam se você não passa
--network? (bridge — o padrão) -
-p 8080:80deixa dois containers conversarem entre si? (Não — ele só conecta o host a um container. Container-a-container precisa de uma rede compartilhada.) - Qual driver você escolheria para um job em lote que nunca pode fazer chamada de rede? (none)
-
bridge — a rede privada padrão. Todo container iniciado sem
-
Explore a bridge padrão e bata no limite de DNS dela
Vamos provar por que a bridge padrão não basta, para que a rede personalizada do Passo 3
pareça merecida e não arbitrária.Baixe uma imagem pequena e amiga do ping
Você vai usar o busybox — uma imagem minúscula que traz
ping,wget,nslookupe um
shell, perfeita para testes de rede.docker pull busybox:1.36 docker pull nginx:1.27-alpineRode dois containers na bridge padrão
Inicie dois containers busybox de vida longa sem a flag
--network, para que entrem na
bridge padrão. Osleep 3600só os mantém vivos para você conseguir dar exec neles.docker run -d --name c1 busybox:1.36 sleep 3600 docker run -d --name c2 busybox:1.36 sleep 3600 docker psInspecione a bridge padrão
Veja quem está conectado e quais IPs receberam:
docker network inspect bridgeRole até a seção
"Containers"— você verác1ec2, cada um com umIPv4Addresscomo
172.17.0.2/16e172.17.0.3/16. Anote o IP dec2; você vai usá-lo já já.A limitação: a resolução de nomes falha
Tente alcançar
c2pelo nome de dentro dec1:docker exec c1 ping -c 2 c2Isso falha —
ping: bad address 'c2'. Na bridge padrão não há DNS, então o nomec2não
significa nada. Agora tente o mesmo container pelo IP (use o endereço que você viu na
saída do inspect):docker exec c1 ping -c 2 172.17.0.3Isso funciona. Os containers conseguem se alcançar — estão na mesma rede — mas só por IP.
E IPs mudam toda vez que um container reinicia, o que faz de fixá-los uma armadilha.Checkpoint
- Na bridge padrão, por que
ping c2falhou masping <IP do c2>funcionou? (Sem DNS na bridge padrão — nomes não são resolvidos, só IPs crus roteiam.) - Por que depender do IP é uma má ideia? (IPs são atribuídos dinamicamente e mudam no restart; sua config quebraria.)
Entregável deste passo: capture a saída do
ping c2que falha e a doping <IP>que
funciona — elas são a metade "antes" da sua entrega. - Na bridge padrão, por que
-
Crie uma rede personalizada com DNS automático
Agora o ganho. Numa rede que você cria, o Docker roda um servidor DNS embutido e os
containers se resolvem pelo nome.Crie a rede
docker network create minha-redeO Docker imprime o ID da nova rede. Por padrão ela usa o driver bridge (você pode ser
explícito com--driver bridge, mas bridge é o padrão para um único host). Confirme que
existe:docker network lsVocê verá
minha-redena lista ao lado das embutidasbridge,hostenone.Rode dois containers na nova rede
A flag
--networkliga um container a uma rede no momento em que ele inicia. Rode um servidor
web nginx e um cliente busybox, ambos emminha-rede:docker run -d --network minha-rede --name web nginx:1.27-alpine docker run -d --network minha-rede --name cliente busybox:1.36 sleep 3600-
web— o servidor nginx, alcançável na porta 80 dentro da rede (repare: nenhum-pé
preciso para tráfego container-a-container; você só publica uma porta quando o
host/navegador precisa entrar). -
cliente— uma caixa busybox de onde você vai rodar os comandos de teste.
Inspecione a rede personalizada
docker network inspect minha-redeNo bloco
"Containers"você veráwebeclienteconectados, cada um com um IP na sub-rede
desta rede. Igual à bridge padrão até aqui — a diferença fica invisível até você usar um nome,
que é o próximo passo.Por que isso importa
No instante em que dois containers compartilham uma rede personalizada, o Docker registra os
nomes deles no seu DNS interno.webeclienteagora se acham pelo nome — sem IPs, sem
arquivos de config, sem restarts quebrando nada. É exatamente isso que o Docker Compose
configura para você automaticamente nos bastidores; aqui você está fazendo na mão para
entender a engrenagem.Checkpoint
- Para qual driver o
docker network createcai por padrão num único host? (bridge) - Por que você não passou
-pao iniciarweb? (Porqueclienteo alcança pela rede compartilhada na porta 80 diretamente;-pé só para expor um container ao host.)
Entregável deste passo: a saída de
docker network lsmostrandominha-rede, e a saída de
docker network inspect minha-redemostrando os dois containers conectados. -
-
Prove a comunicação container-a-container pelo nome
Este é o coração do lab: rodar testes reais de dentro de um container contra outro, usando só
nomes. Este é o "depois" que contrasta com a falha do Passo 2.Ping pelo nome — agora funciona
De dentro de
cliente, dê ping emwebpelo nome:docker exec cliente ping -c 3 webDiferente do Passo 2, isso funciona: você verá respostas de
webe, o mais importante, o
nome resolve para um IP naminha-rede:PING web (172.19.0.2): 56 data bytes 64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.089 ms 64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.101 ms ...O DNS embutido do Docker transformou
webno IP certo automaticamente. Este é todo o
propósito das redes personalizadas.Confirme a resolução de DNS explicitamente
docker exec cliente nslookup webVocê verá
webresolver para o IP do container via o servidor DNS do Docker em127.0.0.11—
o resolver embutido que toda rede personalizada ganha.Busque a página web de verdade pelo nome
O ping prova alcançabilidade; agora prove que o serviço responde.
webroda nginx na porta
80, então peça a homepage dele a partir declienteusando o nome:docker exec cliente wget -qO- http://webVocê vai receber o HTML da página "Welcome to nginx!", buscado pela rede pelo nome. Se a saída
dowgetdo busybox ficar silenciosa,wget -S http://web -O /dev/nullmostra os cabeçalhos
da resposta (um200 OKdo nginx) no lugar.Nota sobre
curl: o busybox trazwget, nãocurl. Se você preferecurl, rode-o a
partir de uma imagem que o tenha, ex.:docker run --rm --network minha-rede curlimages/curl:8.9.1 -s http://web.
A lição é idêntica — o nomewebresolve dentro da rede.Por que isso é tão importante
Você acabou de endereçar outro container por um nome estável que sobrevive a restarts, em
vez de um IP frágil. Seu app web pode apontar paradb, seu worker pararedis, e continua
funcionando não importa quais IPs o Docker distribua. A descoberta de serviços por nome é a
base da qual todo arquivo Compose e ferramenta de orquestração depende.Checkpoint
- O que fez
ping webfuncionar aqui quandoping c2falhou no Passo 2? (Esta rede é personalizada, então o DNS embutido do Docker resolve os nomes dos containers; a bridge padrão não tem esse DNS.) - Qual IP de servidor DNS o
nslookupreportou? (127.0.0.11 — o resolver embutido do Docker.)
Entregável deste passo: capture o
ping -c 3 webbem-sucedido, a saída denslookup webe
a saída dewget -qO- http://web(ou-S) mostrando que o nginx respondeu pelo nome. - O que fez
-
Gerencie redes: conectar, desconectar, isolar, diagnosticar
Redes não são estáticas. Você pode ligar e desligar containers em execução e usar redes
separadas para isolar grupos de serviços — a verdadeira razão pela qual redes são uma
ferramenta de segurança, não só uma conveniência.Isolamento: um container em outra rede não consegue entrar
Inicie um terceiro container na bridge padrão (não na
minha-rede) e tente alcançarweb:docker run -d --name estranho busybox:1.36 sleep 3600 docker exec estranho ping -c 2 webIsso falha —
estranhonão está naminha-rede, então nem consegue resolver ou rotear até
web. Redes separadas isolam serviços: exatamente como você manteria um banco de dados fora da
rede voltada ao público. Isso espelha a divisãowebnetvsdbnetdo ebook, onde um container
web e um container db em redes diferentes simplesmente não conseguem conversar.Conecte um container em execução a uma rede
Você não precisa recriar um container para ligá-lo à rede. Ligue
estranhoàminha-redeao
vivo:docker network connect minha-rede estranho docker exec estranho ping -c 2 webAgora funciona —
estranhoganhou uma segunda interface naminha-redee consegue
resolverweb. Este é o truque de "rede compartilhada" do ebook: dois grupos que de outra
forma estariam isolados podem ser ligados de propósito ao entrarem numa rede comum, sem
derrubar nada.Desconecte-o de novo
docker network disconnect minha-rede estranho docker exec estranho ping -c 2 web # falha de novo — de volta ao isoladoDiagnostique de dentro de um container
Quando algo não conecta, estas ferramentas (todas no busybox) dizem por quê:
docker exec cliente nslookup web # o nome está resolvendo? docker exec cliente ping -c 2 web # o host está alcançável? docker exec cliente wget -S http://web -O /dev/null # o serviço está respondendo (200)? docker network inspect minha-rede # quem está de fato conectado?Trabalhe de cima para baixo: DNS → alcançabilidade → resposta do serviço → participação na
rede. A maioria dos bugs de "não conecta" é um container simplesmente não estar na rede
esperada — odocker network inspectrevela na hora.Limpe as redes
Desconecte ou pare os containers e então remova a rede. Uma rede não pode ser removida enquanto
houver containers conectados:docker rm -f web cliente c1 c2 estranho docker network rm minha-rede docker network prune # remove TODAS as redes não usadas; pede confirmaçãoCheckpoint
- Por que
estranhonão alcançavaweba princípio? (Estava na bridge padrão, não naminha-rede— redes diferentes são isoladas.) - Como você as ligou sem recriar o container? (
docker network connect minha-rede estranhoo ligou ao vivo.) - O que precisa ser verdade antes de
docker network rmfuncionar? (Nenhum container conectado àquela rede.)
Entregável deste passo: capture a falha de isolamento, o
docker network connect+ ping
bem-sucedido, e a limpeza final confirmando que a rede sumiu. - Por que
-
Entregue: documente sua rede e os testes de conectividade
Prove que você conectou dois containers e os fez conversar pelo nome capturando a evidência
real num pequeno repositório.Monte sua entrega
Crie uma pasta, inicialize o git e escreva um
SUBMISSION.mddocumentando o que você fez. Cole
as saídas reais que coletou — não texto inventado. O contraste entre a bridge padrão (Passo
2) e sua rede personalizada (Passo 4) é o núcleo da entrega.# Docker Lab 4 — Conecte containers com redes Docker ## 1. docker network ls (redes padrão + minha-rede) <cole seu `docker network ls` mostrando bridge/host/none e minha-rede> ## 2. Bridge padrão: nome FALHA, IP funciona Saída de `docker exec c1 ping -c 2 c2` (deve FALHAR: bad address): <cole> Saída de `docker exec c1 ping -c 2 <IP do c2>` (deve FUNCIONAR): <cole> ## 3. docker network inspect minha-rede <cole, mostrando web e cliente conectados> ## 4. Rede personalizada: nome RESOLVE Saída de `docker exec cliente ping -c 3 web` (deve FUNCIONAR): <cole> Saída de `docker exec cliente nslookup web`: <cole — repare no resolver 127.0.0.11> Saída de `docker exec cliente wget -qO- http://web` (ou `-S`): <cole — o nginx respondeu pelo nome> ## 5. Isolamento + connect/disconnect `docker exec estranho ping web` antes do connect (FALHA): <cole> Após `docker network connect minha-rede estranho`, ping web (FUNCIONA): <cole> ## 6. Limpeza <cole `docker network rm minha-rede` e um `docker network ls` final> ## Reflexão (2-3 frases) Nas minhas palavras: por que a bridge padrão não resolvia nomes, o que uma rede personalizada acrescenta (DNS embutido) e por que a descoberta por nome ganha de IPs fixos.Entregue
git init git add SUBMISSION.md git commit -m "Docker lab 4 — redes de containers" # faça push para um repo público ou crie um gist, depois entregue essa URLEntregue a URL do repositório ou gist como seu deliverable do lab.
Critério de submissão (autoverificação)
- A saída de
docker network lsmostra suaminha-redeao lado das redes embutidas - Você capturou a bridge padrão falhando em resolver um nome (
ping <nome>→ bad address) mas funcionando por IP -
docker network inspect minha-redemostra os dois containers conectados -
ping -c 3 weba partir declientefunciona pelo nome na rede personalizada -
nslookup webmostra a resolução via o DNS embutido127.0.0.11 -
wget http://webretornou a resposta do nginx (HTML da página ou um cabeçalho200) — um serviço real respondeu pelo nome - Você demonstrou o isolamento e um
docker network connectao vivo corrigindo-o - Um
docker network lsfinal confirma queminha-redefoi removida (host limpo) - Sua reflexão explica corretamente bridge padrão vs DNS de rede personalizada e por que nomes ganham de IPs
Checklist anti-stub
Toda saída precisa ser real e sua. IPs inventados, blocos de exemplo copiados e colados
ou umpingque "funcionaria" não são uma entrega. O corretor procura o contraste: o mesmo
ping <nome>que falha na bridge padrão e funciona naminha-rede. Se os dois parecerem
idênticos, você não rodou um deles de verdade.O que vem a seguir
Você já sabe conectar containers em redes e fazê-los se descobrir pelo nome — a espinha dorsal
de todo app multi-serviço. Mas tudo que você fez até aqui é efêmero: apague um container e
os dados dele somem. No próximo lab de Docker você vai resolver isso com volumes e
persistência de dados — mantendo bancos e arquivos vivos entre restarts e rebuilds de
containers. - A saída de