Há algumas semanas a Elastic Beanstalk anunciou o suporte para a implementação e gerenciamento de containers Docker na nuvem AWS. Neste artigo, vamos descrever como fazer o dock de um aplicativo simples de formulário web, originalmente escrito para o ambiente Elastic Beanstalk Python.
Sobre o aplicativo
Desenvolvemos e divulgamos o aplicativo há alguns meses. Há uma série de vídeos em quatro partes e um post que detalha o uso do DynamoDB e do SNS com o app. Neste artigo, faremos uma análise em 4 fases sobre como o aplicativo roda com o Docker e o Elastic Beanstalk.
Código fonte para referência
O código fonte para a aplicação Python original (ou seja, sem o dock) está disponível no GitHub (no ramo principal). A versão “Dockerized” está no ramo docker.
E se você preferir o código e comparativos para blogar a respeito, confira a visualização disponível no GitHub para comparar as diferenças entre esses dois ramos. Verifique os arquivos adicionados e cada linha alterada em Dockerize neste exemplo.
Fase 1: Adição de um Dockerfile
Vamos começar analisando o código fonte do GitHub:
gt; git clone git@github.com:awslabs/eb-py-flask-signup.git gt; cd eb-py-flask-signup gt; git checkout master
Analisando os conteúdos do diretório, vemos que este é um aplicativo web simples escrito em Python, que usa o framework Flask, o Boto para interagir com o DynamoDB e o SNS, e algumas outras dependências declaradas no arquivo requirements.txt.
Em seguida, criamos um Dockerfile que irá construir uma imagem adequada para executar esta aplicação. O Dockerfile fica no diretório com o restante da fonte do aplicativo (ou seja, ao lado de requirements.txt, application.py etc):
FROM ubuntu:12.10 # Install Python Setuptools RUN apt-get install -y python-setuptools # Install pip RUN easy_install pip # Add and install Python modules ADD requirements.txt /src/requirements.txt RUN cd /src; pip install -r requirements.txt # Bundle app source ADD . /src # Expose EXPOSE 5000 # Run CMD ["python", "/src/application.py"]
Fase 2: Testes locais
Embora este aplicativo exija uma tabela DynamoDB e o tópico SNS para ser totalmente funcional, podemos testá-lo sem eles:
Em primeiro lugar, construa a imagem Docker:
gt; docker build -t eb-py-sample .
Por último, execute um container a partir da imagem (mapeando a porta 5000 do container para a porta de host 8080, e defina algumas env vars discutidas abaixo):
gt; docker run -d \ -e APP_CONFIG=application.config.example \ -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ -p 8080:5000 \ eb-py-sample
No OS X podemos abrir http://localhost:8080 e lá está o app!
Sidebar: Usamos as opções – e para passar adiante algumas variáveis de ambiente:
- APP_CONFIG: O aplicativo requer esta variável de ambiente para apontar para o arquivo de configuração. Apontamos para o arquivo de configuração padrão que vem com o aplicativo. Você poderia criar uma tabela DynamoDB e um tópico SNS e adicioná-los a este arquivo conf para fazer o app funcionar perfeitamente em um env dev local.
- AWS_ACCESS_KEY_ID e AWS_SECRET_ACCESS_KEY: O aplicativo usa o Boto para se conectar ao DynamoDB e ao SNS, e o Boto usa essas variáveis de ambiente para assinar as requisições para esses serviços. Isso vale apenas para o dev local. Quando implementarmos a Elastic Beanstalk usaremos o IAM Roles.
Fase 3: Modificar .ebextensions
Nosso aplicativo possui um diretório “especial.ebextensions” com um arquivo setup.config. Usamos o arquivo para informar ao Elastic Beanstalk que este deve criar a tabela DynamoDB e ao tópico SNS nossas necessidades de aplicativo, e também para criar um arquivo de configuração do app – /var/app/app.config – que inclui os nomes da tabela DynamoDB e o tópico SNS que acabou de ser criado.
O arquivo também detalha algumas coisas específicas ao tipo de ambiente Python (ao contrário do Docker) no Elastic Beanstalk. Precisamos remover os bits agora:
Modifique o membro files para remover as chaves owner e group para que se pareçam com:
files: "/var/app/app.config": mode: "000444" content: | AWS_REGION = '`{ "Ref" : "AWS::Region"}`' STARTUP_SIGNUP_TABLE = '`{ "Ref" : "StartupSignupsTable"}`' NEW_SIGNUP_TOPIC = '`{ "Ref" : "NewSignupTopic"}`'
Modifique option_settings para remover mapeamento estático de arquivos para que se pareça com:
option_settings: "aws:elasticbeanstalk:customoption": "AlarmEmail" : "nobody@amazon.com" "aws:elasticbeanstalk:application:environment": "APP_CONFIG": "/var/app/app.config" "FLASK_DEBUG": "false" "THEME": "flatly"
Confira o artigo anterior para mais informações sobre setup.config, ou consulte setup.config do Dockerized no GitHub
Fase 4: Implementação do Elastic Beanstalk
Já construímos e testamos o container localmente, removemos algumas .ebextensions que eram específicas do ambiente Elastic Beanstalk Python, e agora estamos prontos para implementá-lo com confiança!
Criamos um arquivo chamado Dockerrun.aws.json no mesmo lugar em que criamos o Dockerfile. Este arquivo informará ao Elastic Beanstalk como deve executar o container Docker e se parece com isso (veja o quadro abaixo para mais detalhes sobre este arquivo):
"AWSEBDockerrunVersion": "1", "Volumes": [ { "ContainerDirectory": "/var/app", "HostDirectory": "/var/app" } ], "Logging": "/var/eb_log" }
Sidebar sobre o Dockerrun.aws.json:
O membro Volumes irá mapear /var/app na instância EC2 de /var/app no container. Isso permite que o aplicativo em execução no container do Docker acesse o arquivo app.config criado por .ebextensions/setup.config. O membro Logging indica ao Elastic Beanstalk que nosso aplicativo Dockerized irá gravar logs em /var/eb_log no container. Beanstalk puxará automaticamente os logs a partir deste diretório sempre que o usuário clicar em Snapshot Logs no console, ou se ativar a rotação automática de log.
Vamos comitar as alterações e usar o git archive para fazer um zip para implementar a Elastic Beanstalk (você pode usar a ferramenta zip ou Finder ou ainda Windows Explorer para obter o mesmo):
gt; git add Docker* && git commit -am "Dockerized" gt; git archive --format=zip HEAD > eb-py-flask-signup.zip
E então implementamos o zip via Elastic Beanstalk Management Console.
Quando nosso ambiente estiver verde, poderemos, é claro, acessá-lo e verificar se funciona:
Também faremos um snapshot dos logs do ambiente:
Referências
- Exemplo de aplicativo Dockerized no GitHub: https://github.com/awslabs/eb-py-flask-signup/tree/docker
- O Docker na documentação Elastic Beanstalk:http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_docker.html
***
Artigo escrito por Jonathan Fritz, Senior Product Manager da Amazon EMR.
Este artigo faz parte do AWSHUB, rede de profissionais AWS gerenciado pelo iMasters.