Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

Primero, un poco de teoría. Qué ha pasado La aplicación de doce factores?

En palabras simples, este documento está diseñado para simplificar el desarrollo de aplicaciones SaaS, ayudando a informar a los desarrolladores e ingenieros de DevOps sobre los problemas y prácticas que se encuentran con mayor frecuencia en el desarrollo de aplicaciones modernas.

El documento fue creado por los desarrolladores de la plataforma Heroku.

La aplicación Twelve-Factor se puede aplicar a aplicaciones escritas en cualquier lenguaje de programación y que utilicen cualquier combinación de servicios de respaldo (bases de datos, colas de mensajes, cachés, etc.).

Brevemente sobre los factores en los que se basa esta metodología:

  1. Base de código – Una base de código rastreada en el control de versiones – múltiples implementaciones
  2. Dependencias – Declarar y aislar dependencias explícitamente
  3. Configuración – Guardar la configuración en tiempo de ejecución
  4. Servicios de respaldo – Considere los servicios de respaldo como recursos complementarios
  5. Construir, lanzar, ejecutar – Separar estrictamente las etapas de montaje y ejecución.
  6. Процессы – Ejecutar la aplicación como uno o más procesos sin estado.
  7. Enlace de puerto – Servicios de exportación vía enlace portuario
  8. Concurrencia – Escale su aplicación utilizando procesos
  9. Disponibilidad – Maximice la confiabilidad con un inicio rápido y un apagado limpio
  10. Paridad de desarrollo/operación de aplicaciones – Mantenga sus entornos de desarrollo, puesta en escena y producción lo más similares posible
  11. Inicio sesión – Ver el registro como una secuencia de eventos
  12. Tareas de administración – Realizar tareas de administración/gestión utilizando procesos ad hoc

Puede obtener más información sobre los 12 factores en los siguientes recursos:

¿Qué es el despliegue Azul-Verde?

La implementación Blue-Green es un método para entregar una aplicación a Production de tal forma que el cliente final no vea ningún cambio por su parte. En otras palabras, implementar una aplicación sin el tiempo de inactividad.

El esquema clásico de BG Deploy se parece al que se muestra en la imagen a continuación.

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

  • Al principio hay 2 servidores físicos con absolutamente el mismo código, aplicación, proyecto y hay un enrutador (equilibrador).
  • El enrutador inicialmente dirige todas las solicitudes a uno de los servidores (verde).
  • En el momento en que necesita volver a publicar, todo el proyecto se actualiza en otro servidor (azul), que actualmente no está procesando ninguna solicitud.
  • Después de que el código esté activado azul El servidor está completamente actualizado, el enrutador recibe un comando para cambiar de verde en azul servidor.
  • Ahora todos los clientes ven el resultado del código que se ejecuta con azul servidor.
  • Durante algún tiempo, verde El servidor sirve como copia de seguridad en caso de una implementación fallida en azul servidor y en caso de fallas y errores, el enrutador cambia el flujo de usuario nuevamente a verde servidor con la antigua versión estable y el nuevo código se envía para revisión y prueba.
  • Y al final del proceso se actualiza de la misma forma. verde servidor. Y después de actualizarlo, el enrutador vuelve a cambiar el flujo de solicitud a verde servidor.

Todo parece muy bueno y a primera vista no debería haber ningún problema.
Pero como vivimos en el mundo moderno, la opción con conmutación física indicada en el esquema clásico no nos conviene. Registre la información por ahora, volveremos a ella más tarde.

malos y buenos consejos

Observación: Los ejemplos a continuación muestran las utilidades/metodologías que uso, puedes usar absolutamente cualquier alternativa con funciones similares.

La mayoría de los ejemplos se cruzarán de una forma u otra con el desarrollo web (esto es una sorpresa), con PHP y Docker.

Los párrafos siguientes proporcionan una descripción práctica sencilla del uso de factores utilizando ejemplos específicos; si desea obtener más teoría sobre este tema, siga los enlaces anteriores a la fuente original.

1. Base de código

Utilice FTP y FileZilla para cargar archivos a los servidores uno a la vez, no almacene el código en ningún otro lugar que no sea el servidor de producción.

