Usando o Consul – parte 3

consul-3_ui

Após a segunda parte temos um cluster montado com a ajuda do Vagrant, composto de quatro máquinas virtuais (ou nós) e com um serviço (web, usando o Lighttpd) configurado. Já é o suficiente para permitir a descoberta de serviços, mas ainda falta alguma coisa. Nesta parte serão feitos alguns ajustes nos nós do cluster como adição de criptografia (que será feita em lote através do Vagrant), inclusão das verificações (health checks) e, claro, a ativação da interface web para facilitar algumas tarefas.

Habilitando criptografia

A ideia de adicionar a criptografia é para ficar mais tranquilo (ou menos preocupado) quanto a quem pode entrar o cluster¹. O procedimento em si é relativamente simples e começa pela geração da chave para utilizada o cluster. Isto é feito pelo próprio Consul através do comando keygen:

$ consul keygen
XXXXXXXXXXXXXXXXXXXXXX==

Daí é criar um arquivo JSON para contê-la — a chave ‘encrypt’ é um dos parâmetros utilizados para a configuração do agente.

{ "encrypt": "XXXXXXXXXXXXXXXXXXXXXX==" }

Salvá-lo como “/etc/consul.d/encrypt.json”, matar o agente (usar consul reload não funcionará), reiniciá-lo e repetir o processo tantas vezes quantos forem os nós do cluster…  …parece divertido? Não, nem um pouco! 🙂

A reconfiguração dos quatro nós é chato — fiz uma vez e foi suficiente — imagine então reconfigurar oito, dezesseis ou, sei lá, quarenta nós? Fica mais seguro automatizar o processo e evitar acidentes.

(¹) Novamente lembrando que a comunicação entre os nós se deve fazer em rede privada e e não diretamente em rede pública, correto?

Reconfigurando o cluster

Assim, em uma ramificação (branch) do repositório incluí um script para geração a chave do Consul² já em um arquivo JSON e no diretório correto. E como estava mexendo nos arquivos aproveitei para também consertar um bug no script de inicialização do Consul e ensinar os arquivos usados pelo Vagrant a não fazer as coisas pela segunda vez.

Assim é possível usar o parâmetro “- -provision” do Vagrant para a atualização dos arquivos do cluster sem bagunçar tudo:

$ cd ~/Vagrant/consul
$ git checkout parte-3
$ git pull
$ ./keygen.sh
$ vagrant up --provision

Após a execução é possível verificar pelo arquivo “/var/log/consul.log” que a comunicação entre os nós (via protocolo Gossip) está encriptada agora:

$ vagrant ssh n0
...
vagrant@ns0:~$ cat /var/log/consul.log
...
    Gossip encrypt: true, RPC-TLS: false, TLS-Incoming: false
...

E assim somente os nós configurados com a chave conseguirão fazer parte do cluster.

(²) Usar openssl rand -base64 16 tem o mesmo efeito e não preciso ter a ferramenta instalada só para geração da chave.

Aliás…

Um detalhe sobre o jeito como o Consul faz o gerenciamento dos nós do cluster e que pode parecer que ele não mantêm as informação dos nós, isto é, você adiciona os nós, reinicia os hosts e ao voltar eles não estão mais do cluster!

Acontece que uma vez que o nó sai do cluster — explicitamente via consul leave ou com o encerramento do agente pelo desligamento do host — ele não será automaticamente reconectado pelo agente. Uma forma de corrigir este comportamento é acrescentar o parâmetro “-rejoin” na linha que carrega o agente³ para forçar sua entrada no cluster.

Porém, quando o nó deixa de responder, seu status é marcado como failed (falhou) e voltará para alive (vivo) assim que a comunicação for restabelecida.

(³) Algo que aproveitei para já fazer quando fiz as mudanças para criptografia mas ainda será necessário recolocá-los no cluster usando consul join uma segunda vez.

Verificações

Rotinas para verificação do estado (health check ou simplesmente check — ou seja, a parte de monitoramento) são parte das tarefas realizadas pelo agente do Consul e funcionam tanto uma aplicação (ou serviço) ou para todo o nó.

Definições

Elas são criadas a partir de arquivos JSON e sua estrutura é assim:

{
  "check": {
    "id": "« nome curto que a identifica, é opcional »",
    "name": "« descrição da verificação »",
    "« verificação »": "« valor »",
    "interval": "« intervalo de execução desta rotina »",
    "timeout": "« tempo máximo de execução »"    
  }
}

