/devops

Deploy Time Series API

Primary LanguageRuby

DevOps Deploy Time Series API

Este projeto tem como objetivo o estudo de caso de um sistema distribuído utilizando o Kubernetes como plataforma. Esta aplicação expõe uma API REST e recebe um JSON como payload, por exemplo:

{
	"component": "postman",
	"version": "v0.1.2",
	"author": "Boaventura Rodrigues Neto",
	"status": "Success"
}

Alimentando uma base de dados Redis para acompanhamento do intervalo de tempo entre deploys e seus status.

Requisitos

Este projeto foi desenvolvido localmente em um sistema macOS 10.12 tendo como requisitos as seguintes ferramentas:

VirtualBox

Homebrew

Docker for Mac

Postman

Sobre o container Docker

A criação do container é feita utilizando a recomendação de seguir a order dos comandos visando colocar o conteúdo mais provável de alteração para o fim e juntando os comandos que alteram o conteúdo de maneira acentuada, de forma a minimizar o crescimento desnecessário da imagem. O build da imagem está sendo feito automaticamente com a integração entre o Github e o Docker Hub, fazendo proveito deste facilidador para ter algo de CI desde já. A aplicação está também passando por um processo de lint fazendo uso da ferramenta Rubocop com um hook no pre-commit do git. Caso queira fazer um fork deste projeto e não utilizar o Rubocop, você deve fazer o commit sem verificação: git commit --no-verify .

Preparando o ambiente

Estamos utilizando o Kubernetes como plataforma para demonstrar o estado da arte em automação de infraestrutura. O Kubernetes é uma ferramente que representa o que há de melhor em operação de TI. Aqui podemos unificar todo nosso conhecimento de automação, gerenciamento de configuração, provisionamento e orquestração de containers em um só lugar. Ele utiliza uma linguagem declarativa no formato YAML, e também pode ser utilizado de maneira imperativa com a CLI kubectl. No meu ponto de vista isso significa que ele unifica alguns dos melhores aspectos de duas das melhores ferramentas de administração de sistemas do mundo: Terraform e Ansible.

Primeiramente para interagir com o Kubernetes precisamos do kubectl, vamos instalá-lo:

brew install kubectl

O Kubernetes é implementado pelos mesmos princípios que habilitam o Google a executar bilhões de containers por semana, mas também é fantástico como ele poder fazer o scale down e ser executado em nossa estação de trabalho, através do Minikube.

Instalando o minikube:

brew cask install minikube

Iniciando o minikube:

minikube start

Todos os testes foram feitos utilizando o kubectl 1.7.5 e o minikube 1.7.5, isso pode ser verificado com o comando:

kubectl version

Atente-se para o campo GitVersion.

O Minikube permite habilitar addons no cluster Kubernetes. O Heapster é um exemplo disso, vamos habilitá-lo para termos monitoria de performance do cluster:

minikube addons enable heapster

Fazendo o deploy no Kubernetes

Vamos subir o Redis como "reliable singleton", que mesmo tendo um só Pod (Pod é a menor unidade de deploy no Kubernetes, podendo ter um ou mais containers que possam fazer sentido seu deploy unificado), ele será muito confiável por se tratar de um replicaSet (mantendo o estado desejado da infraestrutura) e ter persistência em disco. Subir a aplicação devops em um deployment com 3 replicaSets, mantento alta disponibilidade, já dando-nos base para fazer nosso rollout Blue/Green com downtime zero (tudo isso somente utilizando os recursos nativos do Kunernetes). Finalmente vamos testar o seu funcionamento.

Redis

Criando o volume persistente:

kubectl create -f redis-volume.yaml

Reivindicando o volume persistente:

kubectl create -f redis-volumeclaim.yaml

Criando o conjunto de réplicas do Redis

kubectl create -f redis-rs.yaml

Expondo o Redis como serviço internamente no Kubernetes

kubectl create -f redis-service.yaml

DevOps

Fazendo o deploy da aplicação devops:

kubectl create -f devops-deployment.yaml

Criando o serviço para acesso externo:

kubectl create -f devops-service.yaml

Acessando a homepage da aplicação devops:

minikube service devops

Testando

Mesmo o último comando abrindo com sucesso a homepage a aplicação vai levar de 1 a 2min para estar online.

Exponha a porta 4567 via localhost:

DEVOPS_POD=$(kubectl get pod -l run=devops -o jsonpath='{.items[0].metadata.name}')
kubectl port-forward $DEVOPS_POD 4567:4567

Abra o Postman, importe a coleção DevOps.postman_collection.json. Utilize a funcionalidade Run e execute "Run DevOps" algumas vezes.

Vá até o navegador de Internet com a homepage da aplicação e adicione o caminho /api/v1/ (devemos nos atentar ao / no fim do caminho), exemplo:

http://{{ip}}:{{port}}/api/v1/

Onde ip e port são fornecidos pelo comando minkube service devops, anteriormente executado.

Visualizando o Kubernetes

Em um terminal execute:

kubectl proxy

Acesse:

http://localhost:8001/ui

Finalizando o ambiente.

Depois de testar podemos destruir nosso ambiente:

minikube stop
minikube delete

Roadmap

[] Implementar export no formato CSV

[] Deixar a aplicação mais resiliente com validação dos campos do payload, health checks etc.

[] Alterar a solução de persistência para um banco mais apropriado para time series com InfluxDB.

[] Adicionar autorização e autenticação na aplicação e no banco de dados.

[] Implementar visualização em time series com a solução Cronograf.

[] Implementar CI/CD para o build da imagem do Docker com Jenkins.

[] Implementar teste automatizado com RSpec.

[] Implementar solução de log aggregator como Graylog ou Fluentd.

[] Criar namespaces no Kubernetes para os ambientes dev, staging e prod, para o Continuous Deployment.

[] Fazer deploy da solução em um provedor de computação em nuvem (pública).