Conheça o Docker Swarm e monte um cluster com Raspberry Pi 3

No post anterior falamos sobre o que é o Docker, e como rodar containers em cima da Raspberry Pi. Esse post, porém, vai além do básico, mostrando como criar um cluster com Raspberry Pi via software com Docker Swarm e rodar várias instâncias de uma mesma aplicação. Este é basicamente o conceito de nuvem, que permite a escalabilidade de aplicações de maneira horizontal, colocando mais instâncias da mesma em execução.

Docker Swarm

Instâncias?

No post anterior, mostramos a execução de dois containers, um MySQL e um Wordpress. Daquele jeito, apenas uma instância de cada container vai ser executada, o que nos atende muito bem para cenários de teste e de baixo acesso. Mas e se eu quiser utilizar o poder computacional de vários computadores (no nosso caso, placas) para poder melhorar a performance da minha aplicação? Nesse caso, eu teria duas opções: a primeira seria o escalonamento vertical, onde eu aumentaria a memória e processador da minha máquina. Até certo ponto, isso pode me atender, mas se tratando de uma Raspberry Pi, é impossível fazer um upgrade assim…

A outra opção é o escalonamento horizontal, que permite aumentar a quantidade de containers que rodam a aplicação. É chamado de escalonamento horizontal pelo fato de ser uma série de computadores/placas conectados em rede, ocorrendo um balanceamento de carga para cada requisição que chega à aplicação. Na prática, isso permite que um usuário X seja redirecionado para o container Y, enquanto o usuário X2, que acessa a aplicação imediatamente após o usuário X, seja redirecionado para o container Y2, de maneira automática. Utilizando o Docker Swarm (ou outro orquestrador de containers, como Kubernetes), isso é feito sem a necessidade de configurações complexas.

Docker Swarm

Na imagem acima, podemos ter uma visão geral de como vai ficar nosso mini-cluster. Serão três placas formando o cluster com Raspberry Pi, sendo que uma das placas será a versão Raspberry Pi Zero W, e as outras duas, a versão Raspberry Pi 3. Cada uma vai ter uma instalação do Docker, e todas elas vão se comunicar através do Docker Swarm.

Um cluster pra chamar de seu

Recapitulando então, vamos precisar de duas ou mais placas para montar o nosso cluster com Raspberry Pi, sendo que no exemplo agora usarei três. Além disso, é necessário ter o Raspbian Stretch e o Docker instalado em cada uma delas.

curl -sSL https://get.docker.com | sh
sudo usermod -aG docker pi
sudo systemctl enable docker
sudo reboot -h now

Verifique se tudo correu bem com o comando

docker ps

Para ficar mais fácil, cada placa na minha rede possui um IP fixo, 192.168.1.21, 192.168.1.22 e 192.168.1.24. Como estamos lidando com um mini-cluster, cada placa será o mesmo que um “nó” (node) do cluster. Escolha um nó pra ser o “principal” (manager), e os outros dois serão apenas “trabalhadores” (workers). No meu caso, será o nó 192.168.1.21. No nó principal, primeiro vamos baixar a imagem Visualizer, que vai permitir a visualização de nós e containers para cada placa. A imagem foi criada por Alex Ellis, e está disponível no Docker Hub.

docker pull alexellis2/visualizer-arm

Docker Swarm, start!

Iniciar um cluster com Docker Swarm é muito simples. Reiterando, o IP da minha placa principal é 192.168.1.21, e estou executando o seguinte comando nela, através de SSH

docker swarm init --advertise-addr 192.168.1.21

Ele, por sua vez, me retorna a seguinte mensagem de êxito

Swarm initialized: current node (xzkp9uucjrj4ose0yfpcdsjvt) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-4ayyu7shasjzry6j6q007nd3ltal6ett0dxny8nrm0gr21z6be-c6b69sxqjgcpbeetqt4ww4vyg 192.168.1.21:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Para ver os nós que meu cluster agora tem, posso executar o comando

docker node ls

Verificando nós cluster

Hora de subir o container do Visualizer! Note que estou dizendo para o container expor a porta 8080 interna como 8880 externa. Isso significa que, dentro do container, a aplicação de visualização vai rodar normalmente na porta 8080, mas de fora conseguirei acessá-la pela porta 8880.

docker service create --name cluster --publish 8880:8080/tcp --constraint node.role==manager --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock alexellis2/visualizer-arm:latest

