Simulando Auto Scale com Docker Compose
Mar 2, 2019 · 6 minute read · Commentsdockerportuguesdevopscontainers
Este post é baseado num workshop ministrado numa das empresas que trabalhei e na Campus Party São Paulo 2019, ele irá fazer o básico até o uma simulação de auto-scale usando o Docker Composer. Aí, vem a pergunta, por que?
Para observar o comportamento da aplicação se funciona num cenário de auto-scale de usando um orquestrador de containers como Kubernetes, DC/OS ou Docker Swarm antes da funcionalidade ir para o repositório do projeto no qual está trabalhando.
Requisitos
Docker 101
Há duas formas de seguir este tutorial: instalando no computador ou via Play-with-Docker.
A instalação do Docker pode ser os passos do livro Docker para Desenvolvedores do @Gomex
Abra o Play-With-Docker ou use Docker instalado no seu computador. Necessário ter uma conta na docker.
Clonar o repositório Git do workshop
$ git clone https://github.com/fike/docker-workshop.git $ cd docker-workshop
O Docker gera as imagens de containers através das instruções contidas no Dockerfile. Para criar uma image usando Dockerfile usa-se o comando
docker build
. O-t
é para definir o nome da imagem (tag).$ docker build -t hello .
Bônus: uma leitura posterior é recomendada no “Best practices for writing Dockerfiles“
A imagem será criada no computador onde foi executado o
docker build
, as imagens em cache/armazenadas podem ser visualizadas usando o comando abaixo:$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello latest 5877ef9de68e About a minute ago 196MB
Perceba que a imagem é gerada por padrão com a tag
latest
.Se quiser gerar novamente uma imagem e manter a anterior com o mesmo nome, pode-se definir uma tag no momento da geração da imagem.
$ docker build -t hello:1 .
Bônus: uma boa prática recomendada para gerenciar versão da imagem, mantenedor da imagem e qualquer outras informações (metadados); recomenda-se usar o
LABEL
no Dockerfile ou usar o parâmetro--label
:Gera a imagem com diversos label $ docker build -t hello:2 --label app=hello --label MAINTAINER="Foo bar <foo@bar.com>" --label build=1 . $ docker inspect -f '{{index .ContainerConfig.Labels}}' hello:2 map[MAINTAINER:Foo bar <foo@bar.com> app:hello build:1] $ docker inspect -f '{{index .ContainerConfig.Labels "app"}}' hello:2 hello
Para acessar uma porta dentro de um container é necessário passar para o Docker quais portas serão expostas. O app do workshop roda na porta 80/TCP, para acessar essa porta é necessário dizer para o Docker qual porta externa será mapeada. O mapeamento de porta é dado por
-p PORTA_EXTERNA:PORTA_INTERNA
.O parâmetro
-d
faz com que o container rode no background.$ docker run -d -p 4000:80 hello
O site estará disponível via
https://localhost:4000
, se você executou o comando em seu computador, ou em um pequeno link no play-with-docker com o número 4000.
O Hello World do app deste workshop usa o Redis para contar os acessos (como não subimos o Redis, o contador está desativado!). Mas antes de subir o Redis é necessário criar uma rede na qual será feita a comunicação entre o app e ele:
Criar a rede workshop
$ docker network create workshop
A rede criada, é só rodar o container do Redis e do App na mesma rede. Não se esqueça de finalizar o container anterior que está no background!
Finalizar o container do app $ docker stop $(docker ps | grep hello | awk '{ print $1 }') Executando o Redis $ docker run -d --name redis --network workshop redis Executando o app $ docker run -d --name hello --network workshop -p 4000:80 hello
Como no passo 5, abra no browser a URL https://localhost:4000/ ou clique no 4000 se estiver usando o Play-With-Docker. Faça o reload algumas vezes, contador irá funcionar desta vez.
Compartilhando volumes (stateful cases). O Docker possibilita compartilhar volumes entre containers de forma bastante simples:
Criando volume $ docker volume create workshop_data Lista os volumes criados $ docker volume ls
Vamos agora iniciar um container com acesso ao volume compartilhado. O mapeamento de volume é dado por
-v VOLUME_HOST:VOLUME_CONTAINER
.VOLUME_CONTAINER é o path que o volume será montado no container
Os parâmetros
-it
conectam seu terminal com um terminal dentro do contêiner.Executar um container e criar um arquivo com alguma informação $ docker run -it -v workshop_data:/storage debian bash $ echo "Oi, consegue ler?" > /storage/README $ exit
O container no passo anterior criou um arquivo em ‘/storage’ como o nome README. Acrescente mais uma informação executando outro container:
$ docker run -it -v workshop_data:/storage debian bash $ cat /storage/README $ echo "Sim, consigo ler!" >> /storage/README $ exit
Extra: Como compartilhar um diretório do host com o container?
Docker Compose
O Docker Compose facilita a comunicação de entre containers para fazer testes ou em desenvolvimento de aplicações (não deve ser usado em ambientes de produção). No diretório do workshop há um arquivo docker-compose.yml
no qual tem as informações para subir o app deste workshop e o Redis.
Gerando as imagens:
Parar todos os containers $ docker stop $(docker ps -aq) $ docker-compose build
Como o Docker (comando), o Docker Compose também tem o argumento ps para listar os containers.
Rodar os containers no background $ docker-compose up -d Listar o containers em execução $ docker-compose ps
Você pode abrir novamente o browser https://localhost:4000/
ou clicar no 4000 se estiver usando o play-with-docker. Note que o contador reniciou.
Finalize os containers em execução:
$ docker-compose stop
A “inteligência” para reconhecer as novas instâncias do app hello-world é o Traefik acessar o a API Docker para identificar novas instacias nada rede na qual ele está em execução. Assim, pode simular o comportamento em produção de uma aplicação ao fazer o up scale e o down scale.
Auto-Scaling
Subindo o app e Redis via Docker Compose. Após a execução do Docker Compose, o app estará disponível da mesma fora mencionado (
https://localhost:4000
). Abra o browser novamente e recarregue algumas vezes, observe que o hostname não varia.Gerando as imagens $ docker-compose -f docker-compose-scale.yml build Executando os containers $ docker-compose -f docker-compose-scale.yml up -d
O arquivo de configuração
docker-compose-scale.yml
tem dois serviços:hello
eredis
. O comando abaixo irá aumenta o número de containers dehello
para 5:$ docker-compose -f docker-compose-scale.yml up -d --scale hello=5
Abra o browser novamente em https://localhost:4000/
e recarregue a página algumas vezes. O hostname deverá ser diferente toda vez que abrir a página, isso porque a cada requisição o Traefik está enviando a requisição para um container.
Extra: Mais Comandos
Alguns comandos avançados:
Adquire informações detalhadas sobre um object Docker $ docker inspect Remove objetos Docker não usados (containers, imagens, redes e volumes) $ docker system prune Remove apenas os containers parados $ docker rm $(docker ps -aq -f status=exited) Compila uma aplicação Go $ docker run --rm -v "$PWD":/d/helloworld -w /d/helloworld golang go build helloworld.go
Extra: Docker Registry
Acesse https://hub.docker.com, lá você encontra uma biblioteca de inúmeras imagens Docker!
Crie uma conta no site, e você pode agora publicar suas próprias imagens! Todas as imagens são nomeadas seguindo o padrão repositorio/imagem:tag
; repositorio
corresponde ao id de sua conta ou de sua organização (por exemplo, https://hub.docker.com/r/maburix).
Para publicar uma imagem, troque o tag de uma imagem para seguir a convenção, e então utilize docker push
:
$ docker tag hello <nome-de-sua-conta>/hello
$ docker push <nome-de-sua-conta>/hello
Agora todo o mundo pode baixar e rodar sua imagem!
$ docker pull <nome-de-sua-conta>/hello
Conclusão
Auto-scale é relativamente simples mas envolve muito componentes que estão relacionado a conceitos como Infraestrutura Imutável, Orquestração de Containers, Continuous Delivery, Blue-Green Deployment, Canary Release, Aplicações Stateless, etc.