Fundamentos de Redes no Docker

DockerBeginner
Pratique Agora

Introdução

Neste laboratório, vamos explorar os fundamentos das redes no Docker. As redes do Docker permitem que os containers se comuniquem entre si e com o mundo externo. Abordaremos vários tipos de rede, a criação de redes personalizadas, a conexão de containers e o gerenciamento de configurações de rede. Esta experiência prática proporcionará uma base sólida sobre os conceitos e práticas de conectividade no ecossistema Docker.

Compreendendo os Tipos de Rede do Docker

O Docker fornece vários drivers de rede integrados. Vamos começar examinando as redes padrão presentes no seu sistema.

No seu terminal, execute o seguinte comando para listar todas as redes Docker disponíveis:

docker network ls

Este comando lista todas as redes que o Docker criou no seu sistema. Você deverá ver uma saída semelhante a esta:

NETWORK ID     NAME      DRIVER    SCOPE
79dce413aafd   bridge    bridge    local
91199fc6ad2e   host      host      local
1078d2c781b6   none      null      local

Vamos detalhar os tipos de rede padrão:

  1. bridge: Este é o driver de rede padrão. Quando você inicia um container sem especificar uma rede, ele se conecta automaticamente à rede bridge. Containers na mesma rede bridge podem se comunicar entre si usando seus endereços IP.

  2. host: Este driver remove o isolamento de rede entre o container e o host Docker. O container compartilha o namespace de rede do host, o que significa que ele utiliza diretamente o endereço IP e o espaço de portas do host. Isso pode ser útil para otimizar o desempenho em cenários específicos.

  3. none: Este driver desativa toda a rede para um container. Containers que utilizam este tipo de rede não terão acesso a redes externas ou a outros containers. É útil quando você deseja isolar completamente um container.

A coluna SCOPE indica se a rede está limitada a um único host (local) ou se pode abranger vários hosts em um Docker swarm (swarm).

Inspecionando a Rede Bridge Padrão

Agora que vimos a lista de redes, vamos examinar mais de perto a rede bridge padrão. Esta rede é criada automaticamente pelo Docker e é usada pelos containers, a menos que seja especificado o contrário.

Execute o seguinte comando para inspecionar a rede bridge:

docker network inspect bridge

Este comando fornece informações detalhadas sobre a rede bridge, incluindo sua sub-rede, gateway e containers conectados. Você verá uma saída semelhante a esta (truncada para fins de brevidade):

[
  {
    "Name": "bridge",
    "Id": "79dce413aafdd7934fa3c1d0cc97decb823891ce406442b7d51be6126ef06a5e",
    "Created": "2024-08-22T09:58:39.747333789+08:00",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
      "Driver": "default",
      "Options": null,
      "Config": [
        {
          "Subnet": "172.17.0.0/16",
          "Gateway": "172.17.0.1"
        }
      ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
      "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {},
    "Options": {
      "com.docker.network.bridge.default_bridge": "true",
      "com.docker.network.bridge.enable_icc": "true",
      "com.docker.network.bridge.enable_ip_masquerade": "true",
      "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
      "com.docker.network.bridge.name": "docker0",
      "com.docker.network.driver.mtu": "1500"
    },
    "Labels": {}
  }
]

Vamos analisar algumas informações importantes desta saída:

  • Subnet: A sub-rede usada pelos containers nesta rede é 172.17.0.0/16. Isso significa que os containers receberão endereços IP dentro desta faixa.
  • Gateway: O gateway para esta rede é 172.17.0.1. Este é o endereço IP que os containers usam para se comunicar com redes fora da sua própria.
  • Containers: Este campo está vazio porque ainda não iniciamos nenhum container.
  • Options: São várias opções de configuração para a rede bridge. Por exemplo, enable_icc definido como "true" significa que a comunicação entre containers (inter-container communication) é permitida nesta rede.

Entender essas informações é crucial ao solucionar problemas de rede ou quando você precisa configurar seus containers para se comunicarem com faixas de IP específicas.

Criando uma Rede Bridge Personalizada

Embora a rede bridge padrão seja adequada para muitos casos de uso, a criação de redes personalizadas permite melhor isolamento e controle. Redes personalizadas são particularmente úteis quando você deseja agrupar containers relacionados ou quando precisa controlar quais containers podem se comunicar entre si.

Vamos criar uma rede bridge personalizada chamada my-network:

docker network create --driver bridge my-network

Este comando cria uma nova rede bridge. A opção --driver bridge é opcional aqui, pois bridge é o driver padrão, mas foi incluída para maior clareza.

Agora, vamos verificar se nossa nova rede foi criada:

docker network ls

Você deve ver my-network na lista de redes:

NETWORK ID     NAME         DRIVER    SCOPE
1191cb61c989   bridge       bridge    local
91199fc6ad2e   host         host      local
47ac4e684a72   my-network   bridge    local
1078d2c781b6   none         null      local

Nossa nova rede my-network aparece na lista, confirmando que foi criada com sucesso. Esta rede está agora disponível para a conexão de containers.

Conectando Containers às Redes

Agora que temos nossa rede personalizada, vamos criar dois containers e conectá-los a ela. Usaremos a imagem nginx para este exemplo, que fornece um servidor web leve.

Execute os seguintes comandos para criar dois containers:

docker run -d --name container1 --network my-network nginx
docker run -d --name container2 --network my-network nginx

Vamos detalhar esses comandos:

  • -d: Esta flag executa o container em modo "detached", o que significa que ele roda em segundo plano.
  • --name: Atribui um nome ao nosso container, facilitando a referência posterior.
  • --network: Especifica a qual rede o container deve se conectar.
  • nginx: É o nome da imagem que estamos usando para criar nossos containers.

Esses comandos criam dois containers em segundo plano chamados container1 e container2, ambos conectados à nossa my-network.

Vamos verificar se os containers estão rodando e conectados à nossa rede:

docker ps

Este comando lista todos os containers em execução. Você deve ver ambos os containers listados na saída:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
1234567890ab   nginx     "/docker-entrypoint.…"   10 seconds ago   Up 9 seconds    80/tcp    container2
abcdef123456   nginx     "/docker-entrypoint.…"   20 seconds ago   Up 19 seconds   80/tcp    container1

Esta saída mostra que ambos os containers estão executando a imagem Nginx e expondo a porta 80 internamente.

Testando a Comunicação entre Containers

Um dos principais benefícios das redes Docker é que os containers na mesma rede podem se comunicar entre si usando seus nomes de container como hostnames. Isso facilita a configuração da comunicação entre serviços sem a necessidade de conhecer seus endereços IP.

Vamos testar isso usando o container1 para enviar uma requisição ao container2:

docker exec container1 curl -s container2

Vamos detalhar este comando:

  • docker exec: Instruiu o Docker a executar um comando dentro de um container em execução.
  • container1: É o nome do container onde queremos executar o comando.
  • curl -s container2: É o comando que estamos executando dentro do container. Ele envia uma requisição GET para o container2 e a flag -s faz o curl operar em modo silencioso.

Este comando executa o curl dentro do container1, enviando uma requisição para o container2. Você deve ver o HTML da página de boas-vindas padrão do Nginx na saída:

<!doctype html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    <style>
      html {
        color-scheme: light dark;
      }
      body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
      }
    </style>
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    <p>
      If you see this page, the nginx web server is successfully installed and
      working. Further configuration is required.
    </p>

    <p>
      For online documentation and support please refer to
      <a href="http://nginx.org/">nginx.org</a>.<br />
      Commercial support is available at
      <a href="http://nginx.com/">nginx.com</a>.
    </p>

    <p><em>Thank you for using nginx.</em></p>
  </body>