El proyecto siempre debe tener una única base de código, es decir, todo el código proviene de uno Git repositorio. Los servidores (producción, preparación, prueba1, prueba2...) utilizan código de ramas de un repositorio común. De esta manera logramos la coherencia del código.

2. Dependencias

Descargue todas las bibliotecas en carpetas directamente a la raíz del proyecto. Realice actualizaciones simplemente transfiriendo el nuevo código a la carpeta con la versión actual de la biblioteca. Instale todas las utilidades necesarias directamente en el servidor host donde se ejecutan 20 servicios más.

Un proyecto siempre debe tener una lista de dependencias claramente comprensible (por dependencias también me refiero al entorno). Todas las dependencias deben definirse y aislarse explícitamente.
Tomemos como ejemplo Compositor и Docker.

Compositor — un administrador de paquetes que te permite instalar bibliotecas en PHP. Composer le permite especificar versiones de forma estricta o flexible y definirlas explícitamente. Puede haber 20 proyectos diferentes en el servidor y cada uno tendrá una lista personal de paquetes y bibliotecas independientes del otro.

Docker — una utilidad que le permite definir y aislar el entorno en el que se ejecutará la aplicación. En consecuencia, al igual que con Composer, pero más detalladamente, podemos determinar con qué funciona la aplicación. Selecciona una versión específica de PHP, instala solo los paquetes necesarios para que el proyecto funcione, sin agregar nada extra. Y lo más importante, sin interferir con los paquetes y el entorno de la máquina host y otros proyectos. Es decir, todos los proyectos en el servidor que se ejecutan a través de Docker pueden utilizar absolutamente cualquier conjunto de paquetes y un entorno completamente diferente.

3. Configuración

Almacene las configuraciones como constantes directamente en el código. Constantes separadas para el servidor de prueba, separadas para producción. Vincule el funcionamiento de la aplicación dependiendo del entorno directamente en la lógica empresarial del proyecto utilizando construcciones if else.

Configuraciones - Sólo así pueden diferir las implementaciones de los proyectos. Idealmente, las configuraciones deberían pasarse a través de variables de entorno (env vars).

Es decir, incluso si almacena varios archivos de configuración .config.prod .config.local y les cambia el nombre en el momento de la implementación a .config (la configuración principal desde la cual la aplicación lee datos), este no será el enfoque correcto, ya que en este caso, la información de las configuraciones estará disponible públicamente para todos los desarrolladores de aplicaciones y los datos del servidor de producción se verán comprometidos. Todas las configuraciones deben almacenarse directamente en el sistema de implementación (CI/CD) y generarse para diferentes entornos con diferentes valores necesarios para un entorno específico en el momento de la implementación.

4. Servicios de terceros

Estar estrictamente vinculado al medio ambiente, utilizar diferentes conexiones para los mismos servicios en determinados entornos.

De hecho, este punto se superpone fuertemente con el punto de configuraciones, ya que sin este punto no se pueden realizar datos de configuración normales y, en general, la capacidad de configuración se reducirá a nada.

Todas las conexiones a servicios externos, como servidores de colas, bases de datos y servicios de almacenamiento en caché, deben ser iguales tanto para el entorno local como para el entorno de producción o de terceros. En otras palabras, en cualquier momento, al cambiar la cadena de conexión, puedo reemplazar las llamadas a la base #1 con la base #2 sin cambiar el código de la aplicación. O, de cara al futuro, como ejemplo, al escalar el servicio, no tendrá que especificar la conexión de ninguna manera especial para un servidor de caché adicional.

5. Construir, lanzar, ejecutar

Tenga solo la versión final del código en el servidor, sin posibilidad de revertir la versión. No es necesario llenar espacio en disco. ¡Cualquiera que piense que puede lanzar código a producción con un error es un mal programador!

Todas las etapas del despliegue deben estar separadas entre sí.

Tener la oportunidad de retroceder. Realiza lanzamientos con copias antiguas de la aplicación (ya ensambladas y listas para la batalla) guardadas en acceso rápido, para que en caso de errores puedas restaurar la versión anterior. Es decir, condicionalmente hay una carpeta. lanzamientos y carpeta corriente, y después de una implementación y ensamblaje exitosos, la carpeta corriente vinculado por un enlace simbólico a la nueva versión que se encuentra dentro lanzamientos con el nombre convencional del número de versión.

