Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

Primeiro, um pouco de teoria. O que aconteceu O aplicativo de doze fatores?

Em palavras simples, este documento foi concebido para simplificar o desenvolvimento de aplicações SaaS, ajudando a informar os desenvolvedores e engenheiros de DevOps sobre os problemas e práticas que são mais frequentemente encontrados no desenvolvimento de aplicações modernas.

O documento foi criado pelos desenvolvedores da plataforma Heroku.

O aplicativo Twelve-Factor pode ser aplicado a aplicativos escritos em qualquer linguagem de programação e usando qualquer combinação de serviços de apoio (bancos de dados, filas de mensagens, caches, etc.).

Resumidamente sobre os fatores em que esta metodologia se baseia:

  1. Base de código – Uma base de código rastreada no controle de versão – múltiplas implantações
  2. Dependências – Declarar e isolar explicitamente dependências
  3. Configuração – Salvar configuração em tempo de execução
  4. Serviços de apoio – Considere serviços de apoio como recursos de plug-in
  5. Construa, libere, execute – Separar rigorosamente as etapas de montagem e execução
  6. Процессы – Execute o aplicativo como um ou mais processos sem estado
  7. Ligação de porta – Exportar serviços via ligação portuária
  8. Concorrência – Dimensione sua aplicação usando processos
  9. Descartabilidade – Maximize a confiabilidade com inicialização rápida e desligamento limpo
  10. Paridade de desenvolvimento/operação de aplicativos – Mantenha seus ambientes de desenvolvimento, preparação e produção tão semelhantes quanto possível
  11. Exploração madeireira – Veja o log como um fluxo de eventos
  12. Tarefas de Administração – Executar tarefas de administração/gerenciamento usando processos ad hoc

Você pode obter mais informações sobre os 12 fatores nos seguintes recursos:

O que é implantação Azul-Verde?

A implantação Azul-Verde é um método de entrega de um aplicativo para produção de forma que o cliente final não veja nenhuma alteração de sua parte. Em outras palavras, implantar um aplicativo com zero tempo de inatividade.

O esquema clássico do BG Deploy se parece com o mostrado na imagem abaixo.

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

  • No início existem 2 servidores físicos com absolutamente o mesmo código, aplicação, projeto e existe um roteador (balanceador).
  • O roteador inicialmente direciona todas as solicitações para um dos servidores (verde).
  • No momento em que você precisa liberar novamente, todo o projeto é atualizado em outro servidor (azul), que não está processando nenhuma solicitação no momento.
  • Depois que o código estiver ativado azul servidor está completamente atualizado, o roteador recebe um comando para mudar de verde em azul servidor.
  • Agora todos os clientes veem o resultado do código executado com azul servidor.
  • Por algum tempo, verde o servidor serve como uma cópia de backup em caso de implantação malsucedida para azul servidor e em caso de falhas e bugs, o roteador muda o fluxo do usuário de volta para verde servidor com a antiga versão estável, e o novo código é enviado para revisão e teste.
  • E ao final do processo ele é atualizado da mesma forma verde servidor. E depois de atualizá-lo, o roteador muda o fluxo de solicitação de volta para verde servidor.

Tudo parece muito bom e à primeira vista não deve haver problemas com isso.
Mas como vivemos no mundo moderno, a opção de comutação física indicada no esquema clássico não nos convém. Registre as informações por enquanto, retornaremos a elas mais tarde.

Conselho ruim e bom

Aviso Legal: Os exemplos abaixo mostram as utilidades/metodologias que utilizo, você pode usar absolutamente quaisquer alternativas com funções semelhantes.

A maioria dos exemplos irá, de uma forma ou de outra, cruzar-se com o desenvolvimento web (isso é uma surpresa), com PHP e Docker.

Os parágrafos abaixo fornecem uma descrição prática simples do uso de fatores usando exemplos específicos; se você quiser obter mais teoria sobre este tópico, siga os links acima para a fonte original.

1. Base de código

Use FTP e FileZilla para fazer upload de arquivos para os servidores, um de cada vez, não armazene o código em nenhum outro lugar que não seja no servidor de produção.

