Se você tem um background de infra grande e está acostumado a entregar IP’s para suas máquinas virtuais, é super natural que você considere essa a solução ideal para containers. Não é!
Se sua resposta foi sim, você não poderia estar mais errado!
Em um ambiente com containers, não queremos que os containers tenham IP’s públicos, exceto caso seja algo muito fora do comum, como aplicações de TELECOM muito específicas, por exemplo.
Claro que existem outros exemplos, mas o que quero dizer e ser totalmente claro é que, se estamos falando de uma aplicação web comum, wordpress, drupal, nextcloud, elastic, ghost,kong, aplicações web .NET, Java, Node, Ruby, Python, PHP etc… então entregar um IP público para seu container, ou simplesmente fixar um IP interno no container é um erro.
Mas o que está errado?
Com docker aumentamos a densidade computacional de nossos servidores, portanto naturalmente estamos falando de servidores que passam a rodar dezenas, até centenas de aplicações, dependendo da máquina e do workload.
Todas, ou ao menos a maioria delas, precisam estar disponíveis fora do servidor, disponíveis nas portas 80 ou 443 para serem acessadas por navegadores e outras aplicações em outros servidores.
Entregar IP’s novos para cada uma dessas aplicações gera transtorno e custo absurdo e desnecessário. Em resumo, você está rasgando dinheiro por gastar tempo configurando e gerindo esses IP’s. Afinal, você tem uma lista de nomes e IP’s no DNS, mas em qual dos 10 servidores esses IP está? Uma camada de gestão adicional entra aí.
Comunicação interna Container para Container
Se 2 containers precisam se falar, vamos supor um container PHP e outro MYSQL então:
- O Container MYSQL não precisa ter sua porta exporta.
- O container MYSQL não precisa ter um IP fixo, muito menos um IP conhecido.
Eu usei PHP e MYSQL, mas pode considerar .NET e SQL Server, Java e Postgres, Node e MongoDB etc etc.
Ok, então o que é necessário?
- Ambos os containers PHP e MYSQL precisam estar na mesma rede docker.
- Tipos de Rede
- Se estivermos falando de um só servidor, estamos falando de redes bridge
- Se estivermos falando de um cluster swarm estamos falando de uma rede overlay.
- A rede docker possui resolução de nomes, em termos práticos, é como se houvesse um DNS interno, embarcado nela.
- Cada novo container nessa rede, possui um ou mais aliases, que podem ser aleatórios ou um nome que você define.
É esse nome que corresponderá ao IP do container e o docker lida de tudo isso para você. Exatamente para que você não tenha de lidar com o IP do container. É algo não fixo e não pré-determinado que não queremos que você lide manualmente.
Comunicação externa Internet/Intranet para Container
Então você criou uma API .NET, uma de 10 API’s diferentes que serão implantadas no mesmo servidor.
Para expor isso para o mundo, você não faria da mesma forma como desenvolve, com as portas 5000, 5001, 5002, 5003, 5… .
Novamente, quando queremos expor um container, não vamos expor a porta dele diretamente.
Em vez disso, nós colocamos um proxy reverso para mediar a comunicação
Fica assim
- o proxy reverso, também seriam um container
- ele seria o único serviço com as portas 880 e 443 expostas lá no host
- ele estaria em uma rede (bridge ou overlay) criada por você
Esse proxy reverso seria o mediador entre a comunicação do mundo externo com nossos containers, nosso servidor.
Isso permite que você tenha 10, 220, 100 containers respondendo indiretamente na mesma porta 443 do servidor. Indiretamente porque é o proxy reverso é quem distribui o tráfego, em geral, com base no cabeçalho HOST.
A regra de comunicação entre containers volta a aparecer aqui, então o proxy reverso também não sabe o IP dos containers, sabe apenas o alias. E novamente o proxy reverso precisa estar na mesma rede docker do container que ele precisa rotear tráfego.
Na prática, é mais comum que o proxy reverso tenha uma rede só delem dedicada à comunicação interna, e nós colocamos todos os containers que precisam ser expostos via proxy reverso, nessa mesma rede.
Isso permite que no seu DHCP, não tenha nenhum IP maluco, do qual você nem lembra como foi entregue e para qual servidor foi entregue.
Já no seu DNS, você aponta os 10 nomes para o mesmo IP do servidor docker.
Conclusão
Docker permite atribuir IPs nos containers, você pode definir um IP interno ou um IP público, da rede.
O caminho para setar o IP é via configurações de rede do container.
Já o caminho para setar um IP público é com redes McVLAN.
Entretanto, escolher essa abordagem como a primeira abordagem, em cenários comuns, como estratégia default, é um atestado de ignorância sobre o docker em si.
É o tipo de coisa que quem conhece diz:
– Hummm, isso é coisa de SysAdmin preguiçoso e presunçoso que cuidava de VMWare, e acha que container é VM.
Claro que existem cenários, principalmente em aplicações muito velhas, em que isso é necessário, mas até hoje, desde 2016 nunca precisei forçar IP em nenhum container, muito menos atribuir um IP público para ele.
2023-08-10 (isso ainda é verdade em 2023, nunca precisei)
O desenho com proxy reverso só parece mais trabalhoso para quem nunca fez. Na prática, é simples e rápido, e você entrega um proxy reverso em minutos.
Outro ponto importante para os SysAdmins que possam chegar a esse video é:
Tudo, absolutamente tudo que no mundo das VM’s se fazia de um jeito A, no docker tem um jeito B, padrão aqui.
Muitas features foram adicionadas ao docker para lidar com os mesmos dilemas existentes em VM’s, só que do jeito docker de pensar.
O objetivo geralmente é manter a imutabilidade, permitir escalabilidade, simplificar os ambientes e inclusive permitir que stacks idênticas sejam implantadas diversas vezes no mesmo servidor.
Isso inclui redes, arquivo hosts, script de inicialização e muito mais.
Se olharmos para o Kubernetes, vamos ver que ele vai além.
O Ingress Controller (componente) e o Ingress (sua configuração) partem do princípio de que há a necessidade de um proxy reverso, para, a partir dessa verdade, entregar uma forma sofisticada, simples e eficiente de realizar esse tipo de configuração.
Sem necessidade de conhecimento específico da linguagem de configuração da implementação do Proxy Reverso, sem usando somente configurações genéricas, impostas pelo próprio Kubernetes.
Muito bom o artigo, Luiz,
Esperando agora sair um vídeo exemplificando como implementar esse setup com dockers e um proxy reverso rsr
Obrigado
1) https://gago.io/blog/proxy-reverso/
2) https://www.youtube.com/watch?v=c9vfAjMrKeQ
3) https://www.youtube.com/watch?v=NJ64oO154Zk
4) https://gago.io/blog/servicemesh-apigateway-reverseproxy/
Espero que goste!