Iniciar serviço cluster

Feito isso, meu serviço de visualização já está executando no primeiro nó (manager) do cluster Docker.

Primeiro nó

Com essa imagem podemos ver que, o serviço chamado cluster tem uma instância rodando no nó raspberrypi, do tipo manager. Mas de nada adianta um cluster se ele contém apenas um nó!

Acoplando os nós do cluster com Raspberry Pi

Com o Docker já instalado nas outras duas placas, é hora de fazê-las enxergar o nó principal. Note que, quando inicializamos o Docker Swarm, na mensagem de êxito nos foi passado um comando para adição de outros nós. Iremos executar esse comando em cada um dos outros nós (no meu caso, nos IPs 192.168.1.22 e 192.168.1.24)

docker swarm join --token SWMTKN-1-4ayyu7shasjzry6j6q007nd3ltal6ett0dxny8nrm0gr21z6be-c6b69sxqjgcpbeetqt4ww4vyg 192.168.1.21:2377

Caso dê tudo certo, agora o Visualizer vai exibir os três nós, da seguinte maneira

Três nós online

Temos agora um cluster com três nós, e apenas um container executando! Deixe de lado os nós trabalhadores, e vamos voltar ao nó principal.

Hora do balanceamento de carga

Pelo post anterior, baixamos a imagem do MySQL e do Wordpress, ambas para arquitetura ARM. Agora mudaremos um pouco a estrutura do que criamos anteriormente, removendo o container do Wordpress criado fora do Docker Swarm.

docker container rm wordpress --force

Infelizmente, a versão ARM do MySQL não suporta a execução dentro do Docker Swarm, o que nos limita a apenas uma instância, fora do cluster. Execute o comando docker run normalmente, para ter certeza de que o container do MySQL está executando.

docker run --name mysql-wordpress -e MYSQL_ROOT_PASSWORD=Aa.12345678 -d hypriot/rpi-mysql

Dessa maneira, teremos um container MySQL e cinco containers do Wordpress. Execute o comando a seguir, fazendo com que o Wordpress enxergue o MySQL e conte com cinco instâncias, notando o parâmetro replicas:

docker service create --name wordpress -p 8080:80 -d -e WORDPRESS_DB_HOST=192.168.1.21 -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=Aa.12345678 -e WORDPRESS_DB_NAME=wordpress --replicas 5 wordpress

A mágica acontece quando, tendo três nós interligados, o Docker Swarm consegue balancear cada container para um determinado nó, baseado em sua disponibilidade, de acordo com a imagem a seguir

Cluster com Raspberry Pi

Em caso de apenas um nó, a placa ficaria sobrecarregada com cinco containers rodando ao mesmo tempo (fora o container do Visualizer)

Exemplo somente 1 nó

Um outro comando útil é o scale, que permite escalar o Wordpress em quantos containers sua placa aguentar, ou até reduzir para somente um.

docker service scale wordpress=1

Considerações finais

Como citado acima, a imagem de arquitetura ARM do MySQL não suporta o Docker Swarm. Isso nos deixa com um gargalo forte de banco de dados, pois de nada adianta ter cinco aplicações Wordpress consumindo um único banco de dados. A vantagem seria quando tivéssemos também cinco instâncias de MySQL, contando com replicação entre si.

Gostou do post Cluster com Raspberry Pi e Docker Swarm? Deixe seu comentário logo abaixo.

Faça seu comentário

Acesse sua conta e participe

3 Comentários

  1. Boa tarde, dessa forma todos os Containers terão os arquivos das paginas ? (.php, .html )
    mas estaram utilizando o mesmo banco de dados. Então independende de qual nó eu esteja acessando a pagina, ela vai usar o mesmo banco de dados.

    Teria um exemplo usando tambem a redundancia do banco de dados ?

  2. Não existe ALGUM outro banco que seja compatível com o Swarm na arquitetura ARM?

    1. Oi Roger, boa tarde.

      Existe sim, no DockerHub você pode achar, por exemplo, o Postgres: https://hub.docker.com/_/postgres/
      Ele tem versões pra arm32v5, arm32v7 e arm64v8.

      Acredito que o MongoDB também tenha, mas não versões oficiais. Compensa dar uma olhada se você acha alguma imagem por lá que te atenda.

      Abraços!