Conforme explicado no capítulo de arquitetura, o Embrapa I/O é uma plataforma do tipo Cloud Agnostic Architecture. Ou seja, se propõe a atuar com diferentes tecnologias de conteinerização e clusterização em nuvem, às quais são aqui chamadas de “orquestradores”.

Assim, é possível que uma aplicação, devidamente conteinerizada, seja instanciada em estágio alpha (para testes internos) em um orquestrador Docker Swarm rodando em um cluster de servidores localizado fisicamente na Embrapa Gado de Corte. A mesma aplicação poderia ser instanciada em estágio beta (para testes externos) em um orquestrador Kubernetes rodando em um cluster de servidores localizado fisicamente na Embrapa Agricultura Digital. Por fim, esta mesma aplicação poderia estar instanciada em estágio release (produção) em um orquestrador Cloud Foundry rodando na IBM Cloud.

Para possibilitar a “orquestração” dos ativos digitais nesta rede descentralizada de clusters, a plataforma implementa drivers de serviços. Estes drivers podem ser de dois tipos:

  • orquestrador: que efetua tarefas de validação dos stacks de containers, deploy/undeploy, health check, backup, sanitização, etc; e

  • storer: que instancia volumes no próprio cluster ou em servidores externos do tipo storage.

O provisionamento de novos clusters, storers e o desenvolvimento de drivers, estão alinhados com a estratégia de desenvolvimento colaborativo e manutenção compartilhada da plataforma. Assim, da mesma forma que ocorre com os boilerplates, clusters são mantidos por equipes descentralizadas, que podem ser internas ou externas à Embrapa.

Detalhes do cluster escolhido para deploy da aplicação

Desta forma, unidades descentralizadas, instituições e empresas parceiras da Embrapa podem compor a rede de clusters do Embrapa I/O, integrando servidores reais ou VMs de seus próprios CPDs. Com isso, a gestão das aplicações nestes servidores físicos ou máquinas virtuais passa a ser realizada pelos processos de DevOps da plataforma.

Atenção! Os processos automatizados de backup nos clusters são de atribuição da equipe de mantenedores, sendo que o Embrapa I/O aborda apenas o backup sob demanda, já detalhado anteriormente. Da mesma forma, recursos essenciais adicionais, tal como envio de e-mail (SMTP) devem ser disponibilizados na rede interna em que o servidor está instalado e devidamente informado na documentação do cluster.

Para realizar a integração, os mantenedores deverão configurar as máquinas, reais ou virtuais, conforme a instrução para o orquestrador e storer escolhido. Na próxima seção, são listados os drivers já disponíveis para criação de clusters. Para diversos destes drivers o Embrapa I/O realiza a conexão via SSH. Portanto é necessário, quando for este o caso, liberar no firewall o acesso do IP 200.202.148.38 na porta 22 do servidor e adicionar a seguinte chave pública no arquivo /root/.ssh/authorized_keys:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCykAvX7CZmqw1bgOCOmRtgpfr55cjqO0v1+DImp4pKrITdFxZu0OqsJgHjio/yp4w5+KvWmFJa5woYbZry9inFciwKo3+rpGjBHJfNfDq70/q3VdSSInFrSMtWgBk0x5QZQ78ENkNkO9DRIdnnffN9bY1uibR6ZX0pCSSyTGgx3NlAakW47tYIzVcrrUGKGG8vZwSkl7GhEEXtNETp02WQpkUvYrNqgRrmw2lvv41QfRETIuNN7PDhJrDO4tYHtix5D+Pvd05IacgTVQxpi6vnMVdgrwbZ1RPw9TLLkoy3kZs45hLG9oipiYOiD6rxiIYC0f1iUaKz9PKZdfnF8Ya5XJFoL6NcBTPDGh01dkEBonOWt3lgpC/2SBM/SeClt8M2lI6KtqAkjPEKWhnirDP0lXzY2CYamnu2rD6p4z4OWAYG6ngQcCIK45vQvsSz8mfitWnJe89WCCaEVj+L1QO/hjnKJ+eKf5ze35HagFRhpIAB34FmGHO3N8yFCLqvHFNLw6dKl5IXU2cvJF1jwhL3coOx9oeFZLPk45Zze2e/Itjd9x84gWtmo60MvXVBsYGYlcZLzSgAbNGldMuxAFWs0ZvghNx+KZjg6fZ2hAlPHIg1MiAlztyLbbjV2Mjc6ke6sjBDvPkPZQde6G/T8Mp56cCtAb/77/dw78zruX5qyQ== embrapa.io

