Gerenciando Redes no Docker
Um tutorial passo a passo para gerenciar redes Docker, incluindo a criação e remoção de redes, mapeamento de portas, gerenciamento de links entre contêineres, e configuração de DNS.
====== Sumário ======
- Introdução
- Gerenciar Portas
- Gerenciar Links
- Gerenciar DNS
- Rede Bridge
- Rede Host
- Comandos de Gerenciamento de Redes no Docker
- Remover Redes
- Conclusão
Introdução
O Docker simplificou o processo de criação, implantação e gerenciamento de contêineres, oferecendo aos desenvolvedores e administradores de sistemas um ambiente portátil e consistente para executar aplicações. No entanto, a verdadeira força do Docker não está apenas na execução de contêineres isolados, mas também na sua capacidade de configurar redes robustas e flexíveis que permitem a comunicação entre contêineres, serviços e o mundo externo.
Este tutorial detalha os aspectos essenciais do gerenciamento de redes no Docker, incluindo como criar e personalizar redes, mapear portas, gerenciar links entre contêineres e configurar servidores DNS. Através de exemplos práticos, você aprenderá a usar as redes padrão do Docker, como bridge e host, e também a criar redes personalizadas com controle sobre sub-redes e endereçamento IP.
Gerenciando Redes no Docker
Gerenciar portas
Lista de redes disponíveis no Docker:
1
docker network ls
docker network ls: Este comando lista todas as redes disponíveis no Docker. No exemplo, temos três redes padrões:- bridge: Rede padrão do Docker, onde os contêineres podem se comunicar entre si, mas com regras de firewall configuradas para o tráfego externo.
- host: Nesta rede, os contêineres compartilham a interface de rede do host diretamente.
- none: Usada para desabilitar completamente a rede de um contêiner.
Mapeando a porta 80 do contêiner no host local:
1
docker container run -d --name web --network bridge -p 80:80 nginx
docker container run -d --name web --network bridge -p 80:80 nginx: Este comando cria e executa um contêiner em segundo plano (-d) chamado web, utilizando a redebridgee mapeando a porta 80 do host para a porta 80 do contêiner.-p 80:80: Mapeia a porta 80 do host para a porta 80 dentro do contêiner, permitindo acesso externo ao serviço rodando no contêiner (no caso, o nginx).
Verificando o mapeamento de portas do contêiner:
1
docker container port web
docker container port web: Exibe o mapeamento de portas do contêiner chamado web. No exemplo, mostra que a porta 80 está mapeada para 0.0.0.0:80 e [::]:80, indicando que a porta está exposta tanto em IPv4 quanto em IPv6.
Lista de contêineres em execução:
1
docker ps
docker ps: Lista todos os contêineres que estão atualmente em execução, mostrando o ID do contêiner, a imagem usada, o tempo de execução, e as portas mapeadas.
Executando uma requisição HTTP ao Nginx:
1
curl 127.0.0.1
curl 127.0.0.1: Faz uma requisição HTTP ao endereço 127.0.0.1 (localhost) para testar o serviço Nginx rodando no contêiner, que foi mapeado para a porta 80 no host.
Removendo o contêiner:
1
docker container rm -f web
docker container rm -f web: Força a remoção do contêiner web, encerrando-o e liberando os recursos associados.
Mapeando uma porta de forma aleatória
Executando um contêiner com porta mapeada aleatoriamente:
1
docker container run -d --name web -P nginx
docker container run -d --name web -P nginx: Este comando cria um contêiner chamado web utilizando a imagem nginx e mapeia todas as portas expostas do contêiner para portas aleatórias no host. O-P(maiúsculo) mapeia as portas internas para portas livres no host, enquanto o-p(minúsculo) mapeia portas específicas.
Verificando o mapeamento de portas aleatórias:
1
docker container port web
docker container port web: Mostra que a porta 80 do contêiner foi mapeada para uma porta aleatória no host, neste caso, 32768.
Testando o mapeamento de porta aleatória:
1
curl 127.0.0.1:32768
curl 127.0.0.1:32768: Faz uma requisição HTTP à porta aleatória (32768) no host, que foi mapeada para a porta 80 do contêiner Nginx. O comando deve retornar a página padrão do Nginx.
Removendo o contêiner:
1
docker container rm -f web
docker container rm -f web: Força a remoção do contêiner web, encerrando o serviço Nginx e liberando a porta aleatória no host.
Gerenciar links
Executando um contêiner chamado “server”:
1
docker container run -di --name=server -h server busybox
docker container run -di --name=server -h server busybox: Este comando cria e executa um contêiner em segundo plano com o nome server, usando a imagem busybox. A flag-hdefine o hostname do contêiner como server.
Executando um contêiner “client” com link para o contêiner “server”:
1
docker container run --detach --interactive --name=client --link server:server --hostname client busybox
docker container run --detach --interactive --name=client --link server:server --hostname client busybox: Este comando cria o contêiner client e faz um link para o contêiner server. O parâmetro--link server:servercria uma entrada no arquivo/etc/hostsdo contêiner client, permitindo que ele se conecte ao contêiner server usando o hostname server.--link: Permite que um contêiner se comunique com outro através de seu hostname, útil para facilitar a conexão entre contêineres.
Verificando o arquivo /etc/hosts no contêiner “client”:
1
docker container exec --interactive --tty client cat /etc/hosts
docker container exec --interactive --tty client cat /etc/hosts: Verifica o arquivo /etc/hosts no contêiner client, onde o Docker automaticamente insere o hostname e IP do contêiner server, permitindo a comunicação entre eles.
Teste de conectividade entre “client” e “server”:
1
docker container exec --interactive --tty client ping -c3 server
docker container exec --interactive --tty client ping -c3 server: O comando ping testa a conectividade entre o contêiner client e o contêiner server usando o hostname server. Como o link foi criado corretamente, o ping retorna com sucesso.
Verificando o arquivo /etc/hosts no contêiner “server”:
1
docker container exec -it server cat /etc/hosts
docker container exec -it server cat /etc/hosts: No contêiner server, o arquivo /etc/hosts não tem a entrada para o contêiner client, pois o link é unidirecional (somente client tem acesso ao server).
Removendo os contêineres:
1
docker container rm -f server client
docker container rm -f server client: Remove os contêineres server e client, encerrando o teste de comunicação entre eles.
Gerenciar DNS
Executando um contêiner com um servidor DNS público especificado:
1
docker container run --interactive --detach --name=server --hostname server --dns=1.1.1.1 busybox
docker container run --interactive --detach --name=server --hostname server --dns=1.1.1.1 busybox: Este comando cria um contêiner chamado server e define o hostname como server. A flag--dns=1.1.1.1especifica que o contêiner deve usar o servidor DNS 1.1.1.1 (da Cloudflare) para resolver nomes de domínio.--dns: Permite especificar um servidor DNS personalizado para o contêiner, substituindo o servidor DNS padrão do host Docker.
Verificando o arquivo /etc/resolv.conf dentro do contêiner:
1
docker container exec -it server cat /etc/resolv.conf
docker container exec -it server cat /etc/resolv.conf: Exibe o conteúdo do arquivo /etc/resolv.conf dentro do contêiner server, onde o Docker configurou o servidor DNS 1.1.1.1. Este arquivo controla como o contêiner resolve nomes de domínio.
Teste de resolução de DNS com o comando nslookup:
1
docker container exec -it server nslookup -querytype=A geanmartins.com.br
docker container exec -it server nslookup -querytype=A geanmartins.com.br: O comando nslookup consulta o servidor DNS especificado no contêiner (1.1.1.1) para obter o endereço IP do domínio geanmartins.com.br. O tipo de consulta especificado (-querytype=A) retorna o registro A (IPv4) do domínio.
Removendo o contêiner:
1
docker rm -f server
docker rm -f server: Remove o contêiner server, encerrando seu processo e liberando os recursos associados.
Configuração persistente de DNS no Docker
Editando o arquivo daemon.json para definir o DNS padrão do Docker:
1
2
3
4
5
cat /etc/docker/daemon.json
{
"log-driver": "syslog",
"dns": ["1.1.1.1"]
}
/etc/docker/daemon.json: Este arquivo de configuração controla as opções padrão do Docker daemon. Neste exemplo, a chave"dns": ["1.1.1.1"]define o DNS padrão para 1.1.1.1 para todos os contêineres que não especificarem manualmente um DNS.log-driver: Configura o driver de logs para syslog, enviando logs para o serviço de registro de sistema do Linux.dns: Define o servidor DNS padrão que será aplicado a todos os contêineres.
Reiniciando o Docker para aplicar as alterações:
1
sudo systemctl restart docker
sudo systemctl restart docker: Reinicia o serviço Docker, aplicando as alterações feitas no arquivodaemon.json. A partir de agora, qualquer contêiner criado sem especificar um DNS usará 1.1.1.1 como servidor DNS.
Executando um novo contêiner sem especificar um servidor DNS:
1
docker exec -ti server nslookup -querytype=A geanmartins.com.br
- Mesmo sem especificar o DNS ao criar o contêiner, o comando nslookup usa o DNS 1.1.1.1 configurado no
daemon.jsonpara resolver o domínio.
Rede Bridge
Executando um contêiner utilizando a rede bridge e mapeando a porta 80:
1
docker container run -d --name web --network bridge -p 80:80 nginx
docker container run -d --name web --network bridge -p 80:80 nginx: Este comando cria um contêiner chamado web que usa a rede bridge (a rede padrão no Docker). O parâmetro-p 80:80mapeia a porta 80 do contêiner para a porta 80 do host, permitindo que o Nginx dentro do contêiner seja acessado via localhost:80.- Rede Bridge: A rede bridge isola os contêineres entre si, mas permite que eles se comuniquem através de NAT (Network Address Translation) configurado pelo Docker. Essa é a rede padrão para contêineres.
Verificando se a porta 80 está sendo escutada no host:
1
sudo ss -nltp | grep 80
ss -nltp | grep 80: O comando ss mostra as portas que estão sendo escutadas no sistema. Aqui, ele verifica se a porta 80 está aberta e sendo usada pelo contêiner nginx através do proxy do Docker (docker-proxy).
Verificando a regra de firewall (iptables) gerada pelo Docker:
1
sudo iptables -nL --line-number | grep 80 -B2
iptables -nL --line-number | grep 80: Este comando mostra as regras de firewall (iptables) geradas automaticamente pelo Docker. No exemplo, a regra permite que o tráfego para a porta 80 no host seja redirecionado para o contêiner nginx.
Removendo o contêiner:
1
docker rm -f web
docker rm -f web: Força a remoção do contêiner web, liberando a porta 80 no host e removendo as regras de redirecionamento configuradas pelo Docker.
Rede Host
Executando um contêiner utilizando a rede host:
1
docker container run -d --name server --net=host nginx
docker container run -d --name server --net=host nginx: Este comando cria um contêiner chamado server que usa a rede host. Na rede host, o contêiner compartilha diretamente a interface de rede do host, sem isolamento de rede. Isso significa que o Nginx dentro do contêiner estará diretamente acessível pelas portas do host, sem a necessidade de mapeamento de portas.- Rede Host: Permite que o contêiner use a pilha de rede do host diretamente, o que pode ser útil em casos onde o desempenho de rede é crítico ou quando o contêiner precisa acessar diretamente interfaces de rede do host.
Verificando se a porta 80 está sendo escutada no host:
1
sudo ss -nltp | grep 80
ss -nltp | grep 80: Como o contêiner está usando a rede host, o processo nginx está diretamente escutando na porta 80 do host, sem precisar de mapeamento de portas via docker-proxy.
Verificando a ausência de mapeamento de portas no contêiner:
1
docker container port server
docker container port server: Como o contêiner está na rede host, este comando não retorna nenhuma porta mapeada, uma vez que o contêiner está diretamente utilizando a porta do host sem NAT ou redirecionamento.
Removendo o contêiner:
1
docker container rm -f server
docker container rm -f server: Remove o contêiner server, encerrando o processo nginx que estava rodando diretamente na interface de rede do host.
Comandos de gerenciamento de redes no Docker
Utilizar Rede Padrão
Opções do comando docker network:
1
docker network --help
docker network --help: Exibe a lista de comandos disponíveis para gerenciamento de redes no Docker. Comandos comoconnect,create,disconnect,inspect,ls,pruneermsão usados para criar, conectar, inspecionar e remover redes.
Listando redes existentes:
1
docker network ls
docker network ls: Lista todas as redes no Docker. Cada rede tem um ID, nome, driver (por exemplo, bridge, host) e o escopo, que geralmente é local.
Inspecionando uma rede em detalhes:
1
docker network inspect bridge
docker network inspect bridge: Exibe informações detalhadas sobre a rede bridge, como seu ID, a sub-rede configurada, o gateway, e os contêineres conectados a essa rede. Esse comando é útil para depurar problemas de rede e visualizar como o Docker gerencia o isolamento entre contêineres.
Criar Redes Personalizadas
Criando uma nova rede personalizada:
1
docker network create --driver bridge --subnet 172.32.0.0/16 dca
docker network create --driver bridge --subnet 172.32.0.0/16 dca: Este comando cria uma nova rede chamada dca com o driver bridge e atribui a sub-rede 172.32.0.0/16. O Docker permite a criação de redes personalizadas para separar ambientes de contêineres ou para fornecer controle mais granular sobre as redes.--driver bridge: Especifica que a rede deve usar o driver bridge.--subnet 172.32.0.0/16: Define o range de IPs da sub-rede que os contêineres dessa rede vão utilizar.
Listando as redes após a criação:
1
docker network ls
docker network ls: Mostra a nova rede dca criada, além das redes padrão do Docker (bridge, host, none).
Inspecionando a rede personalizada:
1
docker network inspect dca
docker network inspect dca: Exibe informações detalhadas sobre a rede dca, incluindo a sub-rede configurada, o gateway, e os contêineres conectados a ela. Essa visão detalhada ajuda a entender como a rede está configurada e se está funcionando conforme o esperado.
Utilizando IP Fixo
Criando um contêiner com IP fixo em uma rede personalizada:
1
docker container run -di --name=c1 -h server --network dca --ip 172.32.0.100 --add-host=client:172.32.0.113 busybox
docker container run -di --name=c1 -h server --network dca --ip 172.32.0.100 --add-host=client:172.32.0.113 busybox: Cria o contêiner c1 com um IP fixo 172.32.0.100 na rede personalizada dca. O parâmetro--add-host=client:172.32.0.113adiciona uma entrada no arquivo/etc/hostsdo contêiner, associando o hostname client ao IP 172.32.0.113, facilitando a comunicação.--ip: Define um IP fixo para o contêiner dentro da rede especificada.
Teste de conectividade entre contêineres:
1
docker container exec -it c1 ping -c2 client
docker container exec -it c1 ping -c2 client: O contêiner c1 realiza um teste de conectividade (ping) para o hostname client (resolvendo o IP 172.32.0.113), demonstrando que a rede personalizada está funcionando corretamente com a atribuição de IPs fixos.
Conectar e Desconectar Contêineres
Desconectando um contêiner de uma rede:
1
docker network disconnect dca c2
docker network disconnect dca c2: Desconecta o contêiner c2 da rede dca, removendo sua associação com essa rede. Isso pode ser útil se o contêiner não precisar mais se comunicar com outros contêineres naquela rede.
Verificando a perda de conectividade:
1
docker container exec -ti c1 ping -c2 client
- Após a desconexão, o comando ping no contêiner c1 falha ao tentar se conectar ao contêiner client, confirmando que c2 foi corretamente desconectado da rede.
Reconectando o contêiner à rede com um IP fixo:
1
docker network connect --ip 172.32.0.113 dca c2
docker network connect --ip 172.32.0.113 dca c2: Reconecta o contêiner c2 à rede dca com o mesmo IP 172.32.0.113, restaurando a conectividade.
Remover Rede
Verificando a conectividade antes da remoção:
1
docker container exec -ti c1 ping -c2 client
docker container exec -ti c1 ping -c2 client: Antes de remover a rede, este comando verifica a conectividade entre os contêineres c1 e c2 na rede dca. O ping deve retornar pacotes recebidos corretamente, confirmando que ambos os contêineres ainda estão conectados à rede.
Removendo os contêineres conectados à rede:
1
docker container rm -f c1 c2
docker container rm -f c1 c2: Força a remoção dos contêineres c1 e c2, liberando os IPs e desconectando-os da rede. O Docker não permite remover uma rede se ainda houver contêineres conectados a ela, por isso os contêineres devem ser removidos primeiro.
Removendo a rede personalizada:
1
docker network rm dca
docker network rm dca: Remove a rede personalizada dca do Docker. Após este comando, a rede dca não estará mais disponível para novos contêineres.
Listando redes restantes:
1
docker network ls
docker network ls: Lista as redes restantes no Docker, que agora devem ser apenas as redes padrão (bridge, host, e none) após a remoção da rede dca.
Removendo redes que não estão em uso
Removendo todas as redes não utilizadas:
1
docker network prune
docker network prune: Remove todas as redes personalizadas que não estão em uso por nenhum contêiner. Esta é uma maneira rápida de limpar redes antigas ou redes não utilizadas, liberando recursos.- Alerta: Este comando remove todas as redes não usadas, portanto deve ser utilizado com cautela em ambientes onde algumas redes são necessárias, mas não possuem contêineres ativos no momento.
Conclusão
O gerenciamento de redes no Docker é um aspecto crucial para quem deseja operar contêineres em ambientes produtivos, simulando redes internas complexas ou expostas para o público. Neste tutorial, abordamos desde a criação de redes básicas com drivers padrão, como bridge e host, até a configuração de redes personalizadas com IPs fixos e sub-redes específicas.
Além disso, você aprendeu a testar a conectividade entre contêineres, utilizar mapeamento de portas, e configurar DNS personalizados para contêineres. Essas práticas são fundamentais para garantir que suas aplicações sejam escaláveis, seguras e funcionais em diferentes ambientes de desenvolvimento e produção.
Com o conhecimento adquirido, você agora tem as ferramentas necessárias para controlar como os contêineres se comunicam, como eles interagem com o host e com o mundo externo, e como manter sua infraestrutura Docker organizada e eficiente.