códigos

O docker é disponibilizado com três redes por padrão. Essas redes oferecem configurações específicas para gerenciamento do tráfego de dados. Para visualizar essas interfaces, basta utilizar o comando: docker network ls

O retorno será:

Bridge

Cada container iniciado no docker é associado a uma rede específica. Essa é a rede padrão para qualquer container, a menos que associemos, explicitamente, outra rede a ele. Todos os containers que estão nessa rede poderão se comunicar via protocolo TCP/IP. Se você souber qual endereço IP do container deseja conectar, é possível enviar tráfego para ele. Todos estão na mesma rede IP (172.17.0.0/16).

Na versão 1.9 do Docker é possível criar basicamente dois tipos de rede: Bridge (forma tradicional, e acessível apenas de dentro do host), ou do tipo Overlay (que possibilita a comunicação entre outros hosts com Docker, possibilitando assim a criação de cluster de Docker).

Como os IPs são automaticamente cedidos, o docker facilmente consegue localizar o container de destino através da opção -link. Ela é responsável por associar o IP do container de destino ao seu nome. Caso inicie um container a partir de uma imagem docker do mysql com nome "bd", inicie outro em seguida com o nome "app" a partir da imagem tutum/apache-php. Se desejar que esse último container consiga conectar-se no mysql usando o nome "bd", inicie ambos os containers da seguinte forma:


  docker container run -d --name bd -e MYSQL_ROOT_PASSWORD=minhasenha mysql
  docker container run -d -p 80:80 --name app --link db tutum/apache-php


Após executá-los, o container "app" poderá se conectar ao container do mysql usando o nome "bd", sendo automaticamente resolvido para o IP da rede 172.17.0.0/16.
A fim de testes, utilize a funcionalidade exec para rodar o comando dentro de um container já existente, use o nome do container como parâmetro do comando abaixo:


  docker container exec -it app ping db


Essa ação é responsável por executar o comando "ping db" dentro do container "app", o qual enviará pacotes icmp, normalmente usado para testar conectividade entre hosts, para o endereço "db". O nome "db" será traduzido para o IP que o container iniciado a partir da imagem o mysql obteve.
Os containers configurados para essa rede terão a possibilidade de tráfego externo utilizando as rotas das redes IP definidas no docker host. Caso o docker host tenha acesso a internet, automaticamente, os containers em questão também terão. Nessa rede é possível expor portas dos containers para todos os ativos com acesso ao docker host.


Redes quando definidas pelo usuário

O docker possibilita que o usuário crie redes. Essas redes são associadas ao elemento que o docker chama de driver de rede. Cada rede criada por usuário deve estar associada a um determinado driver. E, caso você não crie seu próprio driver, deve escolher entre os drivers disponibilizados pelo docker:


Bridge

É o driver de rede mais simples de usar, demanda pouca configuração e a rede assemelha-se à rede padrão docker "bridge". As redes criadas pelo usuário com o driver bridge tem todas as funcionalidades descritas na rede padrão, chamada bridge. Porém, com funcionalidades adicionais. Dentre uma das funcionalidades: a rede criada pelo usuário não precisa mais utilizar a opção antiga “–link”. Pois, toda rede criada pelo usuário com o driver bridge poderá utilizar o DNS interno do Docker que, associa, automaticamente, todos os nomes de containers dessa rede para seus respectivos IPs da rede IP correspondente.
Todos os containers que estiverem utilizando a rede padrão bridge não poderão usufruir da funcionalidade de DNS interno do Docker. Caso utilize essa rede, é preciso especificar a opção legada “–link” para tradução dos nomes em endereços IPs dinamicamente alocados no docker.

Para exemplificar a utilização de rede criada por usuário, crie a rede chamada isolated_nw com o driver bridge:


  docker network create --driver bridge isolated_nw


Agora, verifique a rede:


  docker network list/p>

O resultado deve ser:

Agora, inicie um container na rede isolated_nw:


  docker container run -itd --net isolated_nw alpine sh


Lembrando que: um container que está em determinada rede não acessa outro container que está em outra rede. Mesmo que você conheça o IP de destino. Para que um container acesse outro container de outra rede, é necessário que a origem esteja presente nas duas redes que deseja alcançar. Os containers que estão na rede isolated_nw podem expor suas portas no docker host e essas portas podem ser acessadas tanto por containers externos a rede, chamada isolated_nw, como máquinas externas com acesso ao docker host.

Para descobrir quais containers estão associados a uma determinada rede, execute o comando abaixo:


  docker network inspect isolated_nw


O resultado deve ser:

Dentro de "Containers" verifica-se quais containers fazem parte dessa rede. Todos os containers que estiverem na mesma rede poderão se comunicar através de seus respectivos nomes. Como visto acima, caso um container novo acesse a rede isolated_nw, ele poderá acessar o container amazing_noyce usando apenas o seu nome.