Além disso, o Embrapa I/O expõe as aplicações instanciadas em portas na faixa de 49152 a 65535. Portanto, toda esta faixa de portas deverá ser exposta para acesso público nos servidores de aplicação que compõem o cluster (p.e., todos os nós managers e workers no Docker Swarm).

Atenção! Existe um limite de 30 projetos para cada cada cluster do Embrapa I/O. Este limite está relacionado ao limite padrão do Docker, onde um único host não deve possuir mais do que 30 networks. É possível contornar esta limitação, mas visando manter uma complexidade comedida da gestão das VMs, sugere-se mantê-lo. É importante frisar que o número de aplicações em cada projeto e de containers em cada aplicação não é limitado pela plataforma e, portanto, ficará a cargo das limitações de hardware, sistema operacional e outros recursos escassos, tal como a quantidade máxima de portas expostas em cada cluster (16.383).

Adicionalmente, é fortemente recomendado que seja instalado o Portainer para auxiliar a equipe mantenedora de clusters em Docker Compose, Docker Swarm ou Kubernetes em sua gestão. Por padrão, recomenda-se que este seja disponibilizado publicamente no HTTPS (porta 443) da URL do cluster, com o HTTP (porta 80) redirecionando para o HTTPS.

Para simplificar a instalação e recorrente atualização do Portainer (quando necessário), crie um script denominado /root/portainer.sh com as seguintes instruções:

#!/bin/sh

type docker > /dev/null 2>&1 || { echo >&2 "Command 'docker' has not found! Aborting."; exit 1; }

set -x

set +e

docker stop portainer

docker rm portainer

docker volume create portainer_data

set -e

docker pull portainer/portainer-ce:latest

docker run -d -p 8000:8000 -p 9443:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest

Além disso, instale o Nginx e, para a configuração acima do Portainer, especifique um novo site como segue (troque io.cnpxx.embrapa.br pelo nome correto do seu cluster):

server {
  listen 80;
  listen [::]:80;

  server_name io.cnpxx.embrapa.br;

  return 301 https://io.cnpxx.embrapa.br;
}

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  ssl_certificate /etc/embrapa/wildcard/io.cnpxx.embrapa.br/fullchain.pem;
  ssl_certificate_key /etc/embrapa/wildcard/io.cnpxx.embrapa.br/privkey.pem;
  ssl_trusted_certificate /etc/embrapa/wildcard/io.cnpxx.embrapa.br/fullchain.pem;
  ssl_protocols TLSv1.2 TLSv1.3;

  server_name io.cnpxx.embrapa.br;

  location / {
    resolver 127.0.0.1 [::1];
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Access-Control-Allow-Origin '*';
    proxy_set_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, DELETE, HEAD';
    proxy_cache_bypass $http_upgrade;
    proxy_ssl_session_reuse off;
    proxy_pass http://localhost:9443;
  }
}

Orquestradores e Storers Homologados

Docker Compose

Para instalação do orquestrador em Docker Compose é necessário disponibilizar um único servidor dedicado (bare metal) ou máquina virtual. É recomendado o uso da distribuição Linux Debian 12 Bookworm ou Linux Ubuntu Server 22.04 LTS. É necessário que seja utilizada a arquitetura amd64. No momento da instalação do SO, haverá a possibilidade de instalar pacotes adicionais. Neste momento, selecione o SSH Server e o Docker.

Atenção! É fortemente recomendado efetuar o login no Docker utilizando uma conta institucional. O uso do Docker não-autenticado pode resultar em erros durante o processo de deploy (p.e., Temporary failure in name resolution).

Pacote do Docker selecionado para instalação

Adicione a chave pública SSH da plataforma Embrapa I/O no arquivo /root/.ssh/authorized_keys, conforme mencionado na seção inicial desta página. Agora será necessário configurar um storer associado ao cluster, que é o servidor físico onde serão armazenados os volumes utilizados pelos containers para persistir dados:

  • DockerLocal: Caso não haja uma VM ou um servidor do tipo storage disponível, que seria o equipamento mais apropriado, é possível configurar um storer local. Na prática será um diretório no próprio cluster onde todos os volumes serão criados fisicamente. Para isto, basta criar um diretório em qualquer local no servidor e atribuir permissões de escrita.

  • DockerNFSv4: Havendo uma VM ou servidor físico de storage disponível, os mantenedores poderão instalar e/ou habilitar o NFS (versão 4) nele. Assim como no caso do cluster, é necessário também configurar a chave SSH pública da plataforma no usuário root. É importante que no arquivo /etc/exports sejam parametrizados, pelo menos, as seguintes opções no diretório a ser montado: rw, no_root_squash, sync, no_subtree_check e insecure.

