Da modelagem ao Deploy — Deploy

Aplicação de Machine learning com Docker e Kubernetes

Image for post
Image for post
Photo by SpaceX on Unsplash

O objetivo desse artigo, é exemplificar como desenvolver um modelo de Machine Learning de previsão de demanda e colocá-lo em produção. Para desenvolver o modelo utilizamos o Jupyter Notebook. A API foi desenvolvida em Flask e o front-end em Flasgger, que é uma extensão do Flask que permite criar páginas web. O deployment da aplicação foi feito no Google Cloud utilizando Kubernetes e Docker.

O tutorial está dividido em cinco artigos:

Todo o código do projeto está no Github, link no rodapé do artigo assim como as referências do trabalho.

Machine Learning Pipeline Deploy

1 — Inicialmente definimos que utilizaríamos um modelo de regressão para tentar prever o número de vendas de um departamento de uma loja. Testamos dois modelos e escolhemos a Random Forest pois a função de custo desse algoritmo era menor. Em seguida, treinamos o modelo para então exportá-lo utilizando o pickle.

2 — Como o objetivo de aplicação é ser acessada via web, criamos uma API em Flask, definindo as rotas para dois métodos HTTP GET e POST que seriam acessados de acordo com a URL informada. Dentro da API também utilizamos o pickle para carregar o modelo que havia sido exportado.

3 — O terceiro passo foi criar o front-end da aplicação, utilizamos o Flasgger para isso e criamos a interface para os métodos GET e POST serem acessados via web browser. Executamos localmente a aplicação para testar se as rotas da API estavam funcionando corretamente.

4 — Com a aplicação finalizada, introduzimos os conceitos de Containers e Dockers. Criamos a imagem da aplicação e executamos o Docker Container para ser acessado no localhost. Entendemos também como o Kubernetes pode nos ajudar a escalar o nosso modelo em produção.

O último passo dessa jornada é colocar o modelo em produção no Google Cloud.

Google Cloud

Alteração 1 —Por padrão, colocaremos o arquivo principal com o nome de main. Para isso, criamos uma cópia do flasgger_api.py e renomeamos para main.py.

Alteração 2 — Criar um arquivo YAML (app.yaml) com o seguinte código:

runtime: python37

O arquivo YAML funciona como uma descrição do projeto para a ser colocado em produção.

Alteração 3 — Dentro do arquivo main.py, devemos alterar a parte onde chamamos o app, adicionando o placeholder 0.0.0.0 para o host e especificando a porta 8080.

if __name__ == '__main__':
app.debug = True
app.run(debug=True,host='0.0.0.0',
port=int(os.environ.get('PORT', 8080)))

Criando o Projeto

Image for post
Image for post
Criando o projeto

Após a criação do projeto, é necessário ativar os serviços do Kubernetes Engine e Container Registry. Nossa aplicação possui apenas um container, mas no caso de uma aplicação maior, o Container Registry funcionará como um hub de todos os containers da aplicação. Basta pesquisar pelo nome dos serviços e ativá-los.

Cloud Shell

Image for post
Image for post
Cloud Shell

Utilizaremos a linha de comandos do Google Cloud, para isso é necessário ativar o Cloud Shell na barra superior.

Image for post
Image for post
Git clone

Dentro da pasta do projeto no Github, copie a URL do repositório. Utilizaremos para copiar os arquivos para dentro da nuvem.

Passo 1Clonar repositório.

$ git clone  https://github.com/eduardopd/retail-data-app.git
Image for post
Image for post
Cloud Shell — Git clone

Pronto, todos os arquivos do repositório do Github foram copiados para dentro do repositório na nuvem.

Passo 2 Alterar Dockerfile.

Precisamos fazer algumas alterações no arquivo Dockerfile. Clique em "Abrir editor" e navegue até o arquivo.

Image for post
Image for post
Cloud Shell Editor — Dockerfile
ENV APP_HOME /appWORKDIR $APP_HOMECOPY . ./

A primeira alteração será na parte de copiar o código local para o container.

ENV PORT 8080

Em seguida definimos a porta por onde o container será exposto.

RUN pip install Flask gunicornRUN pip install -r requirements.txt

