Como testar a conectividade entre containers Docker

DockerBeginner
Pratique Agora

Introdução

Os containers Docker tornaram-se uma parte fundamental do desenvolvimento e implantação de aplicações modernas. Ao trabalhar com múltiplos containers, garantir a conectividade adequada entre eles é crucial para que suas aplicações funcionem corretamente.

Neste laboratório, você aprenderá como verificar e solucionar problemas de conectividade entre containers Docker. Começaremos com conceitos básicos de containers Docker, configuraremos containers para testes e, em seguida, exploraremos vários métodos para verificar e diagnosticar as conexões de rede entre os containers.

Ao final deste tutorial, você será capaz de testar, verificar e resolver com confiança problemas de conectividade em suas aplicações em containers.

Este Lab requer uma conexão com a internet para aprendizado, portanto, apenas usuários Pro podem iniciar a VM. Atualize sua conta para Pro.

Configurando Containers Docker para Testes

Antes de podermos testar a conectividade entre containers, precisamos criar alguns containers para trabalhar. Nesta etapa, configuraremos dois containers Docker simples e aprenderemos sobre comandos Docker básicos.

Entendendo Containers Docker

Containers Docker são pacotes leves e autônomos que incluem tudo o que é necessário para executar uma aplicação: código, runtime, ferramentas do sistema, bibliotecas e configurações. Os containers compartilham o kernel do sistema operacional (SO) da máquina host, mas são executados em ambientes isolados.

Criando Containers de Teste

Vamos começar criando dois containers simples baseados na imagem Ubuntu. Usaremos esses containers ao longo do laboratório para testar a conectividade entre eles.

Primeiro, vamos criar nosso primeiro container:

docker run -d --name container1 ubuntu:22.04 sleep infinity

Agora, vamos criar o segundo container:

docker run -d --name container2 ubuntu:22.04 sleep infinity
run containers

Os parâmetros do comando explicados:

  • -d: Executa o container em modo detached (em segundo plano)
  • --name: Atribui um nome ao container
  • ubuntu:22.04: A imagem Docker a ser usada (versão Ubuntu 22.04)
  • sleep infinity: Um comando que mantém o container em execução indefinidamente

Verificando se Nossos Containers Estão Rodando

Para verificar se nossos containers estão rodando corretamente, use o seguinte comando:

docker ps

Você deve ver uma saída semelhante a esta:

CONTAINER ID   IMAGE          COMMAND            CREATED         STATUS         PORTS     NAMES
f8d97c645cce   ubuntu:22.04   "sleep infinity"   5 seconds ago   Up 4 seconds             container2
a2c516a57cb8   ubuntu:22.04   "sleep infinity"   18 seconds ago  Up 17 seconds            container1

Se você não vir ambos os containers listados, eles podem não ter iniciado corretamente. Você pode tentar criá-los novamente.

Instalando Ferramentas de Rede

Por padrão, a imagem do container Ubuntu é muito minimalista e não inclui as ferramentas de rede de que precisaremos. Vamos instalar essas ferramentas em ambos os containers:

Para container1:

docker exec container1 apt-get update
docker exec container1 apt-get install -y iputils-ping net-tools iproute2 curl

Para container2:

docker exec container2 apt-get update
docker exec container2 apt-get install -y iputils-ping net-tools iproute2 curl

Esses comandos:

  1. Usam docker exec para executar comandos dentro de um container em execução
  2. Atualizam a lista de pacotes com apt-get update
  3. Instalam ferramentas de rede (iputils-ping para ping, net-tools para netstat, iproute2 para comandos ip e curl)

Agora, nossos containers estão prontos para testes de conectividade nas próximas etapas.

Entendendo as Redes Docker

Os containers Docker se comunicam entre si através de redes. Entender como o networking Docker funciona é essencial para testar e solucionar problemas de conectividade entre containers.

Noções Básicas de Rede Docker

Ao instalar o Docker, ele cria automaticamente várias redes padrão. As mais comumente usadas são:

  • bridge: A rede padrão à qual os containers se conectam se nenhuma rede for especificada
  • host: Os containers usam a rede do host diretamente (sem isolamento)
  • none: Os containers não têm acesso à rede

Vamos examinar as redes em seu sistema:

docker network ls

Você deve ver uma saída semelhante a:

NETWORK ID     NAME      DRIVER    SCOPE
1b95853bf83b   bridge    bridge    local
91199fc6ad2e   host      host      local
1078d2c781b6   none      null      local

Entendendo a Rede Bridge Padrão

Por padrão, ambos os nossos containers estão conectados à rede bridge padrão. Vamos examinar esta rede:

docker network inspect bridge