É fortemente recomendado ajustar alguns parâmetros do Linux (sysctl). Normalmente estes parâmetros são ajustados editando o arquivo /etc/sysctl.d/99-sysctl.conf (ou diretamente o /etc/sysctl.conf em distribuições mais antigas). Considere os seguintes parâmetros e correspondentes valores mínimos:

fs.file-max=98000
kernel.pid_max=64000
kernel.threads-max=64000
vm.max_map_count=262144

Docker Swarm

Para instalação do orquestrador em Docker Swarm é necessário disponibilizar três ou mais servidores dedicados (bare metal) ou máquinas virtuais. Em cada uma delas deverá ser instalado, preferencialmente, a distribuição Linux Debian 12 Bookworm ou Linux Ubuntu Server 22.04 LTS. É necessário que seja utilizada a arquitetura amd64. No momento da instalação do SO, haverá a possibilidade de instalar pacotes adicionais. Neste momento, selecione o SSH Server e o Docker. Siga os passos da seção anterior para instalar também o Docker Compose em sua versão mais recente em cada um dos servidores que compõem o cluster.

Atenção! É fortemente recomendado efetuar o login no Docker utilizando uma conta institucional. O uso do Docker não-autenticado pode resultar em erros durante o processo de deploy (p.e., Temporary failure in name resolution).

Adicione a chave pública SSH da plataforma Embrapa I/O no arquivo /root/.ssh/authorized_keys de todos os nós do cluster, conforme mencionado na seção inicial desta página.

Para instalar o Docker Swarm, siga os passos da documentação oficial. Você deverá definir a quantidade de servidores que atuará como manager nodes e como worker nodes. Considere a orientação da docuemntação oficial para otimizar a tolerância à falhas, onde o número de managers deverá ser sempre ímpar. Assim, caso tenha 4 servidores/VMs em seu cluster, considere criar 3 manager nodes e 1 worker node. Por fim, adicione todos os nós ao swarm.

Todo cluster Docker Swarm deverá possuir um servidor para registro de imagens (Docker Registry) rodando localmente na porta padrão. Ele será utilizado para registrar as imagens buildadas em tempo de deploy das aplicações. Para criá-lo no swarm, faça:

docker service create --name registry --publish published=5000,target=5000 registry:2

Configure agora um storer associado ao cluster, que é o servidor físico onde serão armazenados os volumes utilizados pelos containers para persistir dados:

  • SwarmNFSv4: Será necessário ter um servidor de storage dedicado ao cluster em Docker Swarm. Nele, os mantenedores deverão instalar e/ou habilitar o NFS (versão 4). Assim como no caso dos nós do cluster, é necessário também configurar a chave SSH pública da plataforma no usuário root. É importante que no arquivo /etc/exports sejam parametrizados, pelo menos, as seguintes opções no diretório a ser montado: rw, no_root_squash, sync, no_subtree_check e insecure. Todos os nós do cluster devem ser capazes de montar o storage NFS.

Backup e Limpeza do Cache

Para backup periódico do cluster, além dos processos e protocolos existentes no data center em que está alocado, recomenda-se configurar um schedular job diário utilizando a ferramenta docker-backup. Uma vez instalada e devidamente adicionada ao path do sistema operacional, crie um arquivo .sh com o seguinte conteúdo:

#!/bin/sh

HOSTNAME=$(hostname)

echo "Starting embrapa.io backup process to $HOSTNAME..."

type docker > /dev/null 2>&1 || { echo >&2 "Command 'docker' has not found! Aborting."; exit 1; }

type docker-backup > /dev/null 2>&1 || { echo >&2 "Command 'docker-backup' has not found! See: https://github.com/muesli/docker-backup. Aborting."; exit 1; }

set -e

BKP_PATH="/var/opt/embrapa.io/backup"

mkdir -p $BKP_PATH

[ ! -d $BKP_PATH ] && echo "$BKP_PATH does not exist." && exit 1

BKP_FOLDER="io_cluster_$(date +%Y-%m-%d_%H-%M-%S)"

echo "Deleting old backups (older than 7 days)..."

find $BKP_PATH -type f -name "*.tar.gz" -mtime +7 -exec rm {} \;

echo "Creating backup folder: '$BKP_FOLDER'..."

