No momento que você inicia uma aplicação dentro de um contêiner espera-se que ela possa ser acessível externamente ao Docker em algum momento. Visando possibilitar isso o Docker permite exportar uma porta no Docker engine, que por sua vez ela é relacionada via NAT para o contêiner em questão.
Vamos a um exemplo, você tem um Docker engine instalado em seu computador pessoal e inicia um contêiner de nginx nele com o comando abaixo:
docker service run -d nginx
Você terá o seguinte cenário:
Como você pode perceber, caso você não exponha a porta do seu contêiner, ele não será acessível pela interface de rede da sua estação, ou seja, clientes externos a sua estação de trabalho não terão acesso ao nginx, pois a interface de rede do Docker é interna.
Para que o nginx seja acessível para clientes externos a sua estação de trabalho, você precisa usar a opção “-p”:
docker service run -d -p 80:80 nginx
Você terá o seguinte cenário:
Ao exportar a porta do contêiner o Docker associa uma NAT entre a interface da sua estação de trabalho e a interface de rede do seu contêiner, que anteriormente era acessível da sua console.
Como funciona no Swarm?
A ideia é bem parecida, a diferença é que no cluster Docker Swarm estamos falando de um ambiente distribuído, ou seja, são várias instâncias do Docker engine atuando juntas em um cluster.
Outro detalhe a se analisar nesse contexto é que como apresentado no capítulo anterior, passamos a manipular service, que na verdade é uma camada de abstração superior ao contêiner. Dessa forma uma vez criados os services, os contêiners são iniciados nos membros do cluster a partir da informação de quantas réplicas esse serviço terá.
Vejamos o mesmo exemplo de nginx, só que antes precisamos criar a rede overlay:
docker network create –driver overlay –subnet 10.0.9.0/24 –opt encrypted minha-rede
Agora criaremos o serviço, com a informação da rede overlay que acabamos de criar:
docker service create –replicas 1 –name minha-web –network minha-rede nginx
Você terá o seguinte cenário:
Caso o cliente acesse a porta 80 do host “Worker1” o tráfego será redirecionado para o host “Worker2” de forma transparente. Por conta disso você não poderá exportar a mesma porta na perspectiva do host para dois serviços ao mesmo tempo.
Podemos concluir que o cluster Swarm atua na prática como um único Docker engine, onde apenas uma porta pode ser exposta, e independente de qual nó solicitado, o conjunto responderá com consistência o serviço solicitado.