>> Apresentação e considerações

Yo!

Fala ChurrOpeiros, vamos falar um pouco de rede no Docker, nesse post vou focar somente na rede Bridge, pra tentar explicar um pouco do seu funcionamento de acordo com os meus estudos, na sequência falarei mais sobre os outros tipos de drivers de rede como host e overlay por exemplo, mais isso será artigo para outros posts.

>> Default Networks

O Docker disponibiliza 3 drivers de rede: bridge, host, e overlay (somente utilizada com o Docker swarm), além disso podemos utilizar drivers de terceiros.

Ao instalar o Docker podemos listar 3 redes criadas como padrão:

~# docker network ls
NETWORK ID   NAME   DRIVER SCOPE
4865e4d1bd6b bridge bridge local
d40004e863b4 host host local
91f5e3d80a35 none null local

Onde:

bridge – Vamos fazer dela mais abaixo

host – Nesse modo, o daemon configura a rede do container como uma cópia da rede do host docker. Sendo assim o container possui as mesmas configurações do host (IP, gateway, rotas, hostname, etc.).

none – Não possui nenhuma configuração de rede no container, ou seja, não tem IP, máscara, Gateway, etc, é um container isolado sem driver de rede.

>> Bridge Network

Como nosso foco é rede bridge, vamos a ela!

Esse é um exemplo básico da arquitetura do Docker em rede bridge.

Vemos que o Docker Host possui uma comunicação com os demais hosts da sua rede e os containers conversam entre si em outro range, o acesso externo ao container é feito através do Docker Host.

docker-bridge-network (1)

O driver bridge cria uma rede privada interna (local) para o host para que os containers dessa rede possam se comunicar. Para acessarmos externamente precisamos expor as portas do container para o nosso Docker Host, e o acesso externo é realizado através do endereço do Docker Host e a porta exposta.

Ao subirmos um container sem especificar o “–network” ele terá a rede bridge como padrão, em nosso exemplo vamos criar a nosso rede primeira bridge network em nosso Docker

~# docker network create --driver bridge rdglinux
fe3d1128f378ab601d5a209ba8e034a543052680d2725bd6a9c6a60624e6e98f

~# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
72c6a0509b8a        bridge              bridge              local
d40004e863b4        host                host                local
91f5e3d80a35        none                null                local
fe3d1128f378        rdglinux            bridge              local

O parâmetro “–network” é onde indicamos a rede que iremos utilizar em nosso container, no caso abaixo iremos subir dois containers rodando nginx, definindo os nomes e a porta que será “bindada”em nosso Docker Host, lembrando que na rede bridge a porta que vamos fazer o bind precisa ser única no host, ou seja, ela não pode estar ocupada por nenhum processo no Docker Host e em nenhum outro container.

~# docker container run --name webserver1 --network rdglinux -d -p 8090:80 nginx
3b85d6f075c7396fe885b37b9be2aa0d0a2ca660755c523962717fd5de545a44

~# docker container run --name webserver2 --network rdglinux -d -p 8091:80 nginx
db6c42d33a52046461e9213cc88edf5b10fcb3436b67db063d590aea5fa67551

Aqui vemos que os nossos contamines estão em execução

~# rodrigo$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
db6c42d33a52        nginx               "nginx -g 'daemon ..."   5 seconds ago       Up 4 seconds        0.0.0.0:8091->80/tcp   webserver2
3b85d6f075c7        nginx               "nginx -g 'daemon ..."   12 seconds ago      Up 12 seconds       0.0.0.0:8090->80/tcp   webserver1

Listando NetworkMode e o IP dos containers através do inspect.

~# docker inspect webserver1 |grep -iE 'NetworkMode|IPAddress'
            "NetworkMode": "rdglinux",
            "SecondaryIPAddresses": null,
            "IPAddress": "",
                    "IPAddress": "172.18.0.2",