O projeto deve sempre ter uma única base de código, ou seja, todo código vem de um Git repositório. Servidores (produção, teste, teste1, teste2...) usam código de ramificações de um repositório comum. Dessa forma, alcançamos consistência de código.

2. Dependências

Baixe todas as bibliotecas em pastas diretamente na raiz do projeto. Faça atualizações simplesmente transferindo o novo código para a pasta com a versão atual da biblioteca. Instale todos os utilitários necessários diretamente no servidor host onde mais 20 serviços estão em execução.

Um projeto deve sempre ter uma lista de dependências claramente compreensível (por dependências também quero dizer o ambiente). Todas as dependências devem ser explicitamente definidas e isoladas.
Tomemos como exemplo Compor и Estivador.

Compor — um gerenciador de pacotes que permite instalar bibliotecas em PHP. O Composer permite que você especifique versões de forma estrita ou vaga e as defina explicitamente. Pode haver 20 projetos diferentes no servidor e cada um terá uma lista pessoal de pacotes e bibliotecas independentes um do outro.

Estivador — um utilitário que permite definir e isolar o ambiente no qual o aplicativo será executado. Da mesma forma, assim como com o compositor, mas de forma mais detalhada, podemos determinar com o que o aplicativo funciona. Selecione uma versão específica do PHP, instale apenas os pacotes necessários para o funcionamento do projeto, sem adicionar nada extra. E o mais importante, sem interferir nos pacotes e no ambiente da máquina host e em outros projetos. Ou seja, todos os projetos no servidor executados através do Docker podem usar absolutamente qualquer conjunto de pacotes e um ambiente completamente diferente.

3. Configuração

Armazene configurações como constantes diretamente no código. Constantes separadas para o servidor de teste, separadas para produção. Vincule a operação do aplicativo dependendo do ambiente diretamente na lógica de negócios do projeto usando construções if else.

Configurações - esta é a única maneira pela qual as implantações dos projetos devem diferir. Idealmente, as configurações devem ser passadas por variáveis ​​de ambiente (env vars).

Ou seja, mesmo que você armazene vários arquivos de configuração .config.prod .config.local e os renomeie no momento da implantação para .config (a configuração principal da qual o aplicativo lê os dados) - essa não será a abordagem correta, pois neste caso as informações das configurações estarão disponíveis publicamente para todos os desenvolvedores de aplicações e os dados do servidor de produção serão comprometidos. Todas as configurações devem ser armazenadas diretamente no sistema de implantação (CI/CD) e geradas para diferentes ambientes com diferentes valores necessários para um ambiente específico no momento da implantação.

4. Serviços de Terceiros

Esteja estritamente vinculado ao ambiente, utilize conexões diferentes para os mesmos serviços em determinados ambientes.

Na verdade, este ponto se sobrepõe fortemente ao ponto sobre configurações, pois sem este ponto os dados normais de configuração não podem ser feitos e, em geral, a capacidade de configuração cairá a nada.

Todas as conexões com serviços externos, como servidores de filas, bancos de dados, serviços de cache, devem ser iguais tanto para o ambiente local quanto para o ambiente de terceiros/produção. Em outras palavras, a qualquer momento, alterando a string de conexão, posso substituir chamadas para a base nº 1 pela base nº 2 sem alterar o código do aplicativo. Ou, olhando para o futuro, por exemplo, ao dimensionar o serviço, você não precisará especificar a conexão de nenhuma maneira especial para um servidor de cache adicional.

5. Construa, libere, execute

Tenha apenas a versão final do código no servidor, sem chance de reverter o lançamento. Não há necessidade de preencher espaço em disco. Qualquer um que pensa que pode liberar código para produção com erro é um péssimo programador!

Todos os estágios de implantação devem ser separados uns dos outros.

Tenha a chance de reverter. Faça lançamentos com cópias antigas do aplicativo (já montadas e prontas para a batalha) salvas em acesso rápido, para que em caso de erros você possa restaurar a versão antiga. Ou seja, condicionalmente existe uma pasta lançamentos e pasta atual, e após implantação e montagem bem-sucedidas da pasta atual vinculado por um link simbólico ao novo lançamento que está dentro lançamentos com o nome convencional do número de lançamento.