mkdir -p $BKP_PATH/$BKP_FOLDER/$HOSTNAME

set +e

echo "Starting Docker backup process with 'docker-backup' to all containers..."

cd $BKP_PATH/$BKP_FOLDER/$HOSTNAME

docker-backup backup --all --stopped --tar --verbose

set -e

echo "Compressing backup folder..."

cd /tmp

tar -czvf $BKP_PATH/$BKP_FOLDER.tar.gz -C $BKP_PATH $BKP_FOLDER

rm -rf $BKP_PATH/$BKP_FOLDER

echo "All done! Backup file at: $BKP_PATH/$BKP_FOLDER.tar.gz"

echo "Clean up unused images..."

docker builder prune -af --filter "until=24h"

docker image prune -af --filter "until=24h"

Adicione este arquivo no CRON para ser executado diariamente. Por exemplo, se foi criado um arquivo /root/embrapa.io/backup/cluster.sh, crie um script /etc/cron.daily/io com o seguinte conteúdo:

#!/bin/sh

find /var/log -type f -name "embrapa.io*" -mtime +14 -exec rm {} \;

DATE="$(date +%Y-%m-%d)"

/root/embrapa.io/backup/cluster.sh >> /var/log/embrapa.io-cluster-$DATE.log 2>&1

Em seguida, faça:

chmod +x /root/embrapa.io/backup/cluster.sh
chmod +x /etc/cron.daily/io

/etc/init.d/cron reload

É importante notar as linhas finais do script de backup, onde aparecem os comandos:

echo "Clean up unused images..."

docker builder prune -af --filter "until=24h"

docker image prune -af --filter "until=24h"

O processo de build do Docker gera uma imensa quantidade de imagens e outros arquivos de cache. Isto tende a ocupar rapidamente todo o espaço em disco. Estes comandos garantem que este cache não tenha mais do que 24 horas.

Uma vez configurado o cluster, basta montar as configurações em formato JSON e enviar para a equipe de gestão da plataforma. O exemplo abaixo demonstra como deverão ser as configurações:

{
  "release": [
    {
      "host": "io.facom.ufms.br",
      "local": "Faculdade de Computação da UFMS",
      "location": "Campo Grande - MS",
      "orchestrator": "DockerCompose",
      "storage": {
        "type": "DockerNFSv4",
        "host": "storage.facom.ufms.br",
        "path": "/mnt/nfs"
      },
      "aliases": [
        "releases.facom.ufms.br",
        "agro.facom.ufms.br",
        "farm.facom.ufms.br",
        "live.facom.ufms.br",
      ],
      "disabled": false,
      "maintainers": [
        { "name": "Hercule Poirot", "email": "hercule.poirot@ufms.br", "phone": "+55 (67) 9 8888-7777" },
        { "name": "Maria Capitolina Santiago", "email": "capitu.santiago@ufms.br", "phone": "+55 (67) 9 6666-5555" }
      ]
    },
    {
      "host": "cluster.cnpgc.embrapa.br",
      "nodes": {
        "manager": [
          "manager1.cnpgc.embrapa.br",
          "manager2.cnpgc.embrapa.br"
        ],
        "worker": [
          "worker1.cnpgc.embrapa.br"
        ]
      },
      "local": "Embrapa Gado de Corte",
      "location": "Campo Grande - MS",
      "orchestrator": "DockerSwarm",
      "storage": {
        "type": "SwarmNFSv4",
        "host": "storer.cnpgc.embrapa.br",
        "path": "/swarm"
      },
      "aliases": [
        "app.cnpgc.embrapa.br",
        "manager.cnpgc.embrapa.br",
        "api.cnpgc.embrapa.br",
        "portal.cnpgc.embrapa.br"
      ],
      "disabled": false,
      "maintainers": [
        { "name": "Dorothy Gale", "email": "dorothy.gale@embrapa.br", "phone": "+55 (67) 3368-1122" },
        { "name": "Bras Cubas", "email": "bras.cubas@embrapa.br", "phone": "+55 (67) 3368-3344" },
        { "name": "Tyler Durden", "email": "tyler.durden@embrapa.br", "phone": "+55 (67) 3368-5566" }
      ]
    }
  ],
  "beta": [
    {
      "host": "io.facom.ufms.br",
      "local": "Faculdade de Computação da UFMS",
      "location": "Campo Grande - MS",
      "orchestrator": "DockerCompose",
      "storage": {
        "type": "DockerNFSv4",
        "host": "storage.facom.ufms.br",
        "path": "/mnt/nfs"
      },
      "aliases": [
        "test.facom.ufms.br",
        "beta.facom.ufms.br"
      ],
      "disabled": false,
      "maintainers": [
        { "name": "Hercule Poirot", "email": "hercule.poirot@ufms.br", "phone": "+55 (67) 9 8888-7777" },
        { "name": "Maria Capitolina Santiago", "email": "capitu.santiago@ufms.br", "phone": "+55 (67) 9 6666-5555" }
      ]
    }
  ],
  "alpha": [
    {
      "host": "io.facom.ufms.br",
      "local": "Faculdade de Computação da UFMS",
      "location": "Campo Grande - MS",
      "orchestrator": "DockerCompose",
      "storage": {
        "type": "DockerLocal",
        "path": "/mnt/storer"
      },
      "aliases": [
        "sandbox.facom.ufms.br",
        "alpha.facom.ufms.br"
      ],
      "disabled": false,
      "maintainers": [
        { "name": "Hercule Poirot", "email": "hercule.poirot@ufms.br", "phone": "+55 (67) 9 8888-7777" },
        { "name": "Elizabeth Bennet", "email": "elizabeth.bennet@ufms.br", "phone": "+55 (67) 9 4444-3333" },
        { "name": "Fitzwilliam Darcy", "email": "fitzwilliam.darcy@ufms.br", "phone": "+55 (67) 9 2222-1111" }
      ]
    }
  ]

Repare que o cluster deve ser configurado especificamente para cada estágio da aplicação. Assim, ele pode estar disponível para os estágios alpha, beta e/ou release, ou seja, não necessariamente para todos. O host deverá apontar para o IP real do servidor ou VM. Os atributos local e location indicam a Unidade da Embrapa, instituição ou empresa e a sua localização geográfica.

O orchestrator indica o driver de orquestração que está sendo utilizado. No exemplo acima, o cluster io.facom.ufms.br está configurado com o orquestrador Docker Compose e, portanto, é composto por um único servidor. Já o cluster cluster.cnpgc.embrapa.br está configurado com o orquestrador Docker Swarm e é, portanto, composto por diversos nós. Neste caso, no atributo host deverá ser referenciado um manager node principal, que no nosso exemplo é o cluster. No atributo node estão declarados explicitamente os demais nós, sendo manager1 e manager2 como manager nodes e worker1 como um worker node, totalizando assim os 4 (quatro) nós que formam o cluster.

O atributo storage contém o driver de storer e atributos relacionados. Por exemplo, para o estágio alpha foi configurado um storer utilizando o driver DockerLocal e, desta forma, os volumes serão criados no diretório /mnt/storer indicado no atributo path. Já em estágio beta e release está sendo utilizado o driver para NFSv4 e, desta forma, os volumes serão criados fisicamente no diretório remoto /mnt/nfs do storage storage.facom.ufms.br.

Os aliases são subdomínios configurados pela Unidade da Embrapa, instituição ou empresa parceira que possibilitam alocar as aplicações em domínios mais condizentes semânticamente com a sua finalidade. Estes aliases devem ser configurados no DNS da seguinte forma:

  1. Para cada alias, crie um registro do tipo CNAME apontando para router.embrapa.io; e
  2. Para cada alias, crie um wildcard subdomain (registro do tipo A) apontando para o IP do router.embrapa.io (ou seja, 200.202.148.38).

Assim, para um alias app.cnpgc.embrapa.br, teríamos:

Name                      Type     Value
----------------------    -----    -----------------
app.cnpgc.embrapa.br      CNAME    router.embrapa.io
*.app.cnpgc.embrapa.br    A        200.202.148.38

Vale ressaltar que as aplicações instanciadas estarão sempre expostas por meio das portas atribuídas a elas em cada cluster. Em clusters com múltiplos nós (nodes), as réplicas em cada nó poderão ser acessadas de forma distinta pelo endereço real do nó e porta específica. O load balancer será automaticamente ativado quando um alias, URL externa ou subpath for configurado. Para isso, é utilizado o método least connected do Nginx, onde a próxima solicitação é atribuída ao servidor com o menor número de conexões ativas.

Caso o atributo disabled esteja setado como true, o cluster não aceitará novos deploys naquele cluster para aquele estágio específico (ou seja, ele pode estar disabled para o estágio release, mas não para alpha e beta), porém as builds já instanciadas continuarão sendo geridas normalmente (inclusive recebendo deploys de novas tags). Por fim, é possível estabelecer grupos diferentes de mantenedores para o cluster em cada estágio.