Docker: Modelos de Comunicação Entre Contêineres
Última atualização: 2026-08-26
Os contêineres não apenas executam dentro de suas próprias redes — eles precisam descobrir e se comunicar uns com os outros. Entender como os contêineres se comunicam entre si é a base para construir uma arquitetura de microsserviços.
1. O Que Você Vai Aprender
- Três Maneiras de os Contêineres se Comunicarem Entre Si
- Usos Avançados de Aliases de Contêiner e DNS
- Métodos para Solucionar Problemas de Rede
- Política de Exposição de Portas
- Design de Isolamento de Grupo de Segurança
2. Uma História Real de uma Pessoa Desenvolvedora de Microsserviços
(1) Ponto de Dor: Os três microsserviços não estão conectados entre si
Charlie implantou três contêineres de microsserviços: API Gateway, Serviço de Usuários e Serviço de Pedidos. O API Gateway conseguia acessar o Serviço de Usuários, mas as requisições sempre expiravam. Após duas horas de solução de problemas, ele descobriu que o API Gateway havia exposto uma porta, mas o firewall não estava habilitado, o Serviço de Usuários estava usando o nome de contêiner errado e o Serviço de Pedidos estava em uma rede diferente.
(2) Soluções para Varredura Sistemática de Rede
Bob ensinou a ele um processo de solução de problemas de rede: nome do contêiner → DNS → rede → porta.
# Passo 1: Verificar resolução DNS
docker exec api nslookup user-service
# Passo 2: Testar conectividade de rede
docker exec api ping -c 2 user-service
# Passo 3: Testar conectividade de porta
docker exec api nc -zv user-service 8080
(3) Benefícios: Tempo de solução de problemas de rede reduzido de 2 horas para 10 minutos
Com um processo sistemático de solução de problemas em vigor, o tempo que Charlie levava para solucionar problemas de rede caiu de 2 horas para 10 minutos.
3. Três Métodos de Comunicação Entre Contêineres
(1) Comparação de Métodos
graph TB
subgraph Method1["① --link (Legado, Obsoleto)"]
L1["Contêiner A"] -->|"variáveis env + /etc/hosts"| L2["Contêiner B"]
end
subgraph Method2["② Rede Personalizada + DNS (Recomendado)"]
D1["Contêiner A"] -->|"resolução automática DNS"| D2["Contêiner B"]
end
subgraph Method3["③ Porta Exposta + IP do Host"]
E1["Contêiner A"] -->|"host:porta"| E2["Contêiner B<br/>(via bridge do host)"]
end
| Método | Princípio | DNS | Status | Recomendação |
|---|---|---|---|---|
--link |
Variáveis de Ambiente + Injeção em hosts | ❌ | ❌ Obsoleto | ⭐ |
| DNS de Rede Personalizada | DNS Integrado do Docker | ✅ | ✅ Recomendado | ⭐⭐⭐ |
| Encaminhamento de Porta do Host | Contêiner→Host→Contêiner | ❌ | Disponível | ⭐⭐ |
4. --link (Obsoleto)
▶ Exemplo: Entendendo como --link funciona (Dificuldade: ⭐)
# Link legado: B pode alcançar A pelo hostname
docker run -d --name db postgres:15-alpine
docker run -d --name web --link db:database nginx:alpine
# web pode usar "database" como hostname (via /etc/hosts)
docker exec web cat /etc/hosts
--link foi obsoleto e é usado apenas para referência histórica. Ele só oferece suporte a conexões unidirecionais (web→db, não db→web), e o arquivo hosts não é atualizado quando o endereço IP muda após a reinicialização do contêiner. Sempre use uma rede personalizada.**
5. Um Guia Detalhado do DNS de Rede Personalizada
(1) O Processo de Resolução DNS
graph LR
A["Contêiner A<br/>ping db"] --> B["Docker DNS<br/>127.0.0.11"]
B -->|db → 172.18.0.2| C["Contêiner B<br/>172.18.0.2"]
▶ Exemplo: --network-alias para definir um alias (Dificuldade: ⭐⭐)
# Iniciar contêiner com alias de rede
docker run -d --name my-postgres \
--network app-net \
--network-alias=database \
--network-alias=db \
postgres:15-alpine
# Ambos os nomes resolvem para o mesmo contêiner
docker exec api ping -c 1 database # resolve para my-postgres
docker exec api ping -c 1 db # mesmo IP
(1) Nome do Contêiner vs. Alias de Rede
| Tipo | Definição | Escopo | Prioridade |
|---|---|---|---|
--name |
Nome do Contêiner | Todas as Redes | Alta |
--network-alias |
Alias de Rede | Apenas Rede Especificada | Média |
| Nome de serviço Docker Compose | Nome do serviço | Rede Compose | Alta |
--network-alias permite que o mesmo contêiner tenha nomes diferentes em redes diferentes. Por exemplo, o banco de dados é nomeado primary-db na backend-net e database na admin-net.
6. Política de Exposição de Portas
(1) --expose vs -p vs -P
| Parâmetro | Função | Acessível Externamente | Casos de Uso |
|---|---|---|---|
--expose 3306 |
Declaração de Porta (Documentação) | ❌ Não Mapeado | Comunicação Entre Contêineres |
-p 3306:3306 |
Mapeado para o host | ✅ Acessível de fora | Serviço externo |
-P |
Mapear Aleatoriamente Portas EXPOSE | ✅ Portas Aleatórias | Desenvolvimento e Depuração |
▶ Exemplo: Use docker port para visualizar mapeamentos de porta (Dificuldade: ⭐)
# Verificar mapeamentos de porta de um contêiner
docker port web
# Exemplo de saída
80/tcp -> 0.0.0.0:8080
7. Solução de Problemas de Rede
(1) Árvores de Decisão para Solução de Problemas
graph TB
START["Contêiner A<br/>não consegue alcançar o Contêiner B"] --> DNS{"Resolução DNS?"}
DNS -->|Falha| FIX1["Mesma Rede Personalizada?<br/>Use --name ou --network-alias"]
DNS -->|Sucesso| PING{"Ping alcançável?"}
PING -->|Falha| FIX2["Na Mesma Rede?<br/>docker network connect"]
PING -->|Sucesso| PORT{"Conexão de Porta?<br/>nc -zv B porta"]
PORT -->|Falha| FIX3["Porta Exposta?<br/>B está ouvindo a porta correta?"]
PORT -->|Sucesso| APP{"Protocolo da Aplicação?<br/>Teste curl/wget"]
APP -->|Falha| FIX4["Verifique a configuração da app<br/>Variáveis de Ambiente/URL"]
APP -->|Sucesso| OK["✅ Comunicação funcionando corretamente"]
▶ Exemplo: Comandos para solucionar problemas de rede de contêineres (Dificuldade: ⭐⭐)
# Passo 1: Verificar resolução DNS
docker exec api nslookup db
docker exec api getent hosts db
# Passo 2: Testar conectividade básica
docker exec api ping -c 2 db
# Passo 3: Testar porta específica
docker exec api nc -zv db 5432
# ou com wget
docker exec api wget -qO- http://api:8080/health
# Passo 4: Verificar interfaces de rede do contêiner
docker exec api ip addr
# Passo 5: Verificar tabela de roteamento
docker exec api ip route
▶ Exemplo: docker network connect para ingressar dinamicamente em uma rede (Dificuldade: ⭐⭐)
# Conectar um contêiner em execução a outra rede
docker network connect backend-net web
# Desconectar de uma rede
docker network disconnect frontend-net web
# Verificar as redes do contêiner
docker inspect web --format='{{json .NetworkSettings.Networks}}' | python3 -m json.tool
8. Design de Isolamento de Grupo de Segurança
(1) Modelo de Isolamento de Três Camadas
| Camada de Rede | Contêiner | Acessível | Porta Externa |
|---|---|---|---|
| Frontend Net | Nginx/CDN | Apenas Backend Net | 80, 443 |
| Backend Net | API/Worker | Apenas DB Net | Nenhuma (via proxy Nginx) |
| DB Net | PostgreSQL/Redis | Sem acesso externo | Nenhuma |
9. Exemplo Completo: Configuração e Solução de Problemas de Rede de Microsserviços
# ============================================
# Passo a passo completo: Rede de microsserviços
# Abrange: redes, aliases, isolamento, depuração
# ============================================
# 1. Criar redes isoladas
docker network create frontend-net
docker network create backend-net
docker network create db-net
# 2. Iniciar banco de dados (apenas db-net)
docker run -d --name postgres \
--network db-net \
--network-alias=database \
--network-alias=primary-db \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=myapp \
postgres:15-alpine
# 3. Iniciar servidor API (backend-net + db-net)
docker run -d --name api \
--network backend-net \
--network-alias=api-server \
-e DATABASE_URL="postgresql://postgres:secret@primary-db:5432/myapp" \
myapp-api:1.0
docker network connect db-net api
# 4. Iniciar Nginx (frontend-net + backend-net)
docker run -d --name nginx \
--network frontend-net \
--network-alias=gateway \
-p 8080:80 \
nginx:1.25-alpine
docker network connect backend-net nginx
# 5. Depurar: verificar conectividade
echo "=== Resolução DNS ==="
docker exec nginx nslookup api-server
docker exec api nslookup primary-db
echo "=== Conectividade de Porta ==="
docker exec nginx nc -zv api-server 5000
docker exec api nc -zv primary-db 5432
echo "=== Verificação de Isolamento ==="
docker exec nginx sh -c "timeout 2 nc -zv primary-db 5432 2>&1 || echo 'BLOQUEADO: nginx não pode alcançar db diretamente (esperado)'"
# 6. Limpar
docker stop postgres api nginx
docker rm postgres api nginx
docker network rm frontend-net backend-net db-net
❓ Perguntas Frequentes
P: --link foi obsoleto? R: Sim. O Docker tornou oficialmente obsoleto o --link e recomenda o uso de redes personalizadas + DNS. Problemas com o --link incluem: conexões unidirecionais, endereços IP não atualizando após uma reinicialização e falta de suporte ao Compose. As redes personalizadas resolvem todos esses problemas.
P: Os nomes dos contêineres são únicos em diferentes redes? R: Os nomes dos contêineres são globalmente únicos no host Docker. No entanto, a resolução DNS ocorre no nível da rede — apenas contêineres na mesma rede podem resolver uns aos outros pelo nome do contêiner. Para resolver entre redes, você deve primeiro adicionar
docker network connect.
P: Como posso garantir que um contêiner só possa ser acessado por contêineres específicos? R: Use isolamento de rede. Coloque o serviço que você deseja proteger (como um banco de dados) em uma rede dedicada e adicione apenas os contêineres que precisam acessá-lo a essa rede. Por exemplo, se o banco de dados estiver na
db-net, apenas a API é adicionada àdb-net, então o Nginx não pode acessar o banco de dados diretamente.
P: O que devo fazer se um contêiner sofrer um timeout de DNS? R: Timeouts de DNS geralmente são causados por: ① O contêiner não está na mesma rede (mais comum); ② Um erro de digitação no nome do contêiner; ③ Problemas de cache DNS (reiniciar o contêiner resolve isso). Solução de problemas:
docker exec <contêiner> nslookup <alvo>Verifique os resultados da resolução.
P: Como visualizo o endereço IP real do contêiner? R:
docker inspect <contêiner> --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'. Ou entre no contêiner e executeip addr/hostname -I. Mas lembre-se: o endereço IP pode mudar, então use o nome do contêiner em vez do endereço IP no código de produção.
📖 Resumo
- Para comunicação entre contêineres, recomendamos o uso de rede personalizada + DNS; descontinue o --link
- Rede bridge personalizada: Os nomes dos contêineres são registrados automaticamente no DNS, e os contêineres na mesma rede se comunicam por nome
--network-aliasAtribuir aliases aos contêineres; o mesmo contêiner pode ter nomes diferentes em redes diferentes- Exposição de porta:
--exposeapenas documentado,-pmapeado para o host,-Pmapeado aleatoriamente - Solução de problemas de rede em quatro etapas: Resolução DNS → Ping → Teste de porta → Teste de protocolo da aplicação
- Arquitetura de três camadas: Frontend → Backend → Banco de Dados; o banco de dados não é exposto à rede frontend
📝 Exercícios
- Exercício Básico (Dificuldade: ⭐): Crie duas redes personalizadas, inicie um contêiner em cada uma e verifique se a resolução DNS para nomes de contêineres dentro da mesma rede funciona corretamente.
- Exercício Avançado (Dificuldade: ⭐⭐): Verifique se contêineres em redes diferentes não podem fazer ping uns nos outros e, em seguida, estabeleça uma conexão usando
docker network connecte depois desconecte. - Pergunta Desafiadora (Dificuldade: ⭐⭐⭐): Use
docker exec+nc/wgetpara solucionar a causa raiz de um contêiner não conseguir acessar o serviço de outro contêiner. Descreva as etapas de solução de problemas e tire uma conclusão.