~# rodrigo$ docker inspect webserver2 |grep -iE 'NetworkMode|IPAddress'
            "NetworkMode": "rdglinux",
            "SecondaryIPAddresses": null,
            "IPAddress": "",
                    "IPAddress": "172.18.0.3",

A informação dos IPs dos containers podem ser também visualizadas com inspecionando a rede que criamos:

~# docker network inspect rdglinux |grep -A14 Containers
        "Containers": {
            "3b85d6f075c7396fe885b37b9be2aa0d0a2ca660755c523962717fd5de545a44": {
                "Name": "webserver1",
                "EndpointID": "09f79517e3879184c2499ca2dcc47f63dc9fe68d5c08df203258f02802c67ce4",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "db6c42d33a52046461e9213cc88edf5b10fcb3436b67db063d590aea5fa67551": {
                "Name": "webserver2",
                "EndpointID": "0f1a1f084e4ad2b28d4c3ced881b20790c0d06ab92daea692ce8def8d550fe31",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }

Agora vamos fazer uma sequência de testes básicos de Ping somente para ver que os nossos contamines conseguem se comunicar com a rede que criamos, e vamos ver que eles tem conectividade entre si tanto por nome quanto por IP pois o Docker já se resolve com um DNS interno dele.

~# docker container exec webserver1 ping -c1 webserver1
PING webserver1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.106 ms
--- webserver1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.106/0.106/0.106/0.000 ms

~# docker container exec webserver1 ping -c1 webserver2
PING webserver2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.142 ms
--- webserver2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.142/0.142/0.142/0.000 ms

~# docker container exec webserver2 ping -c1 webserver1
PING webserver1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.120 ms
--- webserver1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.120/0.120/0.120/0.000 ms

~# docker container exec webserver2 ping -c1 webserver2
PING webserver2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.700 ms
--- webserver2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.700/0.700/0.700/0.000 ms

~# docker container exec webserver1 ping -c1 172.18.0.3
PING 172.18.0.3 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.155 ms
--- 172.18.0.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.155/0.155/0.155/0.000 ms

~# docker container exec webserver2 ping -c1 172.18.0.2
PING 172.18.0.2 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.124 ms
--- 172.18.0.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.124/0.124/0.124/0.000 ms

Listando as postas em LISTEN no Docker Host

~# netstat -antpu |grep LIST
tcp6       0      0  localhost.8091         *.*                    LISTEN
tcp4       0      0  *.8091                 *.*                    LISTEN
tcp6       0      0  localhost.8090         *.*                    LISTEN
tcp4       0      0  *.8090                 *.*                    LISTEN

Agora vamos acessar o serviço que está rodando nos containers e vamos ver a página de boas vindas do Nginx.

~# curl 192.168.100.102:8090

Welcome to nginx!

~# curl 192.168.100.102:8091

Welcome to nginx!

>> Removendo os recursos criados

Como de praxe, esse é um LAB apenas então vamos apagar os recursos que criamos:

~# docker container rm -f webserver1
webserver1

~# docker container rm -f webserver2
webserver2

~# docker network rm rdglinux
rdglinux

>> Conclusão

O Docker nos abre um leque de infinitas possibilidades, é um produto em constante evolução e desenvolvimento que a cada feature trás diversos recursos SENSACIONAIS, nessa série estou procurando abordar alguns pontos que considero importantes e que estão sendo base para meus estudos.

É isso pessoal, aqui procurei abordar de uma forma simples e prática, espero que gostem, coloque seu comentário e COMPARTILHEM!

Obrigado!

>> Referências

Para informações sempre mais precisas e atualizadas, SEMPRE consulte a documentação.

https://docs.docker.com/engine/userguide/networking/#bridge-networks

https://imasters.com.br/infra/compreendendo-os-drivers-do-docker-networking-e-seus-casos-de-uso/?trace=1519021197&source=single

https://www.mundotibrasil.com.br/docker-da-teoria-ao-hands-on-gerenciamento-de-redes/#more-6536