O Docker 1.13 apresenta um recurso muito aguardado chamado suporte a arquivo de composição, que nos permite definir nossos contêineres com um arquivo de configuração simples e agradável em vez de um único comando longo. Se você der uma olhada em nossas postagens anteriores do blog “MySQL on Docker”, usamos várias linhas de comando longas para executar contêineres e serviços. Ao usar o arquivo de composição, os contêineres são facilmente especificados para implantação. Isso reduz o risco de erro humano, pois você não precisa se lembrar de comandos longos com vários parâmetros.
Nesta postagem do blog, mostraremos como usar o arquivo de composição usando exemplos simples sobre implantações do MySQL. Presumimos que você tenha o Docker Engine 1.13 instalado em 3 hosts físicos e o modo Swarm esteja configurado em todos os hosts.
Introdução ao Compose-File
No arquivo Compose, você especifica tudo no formato YAML em vez de tentar lembrar todos os argumentos que temos que passar para os comandos do Docker. Você pode definir serviços, redes e volumes aqui. A definição será escolhida pelo Docker e é muito parecido com passar parâmetros de linha de comando para o comando “docker run|network|volume”.
Como introdução, vamos implantar um contêiner MySQL autônomo simples. Antes de começar a escrever um arquivo Compose, primeiro você precisa conhecer o comando run. Extraído de nossa primeira série de blogs MySQL no Docker, vamos compor o seguinte comando “docker run”:
$ docker run --detach \
--name=test-mysql \
--publish 6603:3306 \
--env="MYSQL_ROOT_PASSWORD=mypassword" \
-v /storage/docker/mysql-datadir:/var/lib/mysql \
mysql
O comando docker-compose procurará um arquivo padrão chamado “docker-compose.yml” no diretório atual. Então, vamos primeiro criar os diretórios necessários de antemão:
$ mkdir -p ~/compose-files/mysql/single
$ mkdir -p /storage/docker/mysql-datadir
$ cd ~/compose-files/mysql/single
Em YAML, aqui está o que deve ser escrito:
version: '2'
services:
mysql:
image: mysql
container_name: test-mysql
ports:
- 6603:3306
environment:
MYSQL_ROOT_PASSWORD: "mypassword"
volumes:
- /storage/docker/mysql-datadir:/var/lib/mysql
Salve o conteúdo acima em “~/compose-files/mysql/single/docker-compose.yml”. Verifique se você está no diretório atual ~/compose-files/mysql/single e, em seguida, inicie-o executando o seguinte comando:
$ docker-compose up -d
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use `docker stack deploy`.
Creating test-mysql
Verifique se o contêiner está sendo executado no modo desanexado:
[[email protected] single]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
379d5c15ef44 mysql "docker-entrypoint..." 8 minutes ago Up 8 minutes 0.0.0.0:6603->3306/tcp test-mysql
Parabéns! Agora temos um container MySQL rodando com apenas um único comando.
Implantando uma pilha
Compose-file simplifica as coisas, nos fornece uma visão mais clara de como a infraestrutura deve ser. Vamos criar uma pilha de contêineres que consiste em um site em execução no Drupal, usando uma instância MySQL em uma rede dedicada e vinculá-los.
Semelhante ao acima, vamos dar uma olhada na versão da linha de comando na ordem correta para construir esta pilha:
$ docker volume create mysql_data
$ docker network create drupal_mysql_net --driver=bridge
$ docker run -d --name=mysql-drupal --restart=always -v mysql_data:/var/lib/mysql --net=drupal_mysql_net -e MYSQL_ROOT_PASSWORD="mypassword" -e MYSQL_DATABASE="drupal" mysql
$ docker run -d --name=drupal -p 8080:80 --restart=always -v /var/www/html/modules -v /var/www/html/profiles -v /var/www/html/themes -v /var/www/html/sites --link mysql:mysql --net=drupal_mysql_net drupal
Para começar a compor, vamos primeiro criar um diretório para nossa nova pilha:
$ mkdir -p ~/compose-files/drupal-mysql
$ cd ~/compose-files/drupal-mysql
Em seguida, crie o conteúdo de gravação do docker-compose.yml conforme abaixo:
version: '2'
services:
mysql:
image: mysql
container_name: mysql-drupal
environment:
MYSQL_ROOT_PASSWORD: "mypassword"
MYSQL_DATABASE: "drupal"
volumes:
- mysql_data:/var/lib/mysql
restart: always
networks:
- drupal_mysql_net
drupal:
depends_on:
- mysql
image: drupal
container_name: drupal
ports:
- 8080:80
volumes:
- /var/www/html/modules
- /var/www/html/profiles
- /var/www/html/themes
- /var/www/html/sites
links:
- mysql:mysql
restart: always
networks:
- drupal_mysql_net
volumes:
mysql_data:
networks:
drupal_mysql_net:
driver: bridge
Acenda-os:
$ docker-compose up -d
..
Creating network "drupalmysql_drupal_mysql_net" with driver "bridge"
Creating volume "drupalmysql_mysql_data" with default driver
Pulling drupal (drupal:latest)...
..
Creating mysql-drupal
Creating drupal
O Docker executará a implantação da seguinte forma:
- Criar rede
- Criar volume
- Puxar imagens
- Criar mysql-drupal (já que o container “drupal” depende dele)
- Crie o contêiner Drupal
Neste ponto, nossa arquitetura pode ser ilustrada da seguinte forma:
Podemos então especificar ‘mysql’ como o host MySQL na página do assistente de instalação, pois ambos os contêineres estão vinculados. É isso. Para derrubá-los, basta executar o seguinte comando no mesmo diretório:
$ docker-compose down
Os contêineres correspondentes serão encerrados e removidos de acordo. Observe que o comando docker-compose está vinculado ao host físico individual que executa o Docker. Para ser executado em vários hosts físicos no Swarm, ele precisa ser tratado de maneira diferente, utilizando o comando “docker stack”. Explicaremos isso na próxima seção.
Vários noves MySQL no Docker:como conteinerizar seu banco de dadosDescubra tudo o que você precisa entender ao considerar executar um serviço MySQL em cima da virtualização de contêiner do DockerBaixe o white paper
Compondo uma pilha no enxame
Em primeiro lugar, verifique se o mecanismo do Docker está sendo executado na v1.13 e o modo Swarm está ativado e no estado pronto:
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
8n8t3r4fvm8u01yhli9522xi9 * docker1.local Ready Active Reachable
o1dfbbnmhn1qayjry32bpl2by docker2.local Ready Active Reachable
tng5r9ax0ve855pih1110amv8 docker3.local Ready Active Leader
Para usar o recurso de pilha para o modo Docker Swarm, temos que usar o formato Docker Compose versão 3. Vamos implantar uma configuração semelhante à acima, além de uma configuração Galera de 3 nós como backend do MySQL. Já explicamos em detalhes nesta postagem do blog.
Primeiro, crie um diretório para nossa nova pilha:
$ mkdir -p ~/compose-files/drupal-galera
$ cd ~/compose-files/drupal-galera
Em seguida, adicione as seguintes linhas em “docker-compose.yml”:
version: '3'
services:
galera:
deploy:
replicas: 3
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 3
window: 60s
update_config:
parallelism: 1
delay: 10s
max_failure_ratio: 0.3
image: severalnines/pxc56
environment:
MYSQL_ROOT_PASSWORD: "mypassword"
CLUSTER_NAME: "my_galera"
XTRABACKUP_PASSWORD: "mypassword"
DISCOVERY_SERVICE: '192.168.55.111:2379,192.168.55.112:2379,192.168.55.207:2379'
MYSQL_DATABASE: 'drupal'
networks:
- galera_net
drupal:
depends_on:
- galera
deploy:
replicas: 1
image: drupal
ports:
- 8080:80
volumes:
- drupal_modules:/var/www/html/modules
- drupal_profile:/var/www/html/profiles
- drupal_theme:/var/www/html/themes
- drupal_sites:/var/www/html/sites
networks:
- galera_net
volumes:
drupal_modules:
drupal_profile:
drupal_theme:
drupal_sites:
networks:
galera_net:
driver: overlay
Observe que a imagem Galera que usamos (severalnines/pxc56) requer um cluster etcd em execução instalado em cada host físico do Docker. Consulte esta postagem do blog sobre as etapas de pré-requisito.
Uma das partes importantes em nosso arquivo de composição é o parâmetro max_attempts na seção restart_policy. Temos que especificar um limite rígido para o número de reinicializações em caso de falha. Isso tornará o processo de implantação mais seguro porque, por padrão, o agendador do Swarm nunca desistirá de tentar reiniciar os contêineres. Se isso acontecer, o loop do processo preencherá o espaço em disco do host físico com contêineres inutilizáveis quando o escalonador não puder trazer os contêineres para o estado desejado. Essa é uma abordagem comum ao lidar com serviços com estado, como o MySQL. É melhor derrubá-los completamente do que fazê-los funcionar em um estado inconsistente.
Para iniciá-los, basta executar o seguinte comando no mesmo diretório em que o docker-compose.yml reside:
$ docker stack deploy --compose-file=docker-compose.yml my_drupal
Verifique se a pilha foi criada com 2 serviços (drupal e galera):
$ docker stack ls
NAME SERVICES
my_drupal 2
Também podemos listar as tarefas atuais na pilha criada. O resultado é uma versão combinada dos comandos “docker service ps my_drupal_galera” e “docker service ps my_drupal_drupal”:
$ docker stack ps my_drupal
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
609jj9ji6rxt my_drupal_galera.1 severalnines/pxc56:latest docker3.local Running Running 7 minutes ago
z8mcqzf29lbq my_drupal_drupal.1 drupal:latest docker1.local Running Running 24 minutes ago
skblp9mfbbzi my_drupal_galera.2 severalnines/pxc56:latest docker1.local Running Running 10 minutes ago
cidn9kb0d62u my_drupal_galera.3 severalnines/pxc56:latest docker2.local Running Running 7 minutes ago
Depois de obter o CURRENT STATE como RUNNING, podemos iniciar a instalação do Drupal conectando-se a qualquer endereço IP do host do Docker ou nome do host na porta 8080, pois neste caso usamos docker3 (embora o contêiner drupal seja implantado no docker1), http ://192.168.55.113:8080/. Prossiga com a instalação e especifique 'galera' como o host MySQL e 'drupal' como o nome do banco de dados (conforme definido no arquivo de composição na variável de ambiente MYSQL_DATABASE):
É isso. A implantação da pilha foi simplificada usando o Compose-file. Neste ponto, nossa arquitetura está mais ou menos assim:
Por fim, para remover a pilha, basta executar o seguinte comando:
$ docker stack rm my_drupal
Removing service my_drupal_galera
Removing service my_drupal_drupal
Removing network my_drupal_galera_net
O uso do arquivo de composição pode economizar seu tempo e reduzir o risco de erro humano, em comparação com o trabalho com linhas de comando longas. Esta é uma ferramenta perfeita para você dominar antes de trabalhar com aplicativos Docker de vários contêineres, lidando com vários ambientes de implantação (por exemplo, dev, test, staging, pre-prod, prod) e lidando com serviços muito mais complexos, assim como o MySQL Galera Cluster. Feliz conteinerização
!