Dockerizando sua infra com Docker Swarm e IBM Cloud Virtual Server – IBM Developer

Dockerizando sua infra com Docker Swarm e IBM Cloud Virtual Server

IBM Virtual Servers

Por que usar Containers

Containers permitem executarmos com isolamento e de maneira leve nossa aplicação em diversos ambientes. Ou seja, usando um empacotador como Docker, nos podemos envelopar nossa aplicação de maneira que ela fique leve e funcione não só na sua máquina mas em qualquer ambiente que possua Docker.

Além disso, com o uso dos orquestradores de containers podemos escalar, gerenciar e implementar rotinas de DevOps facilmente na nossa infraestrutura. Dois orquestradores comuns no mercado atualmente são Swarm e Kubernetes. Para saber os prós e contras de cada tecnologia recomendo ler o post:

Docker Swarm vs. Kubernetes: A Comparison – IBM Cloud Blog Docker Swarm vs. Kubernetes: Which is the right container orchestrator for you?

Kubernetes é um orquestrador open source muito utilizado no mercado e já validado por vários grandes players, porém possui uma curva de aprendizado maior que Swarm que por sua vez já vem embarcado no Docker e não deixa a desejar na orquestração dos nossos containers. Vamos ver abaixo como montar um ambiente na sua infraestrutura para rodar Swarm.

Arquitetura que vamos usar

Para montar nossos clusters vamos usar 4 Virtual Servers sendo um para nosso Load Balancer e 3 para nossa Aplicação. Mas agora, vamos entender o porque dessa decisão:

  • Por padrão o swarm considera cada Virtual Server do cluster como Node, e todos os Nodes podem acessar a aplicação. Por esse motivo, não há balanceamento de requisições entre os Nodes, se fazendo necessário o uso de um proxy acima do cluster da aplicação para balancear a carga entre nossos Nodes.
  • O Swarm nos permite definir nossos Virtual Servers como Managers ou Workers. Nesses tutorial vamos usar um manager e 2 workers. Lembrando que para uma maior disponibilidade é recomendando possuir mais Nodes no Cluster, ou seja,mais Virtual Servers. Veja o link abaixo para saber qual o número recomendado e porque:

Administer and maintain a swarm of Docker Engines When you run a swarm of Docker Engines, manager nodes are the key components for managing the swarm and storing the…

Veja abaixo como ficou nossa arquitetura de máquinas:

Diagrama do Cluster 1 e Cluster 2

Vamos conectar nossas máquinas usando IP Privado, ou seja, a comunicação entre elas será mais segura e sem acesso público, sendo que a única máquina com acesso público será nosso Load Balancer.

Quando usamos Docker Swarm para orquestrar nossos containers usamos o conceito de service para rodar nossa aplicação. Os services são responsáveis por gerenciar os componentes de nossa aplicação, eles são por sua vez gerenciados pelo Node Manager e já contam com um Load Balancer para balancear a carga entre os containers. Nessa demonstração vamos usar os seguintes serviços:

Demonstracao de services

Esses services vão definir a estrutura de nossa aplicação, como mostrado na imagem acima, para garantir uma segurança maior vamos colocar redes diferentes para cada service.

Lembrando que em cada service estipulamos a quantidade de replicas (containers) que irão executar essa função. E essas replicas serão automaticamente espalhadas pelo nosso cluster e gerenciadas para seguirem as especificações iniciais que demos, ou seja, caso um dos containers sofra alguma falha e pare de executar, o Swarm por meio do node manager irá cuidar para que essa situação seja corrigida. Além disso, com simples comandos podemos aumentar/diminuir a quantidade de replicas ou atualizar a versão de um dos nossos serviços.

Abaixo, vamos ver como criar, conectar e gerenciar essa arquitetura.

Criação dos Virtual Servers

Para criarmos os Virtual Servers precisamos primeiro possuir um cadastro na IBM Cloud, para isso basta acessar:

Sign up for IBM Cloud

Clicar em Catalogo

Figura 4. Clicar em Catálogo

Selecione Cálculo e depois Virtual Server

Figura 5. Selecione Cálculo e depois Virtual Server

Após isso, você pode configurar sua instância como deseja, ou seja, escolhendo o virtual server que mais se encaixa com sua necessidade. No meu cluster irei utilizar máquinas públicas padrões com Sistema Operacional Ubuntu.

O processo de criação das máquinas demora alguns minutos. Após criar todas as instâncias necessárias, você poderá ver suas máquinas no Dashboard:

Clique na Logo da IBM Cloud e depois em visualizar todos recursos e vera suas Máquinas

Figura 6. Clique na Logo da IBM Cloud e depois em visualizar todos recursos e vera suas Máquinas

Se conectando as Máquinas Virtuais

Para gerenciarmos nossas máquinas, vamos nos conectar a elas usando SSH. Para fazer isso, basta selecionar uma das instâncias no seu dashboard e seguir os passos abaixo:

Selecione Passwords

Figura 7. Selecione Passwords

De dois cliques em Password e copie a senha

Figura 8. De dois cliques em Password e copie a senha

Agora usando um terminal na sua máquina rode o seguinte comando (lembre de usar o IP público para realizar essa conexão):

ssh root@IP_PUBLICO
# na primeira conexão irá ser feita uma pergunta: indique Sim
# coloque a Senha copiada na seção acima

Após realizar a conexão você está conectado com seu Virtual Server.

Instalando Requisitos

Logo após conectarmos nos nossos Virtual Servers temos que instalar o Docker(em todas as instâncias) para conseguirmos rodar os comandos relacionados ao Swarm. Veja como é a instalação abaixo:

curl -fsSL https://get.docker.com -o get-docker.sh
bash get-docker.sh
docker version

Instalando o docker

Por padrão o Docker já vem embarcado com Swarm, nas próximas nos vamos ver como ativar esse modo para gerenciar nosso cluster.

Configurando Cluster da Aplicação

Selecione um Virtual Server para ser Manager desse cluster, e após isso execute o código abaixo:

docker swarm init --advertise-addr <IP_PRIVADO_DESSE_VIRTUAL_SERVER>

Após executar esse comando você irá receber um comando para adicionar outros Virtual Servers no cluster. Agora vamos nos conectar com os outros 2 Virtual Servers e executar o comando que recebemos, veja abaixo a estrutura desse comando:

docker swarm join \
       <TOKEN_GERADO_NO_SWARM_INIT> \
       <IP_PRIVADO_DO_MANAGER>:<PORTA_DO_MANAGER>

Após adicionar todos os Virtual Servers, podemos agora controlar tudo pela nossa instância Manager. Para confirmar que tudo ocorreu de forma correta execute:

docker node ls
# lista de nós no cluster

Lista de virtual servers

Se a lista de Virtual Servers aparecer, então podemos continuar, caso não repita os passos acima.

Agora vamos criar nossas duas networks, assim como descrito no diagrama:

  • Network 1: irá conectar o frontend e o backend.
  • Network 2: irá conectar o backend com o Banco de Dados.

Para criar uma network use o seguinte comando:

docker network create <NOME_DA_NETWORK> \
                    --driver overlay
docker network ls
# lista todas networks no sistema

Lista de networks

Nesse caso é importante criamos as networks com driver overlay, pois é ele que nos possibilita comunicação dos services mesmo em que eles tenham containers rodando em Virtual Servers diferentes. Para validar que tudo ocorreu bem, você deve ver na lista de networks as 2 redes que você acabou de criar.

Vamos criar nossos serviços agora. Para começar, vamos criar nosso banco de dados, que nesse caso será o MongoDB:

docker volume create --name database
docker service create --name mongo \
                  --replicas 1 \
                  --network net-2 \
                  --mount type=volume,source=database,destination=/data/db \
                  --constraint='node.role == worker' \
                  mongo

Nesse caso, criamos um serviço de nome ‘mongo’ que terá um container de mongoDb executando. Além disso, ele estará conectado na network ‘net-2’, irá armazenar os dados no volume database e esse serviço irá criar containers somente no Nodes (Virtual Servers) que possuem a função ‘worker’.

Vamos criar agora nosso serviço de backend:

docker service create --name backend \
                  --replicas 2 \
                  --network net-2 \
                  --network net-1 \
                  --constraint='node.role == worker' \
                  pedrohlcastro/swarm-todo-backend

Nesse caso, vamos usar uma imagem armazenada no docker hub, porém vale lembrar que você poderia também usar o repositório privado de imagens da IBM Cloud:

Container Registry – Overview IBM Container Registry enables you to store and distribute Docker images in a managed, private registry.

Nosso serviço se chamara ‘backend’, tera dois containers em execução, estará conectado as networks: net-1 e net-2. E assim como no outro caso ele irá criar os containers nos Nodes(Virtual Servers) que tem como função ‘worker’.

E para finalizar o deploy de nossa aplicação vamos criar o último service que será o frontend:

docker service create --name frontend \
                  --replicas 5 \
                  --network net-1 \
                  --constraint='node.role == worker' \
                  -p 80:4200 \
                  pedrohlcastro/swarm-todo-frontend

Nesse caso, temos uma configuração similar ao que usamos nos outros dois serviços, porém dessa vez publicamos nosso serviço na porta 80, dessa forma se acessarmos o IP de qualquer máquina dentro do nosso cluster vamos ver o frontend de nossa aplicação. Porém, como foi explicado anteriormente, queremos que a carga em nossos Virtual Servers seja balanceada e ainda não possuímos essa função (vamos criar na próxima seção).

Para acessar o repositório da aplicação e acessar as imagens usadas:

pedrohlcastro/swarm-todo Contribute to pedrohlcastro/swarm-todo development by creating an account on GitHub.

Docker Hub

Outra abordagem para o deploy desses serviços é usar um arquivo docker-compose, esses arquivos já são bastante utilizados em ambientes de desenvolvimento e com a adição de algumas tags pode ser facilmente portado para o ambiente de produção usando docker swarm com o comando:

docker stack -c <seu_arquivo_compose>

Vamos agora na próxima seção configurar nosso Load Balancer.

Configurando Cluster Load Balancer

Para configurar esse Cluster vamos seguir passos similares aos feitos anteriormente, mas lembre que você deve se conectar ao Virtual Server que irá ser responsável pelo balanceamento de carga e após isso:

docker swarm init --advertise-addr <IP_PRIVADO_DESSE_VIRTUAL_SERVER>

Para realizar essa tarefa de balancear a carga entre os Nodes vamos usar o servidor Nginx. Para isso, vamo criar nosso arquivo de configuração do Nginx:

mkdir -p /config/

cria uma pasta config no seu Virtual Server

nano /config/default.conf

usando seu editor favorito abra um arquivo default.d

Agora basta colar a configuração abaixo:

server {
   listen 80;
   location / {
      proxy_pass http://backend;
   }
}
upstream backend {
   server <node0 private IP>:80;
   server <node1 private IP>:80;
   server <node2 private IP>:80;
}

Lembre-se que temos que modificar os parâmetros <node private IP> com os IP’s privados dos Virtual Servers que compõem o cluster da aplicação.

Se tudo deu certo você irá conseguir ver o frontend a partir do IP público do nosso Virtual Server responsável pelo Load Balancer.