Aquí es donde recordamos la implementación Blue-Green, que le permite no solo cambiar entre códigos, sino también entre todos los recursos e incluso entornos con la capacidad de revertir todo.

6. Procesos

Almacene los datos del estado de la aplicación directamente dentro de la propia aplicación. Utiliza sesiones en la RAM de la propia aplicación. Utilice tanto intercambio como sea posible entre servicios de terceros. Confíe en el hecho de que la aplicación solo puede tener un proceso y no permite escalar.

En cuanto a las sesiones, almacene datos solo en un caché controlado por servicios de terceros (memcached, redis), por lo que incluso si tiene 20 procesos de aplicación en ejecución, cualquiera de ellos, habiendo accedido al caché, podrá continuar trabajando con el cliente en el mismo estado en el que el usuario estaba trabajando con la aplicación en otro proceso. Con este enfoque resulta que no importa cuántas copias de servicios de terceros utilices, todo funcionará con normalidad y sin problemas de acceso a los datos.

7. Enlace de puerto

Sólo el servidor web debe saber cómo trabajar con servicios de terceros. O mejor aún, instale servicios de terceros directamente dentro del servidor web. Por ejemplo, como módulo PHP en Apache.
Todos sus servicios deben ser accesibles entre sí mediante el acceso a alguna dirección y puerto (localgost:5432, localhost:3000, nginx:80, php-fpm:9000), es decir, desde nginx puedo acceder tanto a php-fpm como a postgres, y desde php-fpm hasta postgres y nginx y de hecho desde cada servicio puedo acceder a otro servicio. De esta forma, la viabilidad de un servicio no está ligada a la viabilidad de otro servicio.

8. Paralelismo

Trabaje con un proceso; de lo contrario, varios procesos no podrán llevarse bien entre sí.

Deje espacio para escalar. Docker swarm es genial para esto.
Docker Swarm es una herramienta para crear y gestionar grupos de contenedores tanto entre diferentes máquinas como entre un montón de contenedores en la misma máquina.

Usando swarm, puedo determinar cuántos recursos asignaré a cada proceso y cuántos procesos del mismo servicio lanzaré, y el balanceador interno, al recibir datos en un puerto determinado, los enviará automáticamente a los procesos. Así, al ver que la carga en el servidor ha aumentado, puedo agregar más procesos, reduciendo así la carga en ciertos procesos.

9. Disponibilidad

No utilice colas para trabajar con procesos y datos. Matar un proceso debería afectar a toda la aplicación. Si un servicio falla, todo falla.

Cada proceso y servicio se puede desactivar en cualquier momento y esto no debería afectar a otros servicios (por supuesto, esto no significa que el servicio no estará disponible para otro servicio, sino que otro servicio no se desactivará después de este). Todos los procesos deben finalizarse correctamente, de modo que cuando finalicen, no se dañen datos y el sistema funcione correctamente la próxima vez que lo encienda. Es decir, incluso en el caso de una terminación de emergencia, los datos no deben dañarse (el mecanismo de transacción es adecuado aquí, las consultas en la base de datos funcionan solo en grupos, y si al menos una consulta del grupo falla o se ejecuta con un error, entonces ninguna otra consulta del grupo finalmente falla).

10. Paridad de desarrollo/operación de aplicaciones

La producción, la puesta en escena y la versión local de la aplicación deben ser diferentes. En producción usamos el framework Yii Lite, y localmente Yii, ¡para que funcione más rápido en producción!

En realidad, todas las implementaciones y trabajos con código deberían realizarse en un entorno casi idéntico (no estamos hablando de hardware físico). Además, cualquier empleado de desarrollo debería poder implementar el código en producción si es necesario, y no un departamento de desarrollo especialmente capacitado, que solo gracias a una fuerza especial puede llevar la aplicación a producción.

Docker también nos ayuda con esto. Si se observan todos los puntos anteriores, el uso de Docker hará que el proceso de implementación del entorno tanto en producción como en la máquina local ingrese uno o dos comandos.

11. Registros

