Redes
Uma Redes de contêineres refere-se à capacidade dos contêineres se conectarem e comunicarem entre si. Os contêineres têm redes habilitada por padrão e podem fazer conexões de saída. Um contêiner não tem informações sobre que tipo de rede está conectado ou se seus pares também são cargas de trabalho do Docker ou não.
Um contêiner só vê uma interface de rede com um endereço IP, um gateway, uma tabela de roteamento, serviços DNS e outros detalhes de networking. Isso, a menos que o contêiner use o driver de rede none
.
Você pode criar redes personalizadas e conectar vários contêineres à mesma rede. Uma vez conectados a uma rede personalizada, os contêineres podem se comunicar entre si usando os endereços IP dos contêineres ou os nomes dos contêineres.
Drivers de Rede
Os drivers de rede no Docker são componentes que controlam como os containers se comunicam entre si, com o host e com redes externas. Eles definem a forma como a conectividade de rede é configurada e gerenciada nos containers. O Docker fornece vários drivers de rede para atender a diferentes necessidades de conectividade e isolamento.
Por padrão, quando você cria ou executa um contêiner usando docker create
ou docker run
, o contêiner não expõe nenhuma de suas portas ao mundo externo. Você pode disponibilizar uma porta para serviços fora do Docker usando a flag --publish
ou sua versão abreviada -p
, seguida pela porta do host e a porta do contêiner, separadas por dois pontos. Isso cria uma regra de firewall no host, mapeando uma porta de contêiner para uma porta no host Docker para o mundo externo.
Quando você deseja tornar um serviço que está sendo executado em um contêiner acessível a outras máquinas na rede, você precisa publicar as portas do container, isso é chamado de publicação de portas. A publicação de portas de contêiner é insegura por padrão. Ou seja, quando você publica as portas de um contêiner, ele fica disponível não apenas para o host Docker, mas também para o mundo exterior.
Para restringir a acessibilidade da porta apenas ao host Docker, você pode incluir o endereço IP do host local (127.0.0.1
) antes da porta do host na flag de publicação. Isso garante que apenas o host Docker possa acessar a porta do contêiner publicada.
docker run -p 127.0.0.1:8080:80 nginx
Se quiser tornar um contêiner acessível a outros contêineres, não é necessário publicar as portas do contêiner. Você pode ativar a comunicação entre contêineres conectando-os à mesma rede, geralmente usando o driver bridge
.
Não é possível expor ou fazer o bind de portas para um container que já esteja em execução. Pelo menos não uma maneira que seja fácil e aplicável.
Os contêineres usam os mesmos servidores DNS que o host por padrão, mas você pode substituir isso usando a flag --dns
. Além disso, os contêineres herdam as configurações de DNS definidas no arquivo de configuração /etc/resolv.conf
por padrão.
Os contêineres que se conectam a uma rede personalizada usam o servidor DNS incorporado do Docker. O servidor DNS incorporado encaminha pesquisas de DNS externas para os servidores DNS configurados no host. Você pode configurar a resolução DNS por contêiner, usando sinalizadores para o comando docker run
ou docker create
usado para iniciar o contêiner.
Se o arquivo /etc/resolv.conf
no sistema host contiver uma ou mais entradas de servidor de nomes com um endereço IPv6, essas entradas de servidor de nomes serão copiadas para /etc/resolv.conf
nos contêineres que você executa.
Para contêineres que usam musl libc
(em outras palavras, Alpine Linux), isso resulta em uma condição de corrida para pesquisa de nome de host. Como resultado, a resolução do nome do host poderá falhar esporadicamente se o servidor DNS IPv6 externo vencer a condição de corrida contra o servidor DNS incorporado.
É raro que o servidor DNS externo seja mais rápido que o incorporado. Mas coisas como a coleta de lixo ou um grande número de solicitações de DNS simultâneas podem, às vezes, resultar em uma viagem de ida e volta ao servidor externo mais rápida do que a resolução local.
Os seguintes drivers de rede estão disponíveis por padrão e fornecem funcionalidades básicas de rede:
Driver bridge
A rede bridge é o modo de rede padrão no Docker. Quando você cria e executa um container, ele é automaticamente conectado a uma rede bridge chamada bridge
(a menos que você especifique outra configuração de rede). Essa rede funciona como uma rede interna isolada no host Docker, permitindo a comunicação entre containers conectados a ela.
A rede bridge é isolada do mundo externo por padrão, para expor um container ao mundo externo, é necessário mapear portas explicitamente usando a flag -p
ou --publish
. Os containers que estiverem conectados à mesma rede bridge podem se comunicar entre si.
A rede bridge
é criada como uma interface de rede virtual no host Docker, geralmente chamada de docker0. Cada container conectado à rede bridge recebe um endereço IP único da sub-rede configurada para essa rede (geralmente no formato 172.x.x.x/16).
Por padrão, qualquer containers que estejam compartilhando à mesma rede bridge, poderão se comunicar entre si usando seus endereços IP internos, mas não pelo nome dos containers, para que eles possam se comunicar pelo nome do container e não pelos endereços IP, uma bridge personalizada deve ser usada.
Driver host
A rede host no Docker é um modo de rede que permite que um container use diretamente a pilha de rede do host, sem isolamento de rede. Isso significa que o container compartilha a interface de rede do host e, portanto, não possui um endereço IP separado. Ele usa os mesmos IPs e portas do sistema host.
Ao eliminar a camada de virtualização de rede, a rede host pode oferecer melhorias de desempenho para aplicações que exigem alta taxa de transferência ou baixa latência. O uso da rede host reduz o isolamento entre o container e o host, o que pode ter implicações de segurança. Embora o container compartilhe a rede com o host, ele não possui acesso direto às interfaces de rede do host. Os processos dentro do container não podem vincular-se aos endereços IP do host diretamente.
O uso do driver host não é recomendado como padrão, a menos que você tenha uma necessidade muito específica e compreenda totalmente as implicações. Geralmente, as redes bridge ou personalizadas são suficientes para a maioria das aplicações, pois oferecem melhor isolamento, flexibilidade e segurança.
Driver none
O driver de rede none no Docker é utilizado para criar containers completamente isolados em termos de rede. Ao iniciar um container com este driver, ele não possui interfaces de rede externas configuradas, exceto a interface de loopback (lo
). Isso significa que o container não pode se comunicar com outros containers, com o host ou com redes externas.
Driver overlay
A rede overlay no Docker permite a comunicação segura entre containers distribuídos em diferentes hosts, facilitando a criação de aplicações distribuídas e altamente disponíveis. É uma rede criada para conectar dois ou mais containers que estejam em servidores diferentes, fazendo parecer que estejam no mesmo servidor Docker. Ela é amplamente utilizada em conjunto com o Docker Swarm para orquestração de serviços em clusters.
Driver ipvlan
O driver de rede IPvlan no Docker oferece controle avançado sobre o endereçamento IPv4 e IPv6, permitindo que containers sejam configurados com endereços IP diretamente na rede física subjacente. Isso facilita a integração dos containers com a infraestrutura de rede existente, tornando-os semelhantes a dispositivos físicos na rede.
- Modo L2 (Layer 2): Os containers compartilham o mesmo espaço de broadcast da rede física, permitindo comunicação direta entre eles e com outros dispositivos na mesma sub-rede.
- Modo L3 (Layer 3): Cada container atua como um roteador individual, necessitando de rotas específicas para comunicação, o que pode ser útil para segmentação de rede e controle de tráfego.
Driver macvlan
O driver de rede Macvlan no Docker permite que você atribua um endereço MAC exclusivo a cada container, fazendo com que eles apareçam como dispositivos físicos distintos na rede. Isso é particularmente útil para aplicações legadas que esperam estar diretamente conectadas à rede física ou para cenários onde é necessário um controle mais granular sobre o tráfego de rede.
IPv6
Se precisar de suporte IPv6 para contêineres Docker, você precisará habilitar a opção no daemon Docker e recarregar sua configuração antes de criar qualquer rede IPv6 ou atribuir endereços IPv6 aos contêineres. Ao criar sua rede, você pode especificar a flag --ipv6
para ativar o IPv6. Você não pode desabilitar seletivamente o suporte IPv6 na rede bridge padrão.
Antes de pensar em usar IPv6 em contêineres Docker, você precisa habilitar o suporte IPv6 no daemon Docker. Depois disso, você pode optar por usar IPv4 ou IPv6 (ou ambos) com qualquer contêiner ou rede. O IPv6 só é compatível com daemons Docker executados em hosts Linux.
Use a rede bridge padrão
A rede bridge padrão é considerada legada e não é recomendada para uso em produção. A rede bridge padrão, embora funcional, é considerada legada por algumas razões:
Segurança
A rede bridge concede acesso irrestrito entre containers, o que pode ser um risco de segurança em ambientes de produção.Isolamento
Containers na mesma rede bridge podem se comunicar livremente, dificultando o isolamento de serviços e a contenção de falhas.Gerenciamento
A rede bridge oferece menos flexibilidade e granularidade no gerenciamento de redes em comparação com alternativas mais modernas.
O arquivo /etc/docker/daemon.json
é usado para definir as configurações do daemon Docker, incluindo as configurações de rede padrão. Se você não especificar explicitamente uma rede ao criar um contêiner, o contêiner será criado na rede padrão definida no arquivo daemon.json
.
Para configurar a rede de ponte (bridge) padrão, podemos especificar as opções no arquivo /etc/docker/daemon.json
. Abaixo está um exemplo de daemon.json
com várias opções especificadas. Apenas mantenha as configurações que você precisa personalizar:
{
"bip": "192.32.0.1/24",
"fixed-cidr": "192.32.0.0/24",
"fixed-cidr-v6": "2001:db8:1::/64",
"mtu": 1500,
"dns": [
"8.8.8.8",
"8.8.4.4"
],
"default-gateway": "192.32.0.254",
"default-gateway-v6": "2001:db8:1::1",
"icc": true,
"ip-masq": true,
"iptables": true,
"ip-forward": true
}
bip
: IP do ponteiro do Docker.fixed-cidr
: Subrede fixa IPv4.fixed-cidr-v6
: Subrede fixa IPv6.mtu
: Unidade Máxima de Transmissão.default-gateway
: Gateway padrão IPv4.default-gateway-v6
: Gateway padrão IPv6.icc
: Permitir comunicação entre contêineres.ip-masq
: Mascaramento de IP.iptables
: Habilitar regras de IPTables.ip-forward
: Encaminhamento de IP.
Agora é só reiniciar o serviço do Docker, certifique-se de que nenhum container esteja rodando.
Docker network
O comando docker network
é usado para gerenciar redes no Docker. Com este comando, você pode criar, listar, inspecionar e remover redes. Aqui estão algumas operações mais comuns:
Comando | Descrição |
---|---|
docker network create <nome> | Cria uma nova rede com o nome especificado. |
docker network ls | Lista todas as redes disponíveis no Docker. |
docker network inspect <nome> | Fornece informações detalhadas sobre uma rede específica. |
docker network rm <nome> | Remove uma ou mais redes. Você precisa especificar o nome da rede que deseja excluir. |
docker network connect <rede> <contêiner> | Conecta um contêiner a uma rede específica. |
docker network disconnect <rede> <contêiner> | Desconecta um contêiner de uma rede específica. |
# Cria uma rede chamada my-net
docker network create --driver bridge --subnet 172.18.0.0/16 --gateway 172.18.0.1 my-net
# Conecta um contêiner em execução a uma rede existente:
docker network connect my-net my-nginx
# Desconecta um contêiner em execução a uma rede existente:
docker network disconnect my-net my-nginx
# Ver as redes criadas:
docker network ls
# Remover uma rede chamada test1
docker network rm test1
# Criando uma rede bridge:
docker network create \
--driver=bridge \
--subnet=172.28.0.0/16 \
--ip-range=172.28.5.0/24 \
--gateway=172.28.5.254 \
br0
# Criando uma rede overlay:
docker network create -d overlay \
--subnet=192.168.10.0/25 \
--subnet=192.168.20.0/25 \
--gateway=192.168.10.100 \
--gateway=192.168.20.100 \
--aux-address="my-router=192.168.10.5" --aux-address="my-switch=192.168.10.6" \
--aux-address="my-printer=192.168.20.5" --aux-address="my-nas=192.168.20.6" \
my-multihost-network
--attachable
Permite que containers sejam manualmente conectados à rede por comandos comodocker network connect
.--gateway
Define o gateway IPv4 ou IPv6 da sub-rede principal da rede. O gateway é o endereço usado para comunicação entre redes diferentes.docker network create --subnet=192.168.1.0/24 --gateway=192.168.1.1 my-network
--driver
Especifica o driver que gerenciará a rede. Exemplos comuns:bridge
(padrão): Rede local para containers no mesmo host.overlay
: Comunicação entre containers em diferentes hosts.macvlan
ouipvlan
: Integração direta com a rede física.
--internal
Restringe o acesso externo à rede. Containers na rede interna podem se comunicar entre si, mas não com redes externas (como a internet).--ip-range
Define um sub-range de IPs dentro da sub-rede principal que será usado para alocar IPs aos containers.docker network create --subnet=192.168.1.0/24 --ip-range=192.168.1.128/25 my-network
--ipam-driver
Define o driver para o gerenciamento de endereços IP (IP Address Management - IPAM), que é o sistema responsável por gerenciar e alocar endereços IP dentro das redes criadas no Docker. O padrão édefault
, mas pode ser alterado para outros drivers personalizados.docker network create --ipam-driver default my-network
--ipv6
Habilita suporte a IPv6 na rede criada.docker network create --ipv6 my-ipv6-network
--label
Define metadados na forma de pareschave=valor
associados à rede. Útil para organização, busca ou automação.docker network create --label environment=production my-network
--scope
Define o escopo da rede:local
: A rede existe apenas no host onde foi criada.global
: A rede é compartilhada entre todos os nós em um cluster Swarm.docker network create --scope global my-global-network
--subnet
Define uma sub-rede no formato CIDR para a rede criada. É útil para especificar ranges de IPs específicos para a rede.docker network create --subnet=192.168.1.0/24 my-network
--config-from
Copia a configuração de uma rede existente para a nova rede.docker network create --config-from existing-network my-new-network
--config-only
Cria uma rede que apenas armazena configurações, sem funcionalidade operacional. Usado em conjunto com--config-from
.docker network create --config-only my-config-network
Como criar uma rede segura?
Para utilizar uma bridge personalizada em seus projetos Docker em produção, existem diversas opções vantajosas que oferecem maior flexibilidade e segurança em comparação à rede bridge padrão. O uso de uma rede definida pelo usuário fornece uma rede com escopo definido na qual apenas contêineres conectados a essa rede são capazes de se comunicar.
Controle de acesso granular
Com uma bridge personalizada, você pode definir regras de firewall específicas para controlar o tráfego de entrada e saída entre containers, aumentando a segurança do seu ambiente.Isolamento de serviços
Ao criar redes bridge personalizadas, você pode isolar diferentes serviços em redes separadas, evitando conflitos de comunicação e facilitando a detecção de falhas.Segregação de ambientes
É possível criar bridges personalizadas para separar ambientes de desenvolvimento, teste e produção, garantindo a segurança e a confiabilidade dos seus dados.Integração com ferramentas de rede
As bridges personalizadas permitem a integração com ferramentas de rede como firewalls, proxies e balanceadores de carga, oferecendo maior controle e flexibilidade na gestão do seu ambiente.Suporte a IPv6
As bridges personalizadas podem ser configuradas para suportar IPv6, permitindo a integração com redes e dispositivos modernos que utilizam este protocolo.
Opções de implementação:
Docker Compose
- Utilize o campo
networks
no arquivodocker-compose.yml
para definir e configurar sua bridge personalizada. - Crie redes com diferentes configurações de conectividade, isolamento e segurança para atender às suas necessidades.
- Utilize o campo
Ferramentas de orquestração
- Ferramentas como Docker Swarm e Kubernetes facilitam a criação e o gerenciamento de redes complexas, incluindo bridges personalizadas.
- Utilize interfaces gráficas e recursos avançados para gerenciar suas redes com mais eficiência.