A chave “verificação” pode ser de uma das seguintes:

  • script : É do tipo mais genérico e será executado o comando definido em “valor”, se o código de retorno for 0 a verificação é considerada com passing (bem sucedida), como 1 como warning (atenção) e qualquer outro valor failing (falhando).
  • http : Verifica o estado de acordo com o protocolo HTTP usando a URL indicada em “valor”, os códigos de retorno 2XX do HTTP são tratados como passing, o erro 429 (a “Too Many Requests”) como warning atenção e os demais como failing.
  • tcp : Testa uma conexão TCP indicada em “valor” — localhost:22 –, aqui os status de retorno são diferentes, success (bem sucedido) caso a conexão seja aceita ou critical (crítico) em caso contrário.
  • ttl : É uma verificação invertida, isto é, ao invés do Consul verificar o estado, que o faz é a aplicação/serviço/etc do outro lado acessando uma URL específica da API do agente para informar que (ainda) está viva, algo como fazer curl localhost:8500/v1/agent/check/pass/« id » regularmente.

Também é possível fazer verificações diretamente dentro de contêineres do Docker mas vou deixá-lo de fora para não complicar muito — mas de forma bem simplificada, funciona tal qual “script” porém com execução dentro do contêiner utilizando a API do Docker.

As verificações podem ser agregadas, bastando usar a chave “checks” e listando-as como elementos de um array:

{
  "checks": [
    {
      "id": "teste1",
      ...
    },
    {
      "id": "teste2",
      ...
    }
    ...
  ]
}

Maiores detalhes sobre as verificações podem ser consultadas na documentação do Consul.

Exemplos

Deixei pré-definidas duas verificações — uma geral chamada “ping” e outra inserida ao serviço “web” (definido na parte 2) — e cujos arquivos foram copiados para dentro dos nós quando eles foram iniciados com o “- -provision”.

A primeira é a “/etc/consul.d/ping.json” (copaida dos exemplos do Consul):

{
  "check": {
    "name": "ping",
    "script": "ping -c1 google.com >/dev/null",
    "interval": "30s"
  }
}

A outra foi colocada dentro da definição do serviço web no arquivo “/etc/consul.d/web.json”:

{
  "service": {
    "name": "web",
    "tags": ["lighttp"],
    "port": 80,
    "check": {
      "http": "http://localhost:80/",
      "interval": "10s"
    }
  }
}

Neste ponto já é possível recuperar as informações e status destas verificações usando a API do Consul:

vagrant@n0:~$ curl localhost:8500/v1/agent/checks
{"ping":{"Node":"n0","CheckID":"ping","Name":"ping","Status":"passing",
"Notes":"","Output":"","ServiceID":"","ServiceName":"","CreateIndex":0,
"ModifyIndex":0},"service:web":{"Node":"n0","CheckID":"service:web","Na
me":"Service 'web' check","Status":"passing","Notes":"","Output":"","Se
rviceID":"web","ServiceName":"web","CreateIndex":0,"ModifyIndex":0}}

Claro que monitorar o cluster assim não é a melhor opção de se trabalhar com o programa exceto, claro, no caso de se estar criando seu próprio frontend para a ferramenta. 🙂

Interface Web

Por padrão ela utiliza o mesmo endereço IP usado pelo cliente do Consul (no caso, a interface localhost) e para não fazer muito malabarismo vou recorrer ao rinetd para redirecionar as requisições para ela.

A instalação do rinetd é simples:

vagrant@n0:~$ sudo apt-get install rinetd
...
Unpacking rinetd (from .../rinetd_0.62-5.1_amd64.deb) ...
Processing triggers for man-db ...
Setting up rinetd (0.62-5.1) ...
Starting internet redirection server: rinetd.

E a configuração também, basta acrescentar o seguinte no arquivo “/etc/rinetd.conf”:

...
    allow 172.20.20.*
...
    172.20.20.10    8500    127.0.0.1    8500
...

Então salvar o arquivo, reiniciar o serviço, acessar em 172.20.20.10:8500/ui do seu navegador web — sim, poderia ter feito o mesmo com iptables mas assim é bem mais rápido.

Consul-3_UI-início.png

Agora o cluster está realmente pronto para ser testar a monitoração:

$ vagrant suspend n1 n3
==> n1: Saving VM state and suspending execution...
==> n3: Saving VM state and suspending execution...
$ vagrant ssh n2
...
vagrant@n2:~$ sudo service lighttpd stop
[ ok ] Stopping web server: lighttpd.

E o resultado será algo mais ou menos assim:

consul-3_ui-failing

As verificações estão funcionando (ou quase) e pode-se usar vagrant halt para desligar o cluster agora.

Fim da terceira parte

Por enquanto é só, na próxima parte vamos dar alguma assimetria ao cluster colocando certos serviços em execução em determinados nós, utilizando repositório de dados chave/valor do Consul e, claro, adicionando mais um nó só para ver o que acontece.

Até! 🙂

Anúncios

2 comentários sobre “Usando o Consul – parte 3

  1. Pingback: Usando o Consul – parte 3 - Linux em Ação XYZ

  2. Pingback: Usando o Consul – parte 4 | giovannireisnunes

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s