Redes no Docker
Nesta aula, você aprenderá sobre redes no Docker, incluindo os tipos de redes disponíveis (bridge, host, none, overlay), como os containers se comunicam entre si, como expor portas para o host e o mundo externo, e como o isolamento de rede funciona. Ao final, você terá uma base sólida para projetar e gerenciar a rede de suas aplicações Docker.
Bem-vindo à aula sobre Redes no Docker! Nesta aula, vamos explorar um dos pilares da orquestração de containers: a rede. Entender como os containers se comunicam entre si e com o mundo externo é essencial para construir aplicações distribuídas, escaláveis e seguras. Vamos começar com uma visão geral dos tipos de rede que o Docker oferece e depois mergulhar em detalhes práticos, como comunicação entre containers, exposição de portas e estratégias de isolamento.
O Docker fornece uma camada de abstração de rede que permite aos containers se conectarem de várias maneiras, dependendo das necessidades da aplicação. Seja em um único host ou em um cluster multi-host (como no Docker Swarm), o Docker simplifica a configuração de rede, mas exige que o desenvolvedor entenda os conceitos para tomar decisões corretas. Vamos abordar cada aspecto com exemplos práticos e boas práticas.
Tipos de rede
O Docker oferece vários drivers de rede, cada um com características específicas. Os principais são: bridge, host, none e overlay. O driver padrão é o bridge, que cria uma rede privada interna no host, permitindo que os containers se comuniquem entre si e com o host, mas com isolamento em relação ao mundo externo.
O driver host remove o isolamento de rede entre o container e o host, usando diretamente a interface de rede do host. Isso pode melhorar o desempenho, mas reduz o isolamento. O driver none desativa completamente a rede, útil para containers que não precisam de conectividade. Já o driver overlay é usado em clusters (Swarm) para permitir comunicação entre containers em diferentes hosts, criando uma rede virtual sobreposta.
Para listar as redes existentes, use o comando docker network ls. Para inspecionar uma rede, use docker network inspect. Vamos ver um exemplo:
docker network ls
# NETWORK ID NAME DRIVER SCOPE
# 1a2b3c4d5e6f bridge bridge local
# 7f8e9d0c1b2a host host local
# 3c4d5e6f7a8b none null localPara criar uma rede personalizada do tipo bridge, usamos:
docker network create --driver bridge minha-redeE para conectar um container a essa rede, no momento da criação ou depois:
docker run -d --name meu-container --network minha-rede nginx
# ou
docker network connect minha-rede meu-containerComunicação entre containers
A comunicação entre containers é um dos principais motivos para usar redes personalizadas. Na rede bridge padrão, os containers podem se comunicar por IP, mas o IP pode mudar quando o container é recriado. Para uma comunicação estável, é melhor usar o nome do container como hostname, o que o Docker resolve automaticamente para o IP correto.
Vamos criar dois containers na mesma rede personalizada e testar a comunicação:
docker network create minha-rede
docker run -d --name web --network minha-rede nginx
docker run -it --name teste --network minha-rede alpine sh
# dentro do container teste:
ping webO comando ping web deve funcionar, pois o Docker fornece um servidor DNS embutido para redes personalizadas. Isso facilita a comunicação entre serviços, como um backend e um banco de dados.
Além disso, é possível expor portas entre containers sem publicá-las no host. Por exemplo, um container backend pode escutar na porta 8080 e o frontend pode acessá-lo via http://backend:8080.
Para verificar a comunicação, você pode usar ferramentas como curl ou ping dentro dos containers, como mostrado acima.
Portas
Para permitir que o mundo externo acesse um container, é necessário publicar portas. Isso é feito com a flag -p ou --publish no comando docker run. A sintaxe é -p <porta-do-host>:<porta-do-container>.
Por exemplo, para publicar a porta 80 do container nginx na porta 8080 do host:
docker run -d -p 8080:80 nginxAgora, você pode acessar o container via http://localhost:8080. É possível também publicar portas em um intervalo, usar UDP, ou deixar o Docker escolher uma porta aleatória do host com -P (publica todas as portas expostas).
Para ver as portas publicadas de um container, use docker port <container>:
docker port web
# 80/tcp -> 0.0.0.0:8080É importante notar que a publicação de portas é uma ponte entre o host e o container. Se você não publicar uma porta, o container só será acessível de dentro da rede Docker, o que é útil para serviços internos.
Isolamento
O isolamento de rede é um recurso de segurança crucial. No Docker, ele é alcançado por meio de namespaces e iptables. Cada container tem seu próprio namespace de rede, o que significa que ele tem suas próprias interfaces, rotas e regras de firewall, isolando-o do host e de outros containers.
Por padrão, os containers em uma rede bridge podem se comunicar entre si, mas não com o host (a menos que as portas sejam publicadas). Para um isolamento mais rígido, você pode usar redes none ou configurar políticas de rede, como usar redes separadas para diferentes camadas da aplicação.
Uma boa prática é criar redes separadas para cada componente da aplicação, limitando a comunicação apenas ao necessário. Por exemplo, um banco de dados pode estar em uma rede privada, enquanto o backend está em outra rede que também se conecta à rede do banco, mas o frontend só se conecta ao backend.
Para conectar um container a múltiplas redes, use docker network connect. Para desconectar, use docker network disconnect. Isso permite um controle fino sobre o tráfego.
docker network create backend-net
docker network create frontend-net
docker run -d --name banco --network backend-net mysql
docker run -d --name backend --network backend-net --network frontend-net meu-backend
docker run -d --name frontend --network frontend-net meu-frontendNesse cenário, o backend pode acessar o banco e o frontend, mas o frontend não pode acessar o banco diretamente.
Além disso, você pode usar o driver none para desativar completamente a rede, se o container não precisar de conectividade externa, como em tarefas de processamento em lote.
Boas práticas e observações finais
Ao trabalhar com redes no Docker, lembre-se de:
- Usar redes personalizadas em vez da bridge padrão para obter resolução de DNS por nome.
- Expor apenas as portas necessárias para o mundo externo, minimizando a superfície de ataque.
- Isolar componentes críticos em redes separadas para reduzir o risco de acesso não autorizado.
- Nomear os containers de forma clara para facilitar a comunicação.
- Usar o comando
docker network inspectpara diagnosticar problemas de conectividade.
Com essas práticas, você terá uma infraestrutura de rede robusta e segura para suas aplicações Docker.
Referências
- Documentação oficial de rede do Docker
- Redes bridge no Docker
- Redes host no Docker
- Redes overlay no Docker
- Redes none no Docker
- Comandos de rede do Docker
- Redes no Docker Compose
Exercícios
Explique a diferença entre os drivers de rede bridge, host e none do Docker, e dê um exemplo de caso de uso para cada um.
✓ Resposta: O driver bridge cria uma rede privada interna no host, permitindo comunicação entre containers e com o host, mas com isolamento do mundo externo. É o padrão e é adequado para aplicações que precisam de comunicação entre containers em um único host. O driver host remove o isolamento de rede, usando diretamente a interface do host; é útil para aplicações que exigem alto desempenho de rede ou que precisam usar portas específicas do host. O driver none desativa a rede, ideal para containers que não precisam de conectividade, como tarefas de processamento offline.Como você cria uma rede personalizada chamada
app-nete inicia um containernginxconectado a ela? Escreva os comandos.✓ Resposta:docker network create app-net docker run -d --name meu-nginx --network app-net nginxQual comando você usaria para publicar a porta 8080 do host para a porta 80 de um container? Dê um exemplo completo com
docker run.✓ Resposta:docker run -d -p 8080:80 nginxExplique como você pode verificar se um container consegue se comunicar com outro na mesma rede personalizada, usando o nome do container.
✓ Resposta: Você pode executar um comando dentro do container, comoping <nome-do-container>oucurl <nome-do-container>:<porta>, desde que ambos estejam na mesma rede. Por exemplo, se os containerswebeappestão na redeapp-net, dentro deappvocê pode rodarping weboucurl http://web:80.Descreva uma estratégia de isolamento de rede para uma aplicação de três camadas (frontend, backend, banco de dados) usando redes separadas. Inclua os comandos para criar as redes e conectar os containers.
✓ Resposta: Crie duas redes:backend-netefrontend-net. O banco de dados fica apenas embackend-net. O backend fica em ambas as redes, para acessar o banco e ser acessado pelo frontend. O frontend fica apenas emfrontend-net. Comandos:
Assim, o frontend não consegue acessar o banco diretamente, aumentando a segurança.docker network create backend-net docker network create frontend-net docker run -d --name banco --network backend-net mysql docker run -d --name backend --network backend-net --network frontend-net meu-backend docker run -d --name frontend --network frontend-net meu-frontend