É aqui que lembramos a implantação Azul-Verde, que permite não apenas alternar entre códigos, mas também alternar entre todos os recursos e até ambientes com a capacidade de reverter tudo.

6. Processos

Armazene dados de estado do aplicativo diretamente no próprio aplicativo. Use sessões na RAM do próprio aplicativo. Use o máximo possível de compartilhamento entre serviços de terceiros. Confie no fato de que o aplicativo pode ter apenas um processo e não permite escalonamento.

Em relação às sessões, armazene os dados apenas em um cache controlado por serviços de terceiros (memcached, redis), assim mesmo que você tenha 20 processos da aplicação em execução, qualquer um deles, tendo acessado o cache, poderá continuar trabalhando com o cliente em o mesmo estado em que o usuário estava trabalhando com o aplicativo em outro processo. Com essa abordagem, não importa quantas cópias de serviços de terceiros você use, tudo funcionará normalmente e sem problemas de acesso aos dados.

7. Ligação de porta

Somente o servidor web deve saber trabalhar com serviços de terceiros. Ou melhor ainda, instale serviços de terceiros diretamente no servidor web. Por exemplo, como um módulo PHP no Apache.
Todos os seus serviços devem ser acessíveis entre si através do acesso a algum endereço e porta (localgost:5432, localhost:3000, nginx:80, php-fpm:9000), ou seja, a partir do nginx posso acessar tanto o php-fpm quanto o postgres, e de php-fpm para postgres e nginx e na verdade de cada serviço posso acessar outro serviço. Desta forma, a viabilidade de um serviço não está vinculada à viabilidade de outro serviço.

8. Paralelismo

Trabalhe com um processo, caso contrário vários processos não conseguirão conviver entre si!

Deixe espaço para dimensionamento. O enxame Docker é ótimo para isso.
Docker Swarm é uma ferramenta para criar e gerenciar clusters de contêineres entre máquinas diferentes e vários contêineres na mesma máquina.

Usando o swarm, posso determinar quantos recursos irei alocar para cada processo e quantos processos do mesmo serviço irei iniciar, e o balanceador interno, recebendo dados em uma determinada porta, fará proxy automaticamente para os processos. Assim, vendo que a carga no servidor aumentou, posso adicionar mais processos, reduzindo assim a carga em determinados processos.

9. Descarte

Não use filas para trabalhar com processos e dados. Eliminar um processo deve afetar todo o aplicativo. Se um serviço falhar, tudo cairá.

Cada processo e serviço pode ser desligado a qualquer momento e isso não deve afetar outros serviços (é claro, isso não significa que o serviço estará indisponível para outro serviço, mas que outro serviço não será desligado após este). Todos os processos devem ser encerrados normalmente, para que, ao serem encerrados, nenhum dado seja danificado e o sistema funcione corretamente na próxima vez que você ligá-lo. Ou seja, mesmo em caso de encerramento emergencial, os dados não devem ser danificados (o mecanismo de transação é adequado aqui, as consultas no banco de dados funcionam apenas em grupos, e se pelo menos uma consulta do grupo falhar ou for executada com um erro, então nenhuma outra consulta do grupo falhará de fato).

10. Paridade de desenvolvimento/operação de aplicativos

A produção, a preparação e a versão local do aplicativo devem ser diferentes. Na produção usamos o framework Yii Lite, e localmente o Yii, para que ele funcione mais rápido na produção!

Na realidade, todas as implantações e trabalhos com código deveriam ocorrer em um ambiente quase idêntico (não estamos falando de hardware físico). Além disso, qualquer funcionário de desenvolvimento deve ser capaz de implantar o código na produção, se necessário, e não algum departamento de devops especialmente treinado, que somente graças à força especial pode colocar o aplicativo em produção.

Docker também nos ajuda com isso. Se todos os pontos anteriores forem observados, o uso do docker levará o processo de implantação do ambiente tanto na produção quanto na máquina local para a inserção de um ou dois comandos.

11. Registros

Gravamos logs em arquivos e bancos de dados! Não limpamos arquivos e bancos de dados de logs. Vamos comprar um disco rígido com 9000 Peta bytes e tudo bem.