Este comando exibe informações detalhadas sobre a rede bridge, incluindo os containers conectados a ela e seus endereços IP. Na saída, procure a seção "Containers" para ver container1 e container2 listados com seus endereços IP.

Encontrando Endereços IP dos Containers

Para trabalhar com a conectividade do container, precisamos saber os endereços IP atribuídos aos nossos containers. Existem várias maneiras de encontrar essa informação:

Usando docker inspect:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container1

Ou de dentro do container:

docker exec container1 hostname -i

Anote os endereços IP para ambos os containers:

docker exec container1 hostname -i
docker exec container2 hostname -i

A saída mostrará o endereço IP para cada container, que normalmente começa com 172.17.0.x na rede bridge padrão.

Criando uma Rede Docker Personalizada

Embora a rede bridge padrão permita a comunicação entre containers, a criação de uma rede personalizada oferece melhor isolamento e resolução DNS integrada (os containers podem se comunicar por nome em vez de IP).

Vamos criar uma rede bridge personalizada:

docker network create --driver bridge my-network

Agora, vamos conectar nossos containers existentes a esta nova rede:

docker network connect my-network container1
docker network connect my-network container2

Podemos verificar se nossos containers estão conectados à nova rede:

docker network inspect my-network

Agora, nossos containers estão conectados tanto à rede bridge padrão quanto à nossa my-network personalizada. Na próxima etapa, testaremos a conectividade entre eles.

Testando a Conectividade Básica entre Containers

Agora que configuramos nossos containers e os conectamos às redes, podemos testar a conectividade entre eles. Usaremos vários métodos para verificar se os containers podem se comunicar entre si.

Usando Ping para Testar a Conectividade

A maneira mais simples de testar a conectividade básica de rede é usando o comando ping, que envia solicitações de eco ICMP para o host de destino.

Vamos fazer ping do container1 para o container2 usando o endereço IP:

## Primeiro, obtenha o endereço IP do container2
CONTAINER2_IP=$(docker exec container2 hostname -i)
echo "Container2 IP: $CONTAINER2_IP"

## Obtenha o primeiro endereço IP do CONTAINER2_IP
CONTAINER2_IP=$(echo $CONTAINER2_IP | cut -d' ' -f1)
echo "Container2 IP: $CONTAINER2_IP"

## Agora faça ping do container1 para o container2
docker exec container1 ping -c 4 $CONTAINER2_IP

Você deve ver uma saída semelhante a:

PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.095 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.067 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.090 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.087 ms
--- 172.17.0.3 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.067/0.085/0.095/0.000 ms

Testando a Resolução DNS

Uma vantagem das redes Docker personalizadas é que elas fornecem resolução DNS automática, permitindo que os containers se comuniquem por nome.

Vamos testar a resolução DNS fazendo ping no container por nome:

docker exec container1 ping -c 4 container2

Isso deve funcionar porque ambos os containers estão em nossa my-network personalizada, que fornece resolução DNS. Você deve ver respostas de ping semelhantes ao teste anterior, mas usando o nome do container em vez do IP.

Usando curl para Testar a Conectividade HTTP

Para aplicações que executam serviços web, muitas vezes precisamos testar a conectividade HTTP. Vamos configurar um servidor HTTP simples no container2 e testar a conectividade com ele a partir do container1.

Primeiro, vamos iniciar um servidor HTTP básico no container2:

docker exec container2 apt-get install -y python3
docker exec -d container2 bash -c "echo 'Hello from container2' > /index.html && cd / && python3 -m http.server 8080"

Aguarde alguns segundos para o servidor iniciar e, em seguida, teste a conexão do container1:

docker exec container1 curl -s http://container2:8080

Você deve ver a saída:

Hello from container2

Isso confirma que o container1 pode se conectar ao serviço HTTP do container2 usando o nome do container para resolução DNS.

Testando a Conexão com Diferentes Métodos

Também é útil saber como testar a conectividade usando outras ferramentas. Vamos tentar usar nc (netcat) para verificar se uma porta específica está aberta:

## Certifique-se de que o netcat está instalado no container1
docker exec container1 apt-get install -y netcat

## Teste a conectividade com o servidor HTTP no container2
docker exec container1 nc -zv container2 8080

Você deve ver uma saída indicando que a conexão foi bem-sucedida:

Connection to container2 (172.18.0.3) 8080 port [tcp/*] succeeded!

Esses testes confirmam que nossos containers podem se comunicar entre si tanto no nível da rede (ping) quanto no nível da aplicação (HTTP).

Solucionando Problemas de Conectividade de Containers

Você pode pular esta etapa se não tiver problemas de conectividade.

Agora que entendemos como testar a conectividade entre containers, vamos explorar como solucionar problemas comuns de conectividade.

Problemas Comuns de Conectividade

Ao lidar com redes de containers Docker, você pode encontrar vários problemas comuns:

  1. Containers em redes diferentes sem o roteamento adequado
  2. Configurações de firewall ou grupo de segurança bloqueando o tráfego
  3. Aplicação não escutando no IP/porta esperados
  4. Erros de configuração de rede
  5. Problemas de resolução DNS

Vamos percorrer as etapas de solução de problemas para cada um desses possíveis problemas.

Verificando a Configuração da Rede

Primeiro, vamos examinar a configuração de rede de nossos containers:

## Visualize as interfaces de rede do container1
docker exec container1 ip addr show

## Visualize as interfaces de rede do container2
docker exec container2 ip addr show

A saída mostra todas as interfaces de rede em cada container. Cada rede Docker conectada aparece como uma interface eth com seu endereço IP atribuído.

Verificando as Rotas de Rede

Vamos verificar a configuração de roteamento em nossos containers:

docker exec container1 route -n

Isso mostra a tabela de roteamento para o container1, indicando para onde o tráfego de rede é direcionado.

Verificando as Portas de Escuta

Para determinar se uma aplicação está escutando corretamente as conexões, use:

docker exec container2 netstat -tuln

Isso mostra todas as portas TCP e UDP em escuta. Nosso servidor HTTP deve estar escutando na porta 8080.

Diagnosticando com tcpdump

Para uma análise de tráfego de rede mais detalhada, podemos usar tcpdump para capturar e analisar pacotes:

## Instale o tcpdump no container1
docker exec container1 apt-get install -y tcpdump dnsutils

## Capture pacotes por 10 segundos
docker exec container1 timeout 10 tcpdump -i eth0 -n

Enquanto isso estiver em execução, abra outro terminal e gere algum tráfego:

docker exec container1 ping -c 3 container2

Você deve ver os pacotes ICMP sendo capturados na saída do tcpdump.

Verificando a Resolução DNS do Docker

Se você estiver com problemas de resolução DNS entre containers:

## Verifique a configuração DNS
docker exec container1 cat /etc/resolv.conf

## Teste a resolução DNS
docker exec container1 nslookup container2

Simulando um Problema de Rede

Vamos simular um problema de conectividade desconectando temporariamente o container1 de nossa rede personalizada:

## Desconecte o container1 de my-network
docker network disconnect my-network container1

## Tente fazer ping por nome (isso deve falhar)
docker exec container1 ping -c 2 container2

Você deve ver que o ping falha porque o container1 não consegue mais resolver o container2 por nome após ser desconectado da rede compartilhada.

Vamos reconectá-lo:

## Reconecte o container1 a my-network
docker network connect my-network container1

## Verifique se a conectividade foi restaurada
docker exec container1 ping -c 2 container2

Agora o ping deve funcionar novamente, demonstrando como os containers devem estar na mesma rede para que a resolução de nomes funcione.

Lista de Verificação de Solução de Problemas

Ao enfrentar problemas de conectividade de containers, siga esta lista de verificação:

  1. Verifique se os containers estão em execução: docker ps
  2. Verifique se eles estão na mesma rede: docker network inspect <network>
  3. Verifique se os endereços IP estão atribuídos: docker inspect <container>
  4. Teste a conectividade básica (ping): docker exec <container> ping <target>
  5. Verifique se a aplicação está escutando: docker exec <container> netstat -tuln
  6. Verifique se a resolução DNS está funcionando: docker exec <container> nslookup <target>
  7. Procure problemas de firewall: docker exec <container> iptables -L
  8. Verifique os logs do container: docker logs <container>

Usar essa abordagem sistemática ajudará você a identificar e resolver a maioria dos problemas de conectividade de containers.

Resumo

Neste laboratório, você aprendeu como testar e solucionar problemas de conectividade entre containers Docker. Você:

  • Criou containers Docker e os configurou para rede
  • Aprendeu sobre os fundamentos de rede do Docker, incluindo redes padrão e personalizadas
  • Usou várias ferramentas para testar a conectividade básica entre containers (ping, curl, netcat)
  • Explorou problemas comuns de conectividade e aprendeu abordagens sistemáticas de solução de problemas

Essas habilidades são essenciais para desenvolver e manter aplicações baseadas em Docker, especialmente em arquiteturas de microsserviços, onde vários containers precisam se comunicar entre si.

Para aprendizado adicional, você pode explorar o Docker Compose para aplicações multi-container, Docker Swarm ou Kubernetes para orquestração de containers e conceitos de rede mais avançados, como redes de sobreposição (overlay networks) para implantações multi-host.