Utilizando redes no docker composer

Por padrão, o Compose já cria uma única rede para o seu aplicativo. Cada container entra na rede padrão e é tanto alcançável para os outros containers nessa mesma rede, quanto detectável por eles com um hostname idêntico ao nome do container. O nome da rede é dado baseado no "nome do projeto", que é baseado no nome do diretório em que está inserido. É possível dar override no nome do projeto com a flag --project-name ou a variável COMPOSE_PROJECT_NAME.

Digamos que o seu aplicativo esteja em um diretório chamado meuapp, e o seu docker-compose.yml esteja parecido com isso:


  services:
   web:
      build: .
      ports:
         - "8000:8000"
   db:
      image: postgres
      ports:
         - "8001:5432"

Quando você roda docker compose up, acontece o seguinte:

1.   Uma rede chamada meuapp_default é criada.
2.   Um container é criado usando a configuração de web. Ele entra na rede meuapp_default com o nome web.
3.   Um container é criado usando a configuração de db. Ele entra na rede meuapp_default com o nome db.

Cada container pode, agora, pesquisar o hostname web ou db e retornar o endereço IP do respectivo container. Por exemplo, o código de aplicação de web pode conectar à URL postgres://db:5432 e começar a usar o banco dados Postgres.
É importante notar a diferença entre HOST_PORT e CONTAINER_PORT. No exemplo acima, para db, HOST_PORT é 8001 e a port do container é 5432 (padrão postgres). A comunicação entre serviços de rede usa CONTAINER_PORT. Quando HOST_PORT é definida, o serviço é acessível externamente também.


Vincular containers

Vínculos permitem definir apelidos extras pelos quais um serviço é alcançável por outro. Eles não são necessários para habilitar a comunicação de serviços. Por padrão, qualquer serviço pode alcançar outro com aquele nome do serviço. Por exemplo, db é alcançável por web nos hostnames db e database:


  services:

   web:
      build: .
      links:
         - "db:database"
   db:
      image: postgres


Redes com múltiplos hosts

Quando estamos usando uma aplicação Compose em uma engine Docker com o modo Swarm (recurso para gerenciar um cluster de Docker daemons) habilitado, é possível usar o driver overlay já incluído para habilitar a comunicação entre múltiplos hosts.
Redes overlay sempre são criadas como attachable, ou seja, que é possível separar um container privilegiado e ainda continuar a comunicação. É possível, opcionalmente, colocar a propriedade attachable como falsa.


Especificar redes personalizadas

Ao invés de apenas usar a rede padrão, você pode especificar a sua própria rede usando a chave de networks de alto nível. Isso permite a criação de topologias mais complexas e especificar drivers de rede personalizados. Também é possível usá-la para conectar serviços a redes criadas externamente que não são gerenciadas pelo Compose.
Cada serviço pode especificar a quais redes quer se conectar com a chave de networks de nível de serviço, que é uma lista de nomes referenciando entradas através chave de redes de alto nível.

O exemplo a seguir mostra um arquivo Compose que define ruas redes personalizadas. O serviço proxy é isolado do serviço db pois eles não têm uma rede em comum. Apenas app pode comunicar com ambos.


  services:
   proxy:
      build: ./proxy
      networks:
         - frontend
   app:
      build: ./app
      networks:
         - frontend
         - backend
   db:
      image: postgres
      networks:
         - backend

  networks:    frontend:
      # Use um driver personalizado
      driver: driver-personalizado-1
   backend:
      # Use um driver personalizado que leva opções especiais
      driver: driver-personalizado-2
      driver_opts:
         foo: "1"
         bar: "2"


Redes podem ser configuradas com endereços de IP estáticos colocando o endereço ipv4 e/ou ipv6 para cada rede vinculada.
Redes também podem ter um nome personalizado:


  services:
   # ...
  networks:
   frontend:
        name: frontend_personalizado
        driver: driver-personalizado-1

Configurar a rede padrão

Ao invés de especificar as suas próprias redes, também podemos mudar as configurações da rede padrão do aplicativo definindo uma entrada networks chamada default:


  services:
   web:
      build: .
      ports:
         - "8000:8000"
   db:
      image: postgres

  networks:
   default:
      # Use um driver personalizado: .
      driver: driver-personalizado-1

Usando uma rede já existente

Se você quer que seus containers entrem em uma rede já existente, use a opção external.


  services:
   # ...
  networks:
   network1:
      name: minha-rede-existente
      external: true

Ao invés de tentar criar uma rede chamada [nomeprojeto]_default, o Compose procura por uma rede chamada minha-rede-existente e conecta os containers do seu app a ela.