Todos os logs devem ser considerados como um fluxo de eventos. O aplicativo em si não deve estar envolvido no processamento de logs. Os logs devem ser enviados para stdout ou enviados por meio de um protocolo como udp, para que trabalhar com logs não crie problemas para o aplicativo. graylog é bom para isso. O Graylog recebendo todos os logs via udp (este protocolo não requer espera por uma resposta sobre o sucesso do recebimento do pacote) não interfere de forma alguma na aplicação e apenas trata da estruturação e processamento dos logs. A lógica do aplicativo não muda para funcionar com tais abordagens.

12. Tarefas administrativas

Para atualizar dados, bancos de dados, etc., use um endpoint criado separadamente na API, executá-lo 2 vezes seguidas resultará na duplicação de tudo. Mas você não é estúpido, não clica duas vezes e não precisamos de migração.

Todas as tarefas de administração devem ser executadas no mesmo ambiente que todo o código, no nível da versão. Ou seja, se precisarmos alterar a estrutura do banco de dados, então não o faremos manualmente alterando os nomes das colunas e adicionando novas através de algumas ferramentas visuais de gerenciamento de banco de dados. Para isso, criamos scripts separados - migrações, que são executados em todos os lugares e em todos os ambientes da mesma forma, com um resultado comum e compreensível. Para todas as outras tarefas, como preencher o projeto com dados, deverão ser utilizadas metodologias semelhantes.

Exemplo de implementação em PHP, Laravel, Laradock, Docker-Compose

PS Todos os exemplos foram feitos em MacOS. A maioria deles também é adequada para Linux. Usuários do Windows, me perdoem, mas não trabalho com o Windows há muito tempo.

Vamos imaginar uma situação em que não temos nenhuma versão de PHP instalada em nosso PC e nada.
Instale as versões mais recentes do docker e docker-compose. (isso pode ser encontrado na Internet)

docker -v && 
docker-compose -v

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

1. Coloque Laradock

git clone https://github.com/Laradock/laradock.git && 
ls

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

Em relação ao Laradock, direi que é uma coisa muito legal, que contém muitos containers e coisas auxiliares. Mas eu não recomendaria usar o Laradock como tal, sem modificações na produção, devido à sua redundância. É melhor criar seus próprios containers com base em exemplos do Laradock, isso ficará muito mais otimizado, pois ninguém precisa de tudo que está lá ao mesmo tempo.

2. Configure o Laradock para executar nossa aplicação.

cd laradock && 
cp env-example .env

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

2.1. Abra o diretório habr (a pasta pai na qual o laradock é clonado) em algum editor. (No meu caso PHPStorm)

Nesta fase damos apenas um nome ao projeto.

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

2.2. Inicie a imagem do espaço de trabalho. (No seu caso, as imagens levarão algum tempo para serem construídas)
Workspace é uma imagem especialmente preparada para trabalhar com a estrutura em nome do desenvolvedor.

Entramos no contêiner usando

docker-compose up -d workspace && 
docker-compose exec workspace bash

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

2.3. Instalando Laravel

composer create-project --prefer-dist laravel/laravel application

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

2.4. Após a instalação, verificamos se o diretório com o projeto foi criado e matamos o compose.

ls
exit
docker-compose down

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

2.5. Vamos voltar ao PHPStorm e definir o caminho correto para nossa aplicação laravel no arquivo .env.

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

3. Adicione todo o código ao Git.

Para fazer isso, criaremos um repositório no Github (ou em qualquer outro lugar). Vamos para o diretório habr no terminal e executar o seguinte código.

echo "# habr-12factor" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin [email protected]:nzulfigarov/habr-12factor.git # здесь будет ссылка на ваш репо
git push -u origin master
git status

Vamos verificar se está tudo em ordem.

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

Por conveniência, recomendo usar alguma interface visual para Git, no meu caso é GitKraken. (aqui está um link de referência)

4. Vamos lançar!

Antes de começar, certifique-se de que nada esteja pendurado nas portas 80 e 443.

docker-compose up -d nginx php-fpm

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

Assim, nosso projeto consiste em 3 serviços distintos:

  • nginx - servidor web
  • php-fpm - php para receber solicitações de um servidor web
  • espaço de trabalho - php para desenvolvedores