¡Escribimos registros en archivos y bases de datos! No limpiamos archivos ni bases de datos de registros. Compremos un disco duro con 9000 Peta bytes y está bien.

Todos los registros deben considerarse como una secuencia de eventos. La aplicación en sí no debe participar en el procesamiento de registros. Los registros deben enviarse a stdout o enviarse a través de un protocolo como udp, para que trabajar con registros no cree ningún problema para la aplicación. Graylog es bueno para esto. Graylog, que recibe todos los registros a través de udp (este protocolo no requiere esperar una respuesta sobre la recepción exitosa del paquete), no interfiere con la aplicación de ninguna manera y solo se ocupa de estructurar y procesar registros. La lógica de la aplicación no cambia para funcionar con dichos enfoques.

12. Tareas de administración

Para actualizar datos, bases de datos, etc., utilice un punto final creado por separado en la API; ejecutarlo 2 veces seguidas hará que todo se duplique. Pero no eres estúpido, no harás clic dos veces y no necesitamos migración.

Todas las tareas de administración deben realizarse en el mismo entorno que todo el código, en el nivel de versión. Es decir, si necesitamos cambiar la estructura de la base de datos, entonces no lo haremos manualmente cambiando los nombres de las columnas y agregando otras nuevas a través de algunas herramientas visuales de administración de bases de datos. Para tales cosas, creamos scripts separados: migraciones, que se ejecutan en todas partes y en todos los entornos de la misma manera con un resultado común y comprensible. Para todas las demás tareas, como llenar el proyecto con datos, se deben utilizar metodologías similares.

Ejemplo de implementación en PHP, Laravel, Laradock, Docker-Compose

PD: Todos los ejemplos se realizaron en MacOS. La mayoría de ellos también son adecuados para Linux. Usuarios de Windows, perdónenme, pero hace mucho que no trabajo con Windows.

Imaginemos una situación en la que no tenemos ninguna versión de PHP instalada en nuestro PC y nada de nada.
Instale las últimas versiones de Docker y Docker-compose. (esto se puede encontrar en Internet)

docker -v && 
docker-compose -v

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

1. poner Laradock

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

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

Respecto a Laradock, diré que es algo genial, que contiene muchos contenedores y cosas auxiliares. Pero no recomendaría usar Laradock como tal sin modificaciones en producción debido a su redundancia. Es mejor crear tus propios contenedores basados ​​en ejemplos en Laradock, esto estará mucho más optimizado, porque nadie necesita todo lo que está allí al mismo tiempo.

2. Configure Laradock para ejecutar nuestra aplicación.

cd laradock && 
cp env-example .env

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

2.1. Abra el directorio habr (la carpeta principal en la que se clona laradock) en algún editor. (En mi caso PHPStorm)

En esta etapa solo le damos un nombre al proyecto.

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

2.2. Inicie la imagen del espacio de trabajo. (En su caso, las imágenes tardarán algún tiempo en crearse)
Workspace es una imagen especialmente preparada para trabajar con el marco en nombre del desarrollador.

Entramos dentro del contenedor usando

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

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

2.3. Instalando Laravel

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

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

2.4. Después de la instalación, verificamos si se ha creado el directorio con el proyecto y eliminamos la redacción.

ls
exit
docker-compose down

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

2.5. Volvamos a PHPStorm y establezcamos la ruta correcta a nuestra aplicación laravel en el archivo .env.

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

3. Agrega todo el código a Git.

Para ello, crearemos un repositorio en Github (o en cualquier otro lugar). Vayamos al directorio habr en la terminal y ejecutemos el siguiente 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

Comprobemos si todo está en orden.

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

Para mayor comodidad, recomiendo usar alguna interfaz visual para Git, en mi caso es GitKraken. (aquí hay un enlace de referencia)

4. ¡Lanzamos!

Antes de comenzar, asegúrese de que no haya nada colgado en los puertos 80 y 443.

docker-compose up -d nginx php-fpm

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

Así, nuestro proyecto consta de 3 servicios separados:

  • nginx-servidor web
  • php-fpm - php para recibir solicitudes de un servidor web
  • espacio de trabajo - php para desarrolladores

De momento hemos conseguido que hayamos creado una aplicación que cumple con 4 puntos sobre 12, a saber:

1. Base de código — todo el código está en un repositorio (pequeña nota: podría ser correcto agregar Docker dentro del proyecto laravel, pero esto no es importante).

2. Dependencias - Todas nuestras dependencias están escritas explícitamente en application/composer.json y en cada Dockerfile de cada contenedor.

3. Servicios de respaldo — Cada uno de los servicios (php-fom, nignx, workspace) vive su propia vida y está conectado desde el exterior y cuando se trabaja con un servicio, el otro no se verá afectado.

4. Процессы — cada servicio es un proceso. Cada uno de los servicios no mantiene el estado interno.

5. Enlace de puerto

docker ps

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

Como podemos ver, cada servicio se ejecuta en su propio puerto y es accesible para todos los demás servicios.

6. Concurrencia

Docker nos permite generar múltiples procesos de los mismos servicios con equilibrio de carga automático entre ellos.

Detengamos los contenedores y pasemoslos por la bandera. --escala

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

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

Como podemos ver, se han creado copias del contenedor php-fpm. No necesitamos cambiar nada al trabajar con este contenedor. También seguimos accediendo a él en el puerto 9000, y Docker regula la carga entre contenedores por nosotros.

7. Disponibilidad - cada contenedor puede morir sin dañar al otro. Detener o reiniciar el contenedor no afectará el funcionamiento de la aplicación durante los lanzamientos posteriores. Cada contenedor también se puede levantar en cualquier momento.

8. Paridad de desarrollo/operación de aplicaciones - todos nuestros entornos son iguales. Al ejecutar el sistema en un servidor en producción, no tendrá que cambiar nada en sus comandos. Todo estará basado en Docker de la misma forma.

9. Inicio sesión — todos los registros en estos contenedores se transmiten y son visibles en la consola Docker. (en este caso, de hecho, con otros recipientes caseros puede que no sea así si no lo cuidas)

 docker-compose logs -f

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

Pero hay un problema: los valores predeterminados en PHP y Nginx también escriben registros en un archivo. Para cumplir los 12 factores es necesario desactivar escribir registros en un archivo en las configuraciones de cada contenedor por separado.

Docker también ofrece la posibilidad de enviar registros no solo a la salida estándar, sino también a elementos como Graylog, que mencioné anteriormente. Y dentro de Graylog, podemos operar los registros como queramos y nuestra aplicación no lo notará de ninguna manera.

10. Tareas de administración — todas las tareas de administración se resuelven con laravel gracias a la herramienta artesanal exactamente como les gustaría a los creadores de la aplicación de 12 factores.

Como ejemplo, mostraré cómo se ejecutan algunos comandos.
Entramos en el contenedor.

 
docker-compose exec workspace bash
php artisan list

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

Ahora podemos usar cualquier comando. (tenga en cuenta que no configuramos la base de datos y el caché, por lo que la mitad de los comandos no se ejecutarán correctamente, porque están diseñados para funcionar con el caché y la base de datos).

Desarrollo de aplicaciones y despliegue Blue-Green, basado en la metodología The Twelve-Factor App con ejemplos en php y docker

11. Configuraciones y 12. Construir, lanzar, ejecutar

Quería dedicar esta parte al Despliegue Azul-Verde, pero resultó ser demasiado extensa para este artículo. Escribiré un artículo aparte sobre esto.

En pocas palabras, el concepto se basa en sistemas CI/CD como Jenkins и CI de Gitlab. En ambos, puede establecer variables de entorno asociadas con un entorno específico. Por tanto, en esta situación se cumplirá el punto c Configuraciones.

Y el punto sobre Construir, lanzar, ejecutar se resuelve mediante funciones integradas con el nombre Tubería.

Tubería le permite dividir el proceso de implementación en muchas etapas, destacando las etapas de ensamblaje, lanzamiento y ejecución. También en Pipeline puedes crear copias de seguridad y, de hecho, cualquier cosa. Esta es una herramienta con un potencial ilimitado.

El código de la aplicación está en Github.
No olvide inicializar el submódulo al clonar este repositorio.

PD: Todos estos enfoques se pueden utilizar con otras utilidades y lenguajes de programación. Lo principal es que la esencia no difiere.

Fuente: habr.com

Añadir un comentario