</html>

Esta resposta bem-sucedida demonstra que o container1 consegue se comunicar com o container2 usando seu nome. O servidor DNS embutido do Docker resolve o nome do container para o seu endereço IP dentro da rede.

Expondo Portas de Containers

Por padrão, containers em uma rede personalizada podem se comunicar entre si, mas não são acessíveis de fora do host Docker. Para tornar um container acessível a partir do host ou de redes externas, precisamos expor suas portas.

Vamos criar um novo container com uma porta exposta:

docker run -d --name exposed-container -p 8080:80 --network my-network nginx

Vamos detalhar este comando:

  • -d: Executa o container em modo background.
  • --name exposed-container: Nomeia o container como "exposed-container".
  • -p 8080:80: Mapeia a porta 80 interna do container para a porta 8080 no host.
  • --network my-network: Conecta o container à nossa rede personalizada.
  • nginx: Utiliza a imagem do Nginx.

Este comando cria um novo container chamado exposed-container, mapeia a porta 80 do container para a porta 8080 do host e o conecta à nossa my-network.

Agora, você pode acessar o servidor Nginx deste container a partir da sua máquina host abrindo um navegador e navegando para http://localhost:8080, ou usando o curl:

curl localhost:8080

Você verá o mesmo HTML da página de boas-vindas do Nginx de antes. Desta vez, no entanto, estamos acessando o container diretamente do host, e não de outro container.

Usando a Rede Host

Para cenários onde você deseja que um container compartilhe a pilha de rede do host, você pode usar o driver de rede host. Isso remove o isolamento de rede entre o container e o host, o que pode ser útil para certas aplicações, mas deve ser usado com cautela devido a possíveis conflitos de portas.

Vamos criar um container usando a rede host:

docker run -d --name host-networked --network host nginx

Este comando cria um novo container chamado host-networked usando a rede do host. Note que você não pode usar -p com a rede host, pois o container já está utilizando as interfaces de rede do host diretamente.

Para verificar se o container está usando a rede host, podemos inspecionar suas configurações de rede:

docker inspect --format '{{.HostConfig.NetworkMode}}' host-networked

Este comando inspeciona o container e formata a saída para mostrar apenas o NetworkMode. Ele deve retornar host, confirmando que o container está operando nesse modo.

Ao usar a rede host, o container compartilha o endereço IP do host e pode acessar todas as interfaces de rede do host diretamente. Isso pode ser útil para maximizar o desempenho, mas também significa que qualquer porta que o container use será aberta diretamente no host, o que pode levar a conflitos se você não for cuidadoso.

Resumo

Neste laboratório, exploramos os fundamentos das redes no Docker. Abordamos vários tipos de rede, a criação de redes personalizadas, a conexão de containers, o teste de comunicação entre containers, a exposição de portas e o uso da rede host. Esses conceitos formam a base da conectividade no Docker e são essenciais para projetar e gerenciar aplicações containerizadas.

Aprendemos como:

  • Listar e inspecionar redes Docker
  • Criar redes bridge personalizadas
  • Conectar containers a redes
  • Testar a comunicação entre containers
  • Expor portas de containers para o host
  • Utilizar a rede host para containers

Compreender esses conceitos de rede ajudará você a projetar aplicações containerizadas mais robustas e seguras. À medida que você continuar trabalhando com Docker, encontrará cenários de rede mais avançados, mas os princípios que cobrimos aqui servirão como uma base sólida para sua jornada em orquestração de containers e arquitetura de microsserviços.

Lembre-se de que a rede do Docker é uma ferramenta poderosa que permite criar ambientes isolados para suas aplicações, permitindo ao mesmo tempo uma comunicação controlada entre containers e com o mundo exterior. Pratique esses conceitos e explore tópicos mais avançados para se tornar proficiente no gerenciamento de redes Docker.