1. Início
  2. Back-end
  3. Orquestração de contêineres — com Docker, Swarm e Portainer

Orquestração de contêineres — com Docker, Swarm e Portainer

containeres um do lado do outro

Quando se trata de DevOps, orquestrar contêineres é um ponto vital. Isso se deve ao fato de que, em um ambiente DevOps, a entrega da infra ocorre como código.

Mas não se assuste (ainda), estamos apenas começando e, para entender direitinho como tudo isso funciona, vamos falar de Docker, Swarm e Portainer.

Não vamos entrar em debate sobre qual ferramenta é melhor, mas sim, ensinar na prática como orquestrar contêineres utilizando essas três ferramentas e o sistema operacional Linux.

É importante frisar que nosso foco principal é na ferramenta Docker, fornecedora de contêineres.

Vamos lá? 🙂

Não vamos pular etapas: deixe o kubernetes pra depois

É claro que a ferramenta mais indicada para orquestração de contêineres Docker é o Kubernetes.

Mas não se engane: precisamos aprender a dirigir o 1.0 turbo antes de pegarmos o V8. Por isso o Docker Swarm simplificará nossos primeiros passos.

Apesar de muitas opiniões contrárias, o Swarm se sai muito bem em produção, sim. Se você o utilizar direito, a migração pro Kubernetes vai ser simples um dia.

>>Leitura Recomendada:
Usando o
MediatR com ASP.NET Core

O Swarm na prática

O Swarm é um modo nativo do docker, que, quando habilitado, clusteriza um conjunto de computadores.

Após o devido ingresso no cluster, o modo swarm passa a atuar como hospedeiro para qualquer contêiner que precise dos recursos disponíveis no cluster.

Neste modo, você cria “Services”, em vez de contêineres. Agora imagine o ‘Service’ como se fosse um projeto arquitetônico de uma casa.

A partir desse projeto arquitetônico, você diz pro swarm quantas casas (contêineres) você quer construir, e pronto: os contêineres são criados e distribuídos no cluster.

>>Leitura Recomendada:
Os principais serviços da arquitetura AWS!

Services e contêineres

Sim. No mundo DevOps você projeta e a linha de produção faz acontecer.

Considere o Docker como uma de nossas linhas de produção. Ele pode atuar de forma harmoniosa com várias linhas de produção simultâneas, que dividem seus recursos para otimizar a entrega. Isso é swarm, linhas de produção integradas.

Quando você cria um cluster Swarm, considere que é necessário no mínimo três computadores e eles são classificados em managers e workers.

Os managers têm alguns ‘privilégios’ e podem ditar como o cluster trabalha.

Agora, guarde isso: é necessário no mínimo três masters para um cluster saudável.

Para iniciar um cluster swarm, instale o docker no seu linux preferido. Considerando o IP da sua maquina como “192.168.0.6”, dê o comando:

$ docker swarm init

A resposta será:

 
Swarm initialized:

To add a worker to this swarm, run the following command:
$docker swarm join --token AEOIHEAOE-1-aefuihfea342342i3u42iuh24g54g2h4 no23nih4i2u3ni424oi23n42u4gn2o3i 192.168.0.6:2377

Ele, além de inicializar o cluster, ainda te passa o comando que você deve rodar nos outros ‘nós’ para que eles ingressem como “WORKERS” no ecossistema.

Para obter o comando de ingresso de novos “MASTERS” (precisamos de três para um cluster saudável), digite “docker swarm join-token manager”.

Um cluster em dois comandos. Nem parece possível.

Portainer – Enterprise ready

Estamos aqui para entender o que acontece em um orquestrador de contêineres, então vamos utilizar um gestor gráfico chamado Portainer.

Eu sei que uma tecnologia muito falado atualmente é o Kubernetes, está em alta. Mas, para começar a orquestrar, o Portainer pode ser a solução ideal. Se te interessar mais tarde, aqui está uma comparação: Portainer vs Kubernetes.