Neste momento, conseguimos criar uma aplicação que cumpre 4 pontos em 12, nomeadamente:

1. Base de código — todo o código está em um repositório (pequena observação: pode ser correto adicionar o docker dentro do projeto laravel, mas isso não é importante).

2. Dependências - Todas as nossas dependências são escritas explicitamente em application/composer.json e em cada Dockerfile de cada container.

3. Serviços de apoio — Cada um dos serviços (php-fom, nigx, workspace) vive sua própria vida e está conectado externamente e ao trabalhar com um serviço o outro não será afetado.

4. Процессы — cada serviço é um processo. Cada um dos serviços não mantém o estado interno.

5. Ligação de porta

docker ps

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

Como podemos ver, cada serviço roda em sua própria porta e é acessível a todos os outros serviços.

6. Concorrência

O Docker nos permite gerar vários processos dos mesmos serviços com balanceamento de carga automático entre eles.

Vamos parar os contêineres e passá-los pela bandeira --escala

docker-compose down && 
docker-compose up -d --scale php-fpm=3 nginx php-fpm

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

Como podemos ver, foram criadas cópias do contêiner php-fpm. Não precisamos mudar nada ao trabalhar com este contêiner. Também continuamos acessando na porta 9000, e o Docker regula a carga entre contêineres para nós.

7. Descartabilidade - cada contêiner pode ser morto sem prejudicar o outro. Parar ou reiniciar o contêiner não afetará a operação do aplicativo durante inicializações subsequentes. Cada contêiner também pode ser levantado a qualquer momento.

8. Paridade de desenvolvimento/operação de aplicativos - todos os nossos ambientes são iguais. Ao executar o sistema em um servidor em produção, você não precisará alterar nada em seus comandos. Tudo será baseado no Docker da mesma forma.

9. Exploração madeireira — todos os logs nesses contêineres vão para streaming e ficam visíveis no console do Docker. (neste caso, aliás, com outros recipientes caseiros, pode não ser o caso se não cuidar bem)

 docker-compose logs -f

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

Mas há um problema: os valores padrão em PHP e Nginx também gravam logs em um arquivo. Para atender aos 12 fatores, é necessário desativar gravar logs em um arquivo nas configurações de cada contêiner separadamente.

O Docker também oferece a capacidade de enviar logs não apenas para stdout, mas também para itens como graylog, que mencionei acima. E dentro do graylog, podemos operar os logs como quisermos e nossa aplicação não perceberá isso de forma alguma.

10. Tarefas de Administração — todas as tarefas de administração são resolvidas pelo laravel graças à ferramenta artesanal exatamente como gostariam os criadores do aplicativo de 12 fatores.

Como exemplo, mostrarei como alguns comandos são executados.
Entramos no contêiner.

 
docker-compose exec workspace bash
php artisan list

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

Agora podemos usar qualquer comando. (observe que não configuramos o banco de dados e o cache, portanto metade dos comandos não serão executados corretamente, pois foram projetados para funcionar com o cache e o banco de dados).

Desenvolvimento de aplicações e implantação Blue-Green, baseado na metodologia The Twelve-Factor App com exemplos em php e docker

11. Configurações e 12. Construa, libere, execute

Eu queria dedicar esta parte à implantação azul-verde, mas acabou sendo muito extensa para este artigo. Escreverei um artigo separado sobre isso.

Em poucas palavras, o conceito é baseado em sistemas CI/CD como Jenkins и CI do Gitlab. Em ambos, você pode definir variáveis ​​de ambiente associadas a um ambiente específico. Assim, nesta situação, o ponto c será cumprido Configurações.

E o ponto sobre Construa, libere, execute é resolvido por funções integradas com o nome Pipeline.

Pipeline permite dividir o processo de implantação em várias etapas, destacando as etapas de montagem, liberação e execução. Também no Pipeline você pode criar backups e, na verdade, qualquer coisa. Esta é uma ferramenta com potencial ilimitado.

O código do aplicativo está em Github.
Não se esqueça de inicializar o submódulo ao clonar este repositório.

PS: Todas essas abordagens podem ser usadas com quaisquer outros utilitários e linguagens de programação. O principal é que a essência não difere.

Fonte: habr.com

Adicionar um comentário