Instalamos as dependências do ambiente de produção com o gunicorn e os requerimentos da aplicação através do arquivo requirements.txt.

CMD python main.py runserver 0.0.0.0:$PORT

Finalmente, definimos que main.py será executado no IP público informado (0.0.0.0 é um placeholder para o IP), na porta especificada em ENV PORT 8080.

Passo 3Alterar requirements.txt.

Image for post
Image for post
Cloud Shell Editor — requirements

Adicionar biblioteca pycaret.

Passo 4Verificar pasta de arquivos.

$ ls
$ cd retail-data-app
$ ls
Image for post
Image for post
Cloud Shell — Repository

Digitando os comandos acima podemos verificar que o clone do repositório foi feito corretamente e que o arquivo Dockerfile já está sem a extensão .TXT.

Passo 5Exportando o projeto para uma variável global.

$ export PROJECT_ID=retail-app-01

Passo 6 Criando a imagem Docker.

$ docker build -t gcr.io/${PROJECT_ID}/app:v1 .

Nesse comando, informamos qual o container para onde a imagem deve ir. É fundamental que o Container Registry tenha sido ativado. O nome da imagem a ser criada também é informado após o nome do projeto. Nesse caso será app e a versão v1.

$ docker images
Image for post
Image for post
Cloud Shell — Docker images

Pronto, a imagem foi criada e assim como localmente, podemos utilizar o comando docker images para verificar as imagens.

Passo 7Executar a imagem localmente.

$ docker run --rm -p 8080:8080 gcr.io/${PROJECT_ID}/app:v1
Image for post
Image for post
Cloud Shell — Localhost

Esse passo é importante para garantir que a configuração de portas feita no Dockerfile funciona e que não houve erros na execução.

Passo 8Upload a imagem do container para o repositório (Push).

Image for post
Image for post
Container Registry

Ative a API Container Registry e em seguida execute os comandos abaixo:

$ gcloud auth configure-docker
$ docker push gcr.io/${PROJECT_ID}/app:v1

O processo pode demorar um pouco, o que estamos fazendo aqui é o upload da imagem que criamos no Docker para o Container Registry.

Passo 9Criando um Kubernetes Cluster.

Image for post
Image for post
Kubernetes Engine

Ative o serviço do Kubernetes Engine e execute os comandos abaixo:

$ gcloud config set compute/zone us-central1$ gcloud container clusters create retail-cluster --num-nodes=1
Image for post
Image for post
Kubernetes Cluster

Passo 10Deploy.

Primeiro passo no Kubernetes é criar um Kubernetes Deployment com os pods. Pod é a menor unidade dentro do Kubernetes, são réplicas que auxiliam na escalabilidade da aplicação, sendo acionadas de acordo com a utilização da CPU. Imagine um estádio de futebol onde os setores são abertos na medida em que o público entra. Os setores são as réplicas dos pods.

$ kubectl create deployment app --image=gcr.io/${PROJECT_ID}/app:v1
$ kubectl scale deployment app --replicas=3
$ kubectl autoscale deployment app --cpu-percent=80 --min=1 --max=5

Após executar os comando, o deployment estará criado e a aplicação escalada.

$ kubectl get pods
Image for post
Image for post
Kubernetes Deployment Pods

Passo 11Expor a aplicação.

Os pods tem IP's individuais que só podem ser "enxergados" de dentro do cluster. Como o nosso objetivo é acessar a aplicação pela web, precisamos "expor" os pods para que possam ser acessados dessa maneira.

$ kubectl expose deployment app --name=retail-app-service --type=LoadBalancer --port 80 --target-port 8080

Agora os pods estão expostos e podem ser acessados via browser. Digite o comando abaixo e copie o EXTERNAL-IP.

$ kubectl get service
Image for post
Image for post
Kubernetes Get Service

Por fim, basta colar o EXTERNAL-IP no browser e voilà! A aplicação está disponível na web.

Image for post
Image for post
EXTERNAL-IP/apidocs

Conclusão

Boas previsões!

Eduardo Domingues — Github | LinkedIn

Referências:

Github do projetohttps://github.com/eduardopd/retail-data-app

Written by

Data Scientist — Quantitative Trader

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store