O Portainer é uma interface web que interage com o socket do docker para criar novos contêineres e monitorá-los.

O Portainer também pode ser utilizado para visualizar o cluster, gerenciar a autenticação de usuários e permissões de acesso ao cluster.

O portainer é, de forma resumida, uma aplicação para gerenciar seus containers, estejam eles em cluster ou não.

Eles tem objetivo de agilizar a movimentação desses contêineres no momento de carga e descarga.

Outro detalhe legal: você pode administrar vários clusters Swarm em um único portainer.

Utilizando o “Portainer Agent” você se conecta em outros clusters, acessa a Shell de qualquer contêiner, migra suas Stacks — já vamos falar disso — para outros clusters e muito mais.

>> Leitura recomendada:
Como instalar o Portainer?

Poderíamos fazer isso expondo a API do Docker?

Sim, mas o processo varia de acordo com a distribuição Linux que você utiliza, então vamos facilitar as coisas.

Por enquanto o agente do Portainer é o suficiente.

O Portainer como serviço

homem organizando pneus num estoque

Esta solução na verdade é composta de dois serviços, o Portainer em si e o agente.

O agente é responsável pela comunicação da interface web de administração e os nós do cluster. Assim você poderá acessar qualquer container ou volume, ver logs, etc.

Para subir o agente  use o comando:


$ docker service create \
--name portainer_agent \
--network apps \
-e AGENT_CLUSTER_ADDR=tasks.portainer.agent \
--mode global \
--constraint 'node.platform.os == linux' \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
--mount type=bind,src=/var/lib/docker/volumes,dst=/var/lib/docker/volumes \
   portainer/agent


Parece complicado, mas vamos entender as novidades em relação ao comando de criação do serviço do traefik.

Por meio do “-e”, passamos uma variável de ambiente com um endereço pro nosso agente. Em seguida determinamos o modo global, ou seja, todos os nós do cluster devem rodar esse contêiner.

Como essa imagem é para nós Linux, usamos a constraint para garantir que ele não vai rodar em nós com outro sistema operacional.

Pra fechar montamos o socket do docker e o diretório de volumes do docker, assim o Portainer pode administrar os volumes e containers em qualquer nó em que o agente estiver.

Finalmente, suba o Portainer com o comando:

$  docker service create -t \
--name portainer \
--network apps \
--replicas=1 \
--constraint 'node.role == managem' \
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
--mount type=bind,src=/mnt/portainer,dst=/data \
-l “traefik.docker.network=app” \
-l “traefik.frontend.rule=Host:portainer.lab.local” \
-l “trafik.port=9000” \
portainer/portainer -H “tcp://tasks.portainer.agent:9001” --tlsskipverify

O que muda aqui, é que só teremos uma réplica. este serviço deve rodar apenas em nós que sejam “managers” do swarm.

Também persistimos o diretório do container “/data” no diretório local do host “/mnt/portainer”.

Em seguida passamos os labels pro nosso front-end encaminhar requisições para o endereço “portainer.lab.local” diretamente para o contêiner do Portainer na porta 9000.

Pra fechar, apontamos para o endereço dos agentes ignorando a verificação ssl e PUM! Tá no ar!

Como eu faço a orquestração de contêineres na prática?

A introdução foi longa, mas necessária. Revise tudo acima até imergir no contexto.

Remova quaisquer resquícios de outras versões do docker:

$ sudo apt-get remove docker docker-engine docker.io containerd runc 

Instale os pré requisitos:

$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common 

Configure o repositório oficial do Docker

Adicionando Chaves do repositório

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88

Adicionando repositório oficial do Docker-ce


$ sudo add-apt-repository \
  "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) \
  stable

Instalando docker

$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

IMPORTANTE: repita esses passos em todas as Vm’s. Em seguida vamos criar nosso cluster.

Inicializando cluster SWARM

Para inicializar o cluster, acesse a vm 1, acesse como root e dê o comando:


$ docker swarm init

A saída desse comando vai te dar a instrução de adicionar workers ao cluster, mas queremos managers. Afinal, precisamos de 3 managers para um cluster saudável, lembra?

Para obter o comando de inclusão de managers, digite o comando:

$ docker swarm join-token manager

A saída desse comando nada mais é que o que você precisa executar em todos as demais VM’s para que elas entrem no cluster como Managers.

A cereja do bolo

Apesar de não ser nosso escopo, não é nada prático acessarmos nossos serviços por meio de um endereço de IP.

Então vamos utilizar um Front-end para encaminhar nossas requisições “HTTP” para os contêineres que rodam aplicações web.

Para isso, vamos usar o Traefik, que é um front-end super performático e otimizado para nosso ambiente cloud.

Com ele, em vez de criarmos “virtual Hosts” em um Front-end Apache por exemplo, basta que informemos algumas “labels”  na hora de subir nossos contêineres.

Para subir (já como um service dentro do swarm) o Trafik, primeiramente crie a rede que ele vai utilizar para fazer a ponte de frontend com os demais containers:


$ docker network create --driver overlay -- attachable --subnet=192.162.250.0/24 apps

Este comando cria uma rede usando o driver overlay, que vai interagir com todo o cluster e pode ser anexada aos contêineres que forem criados. É importante escolher uma faixa de rede incomum para evitar problemas de roteamento.

Em seguida crie o contêiner do traefik:


$ docker service create --name Frontend -- network apps --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock -p 80:80 -p 8080:8080 traefik:latest --docker --docker.watch --api

Que beleza!

Um front-end em duas linhas de comando. Vamos entender o que cada parte do comando significa:

“docker service create” = Estamos informando pro Docker que vamos criar um serviço do swarm.

“–name Frontend” = Estamos atribuindo um nome a este serviço. Nesse caso o serviço vai se chamar “Frontend”.

“–mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock” = Monte um volume do tipo “diretório local” no caminho “/var/run/docker.sock” dentro do contêiner pro mesmo caminho. é através desse socket do docker que o traefik detecta novos contêineres.

“-p 80:80 -p 8080:8080” = Exponha essas portas apontando para o contêiner. Seria um “nat” da porta externa do host docker, para interna do contêiner.

“traefik:latest” = Imagem docker que vamos usar para esse serviço. Nesse caso a do traefik na última versão.

“–docker –docker.watch –api” = Comandos passados para o contêiner do nosso frontend, de acordo com a documentação do traefik.

Na prática, informamos ao traefik que ele vai monitorar o ambiente docker por meio do socket montado e que vai disponibilizar uma interface web para consultas de API e monitoramento visual.

>>Leitura Recomendada:
Arquitetura de microsserviços x Arquitetura Monolítica

Algumas coisas ainda não fazem sentido

O mundo Docker é imenso e eu acabei de te mostrar apenas uma das milhares de formas de se subir um cluster e uma interface de gerenciamento.

Explore este ambiente e veja que, por meio do portainer, boa parte acontece em background no docker.

Lembra dos yamls e Stacks? Falamos sobre isso no artigo sobre os Pilares DevOps?

O portainer é perfeito para que você veja isso funcionando. Quer uma dica para sua primeira stack?

Faça uma com o serviço “Visualizer”. Com ele você visualiza seus contêineres em tempo real. Em que nós os containers estão rodando, veja-os saltando de nó em nó, etc etc..

Qual a conclusão sobre orquestração de ambientes?

Espero ter ajudado com um “norte” na sua caminhada Docker. Muita coisa é novidade e, naturalmente, você precisa de um tempo de adaptação. Agora é questão de persistir e testar. O resto vem naturalmente.

Grande abraço!


Categorias

Leituras Recomendadas

Quer receber conteúdos incríveis como esses?

Assine nossa newsletter para ficar por dentro de todas as novidades do universo de TI e carreiras tech.