Cómo implementamos la entrega continua de actualizaciones a la plataforma del cliente

En True Engineering, hemos configurado el proceso de entrega continua de actualizaciones a los servidores del cliente y queremos compartir esta experiencia.

Primero, desarrollamos un sistema en línea para el cliente y lo implementamos en nuestro propio clúster de Kubernetes. Ahora nuestra solución altamente cargada se ha trasladado a la plataforma del cliente, para lo cual hemos configurado el proceso de implementación continua totalmente automático. Gracias a esto, hemos acelerado el tiempo de comercialización: entrega de cambios en el entorno del producto.

En este artículo, hablaremos sobre todas las etapas del proceso de Implementación continua (CD) o la entrega de actualizaciones a la plataforma del cliente:

  1. ¿Cómo comienza este proceso?
  2. sincronización con el repositorio Git del cliente,
  3. montaje de backend y frontend
  4. despliegue automático de la aplicación en un entorno de prueba,
  5. implementación automática en Prod.

En el proceso compartiremos los detalles de la configuración.



1. Iniciar CD


La implementación continua comienza con el hecho de que el desarrollador publica los cambios en la rama de lanzamiento de nuestro repositorio Git.

Nuestra aplicación funciona sobre la base de la arquitectura de microservicios y todos sus componentes se almacenan en un repositorio. Gracias a esto, todos los microservicios se ensamblan e instalan, incluso si uno de ellos ha cambiado.

Organizamos el trabajo a través de un repositorio por varias razones:

  • Facilidad de desarrollo: la aplicación se está desarrollando activamente, por lo que puede trabajar de inmediato con todo el código.
  • Una única canalización de CI / CD que garantiza que la aplicación como un solo sistema pase todas las pruebas y se entregue al entorno de producción del cliente.
  • Excluimos la confusión en las versiones: no tenemos que almacenar un mapa de versiones de microservicios y describir nuestra configuración para cada microservicio en los scripts de Helm.

2. Sincronización con el repositorio Git del código fuente del cliente


Los cambios realizados se sincronizan automáticamente con el repositorio Git del cliente. Allí, se configura el ensamblaje de la aplicación, que comienza después de actualizar la rama, y ​​la implementación para producir. Ambos procesos ocurren en su entorno desde el repositorio de Git.

No podemos trabajar directamente con el repositorio del cliente, porque necesitamos nuestros propios entornos de desarrollo y prueba. Usamos nuestro repositorio Git para estos fines: está sincronizado con su repositorio Git. Tan pronto como el desarrollador publique los cambios en la rama correspondiente de nuestro repositorio, GitLab envía inmediatamente estos cambios al cliente.



Después de eso, debes hacer un ensamblaje. Consiste en varias etapas: montaje del backend y frontend, prueba y entrega al producto.

3. Construye el backend y la interfaz


El ensamblaje de backend y frontend son dos tareas paralelas que se realizan en el sistema GitLab Runner. Su configuración del ensamblaje original se encuentra en el mismo repositorio.

Tutorial para escribir un script YAML para construir en GitLab .

GitLab Runner recoge el código del repositorio deseado, recopila el comando de compilación de la aplicación Java y lo envía al registro de Docker. Aquí recopilamos el backend y la interfaz, obtenemos imágenes de Docker, que colocamos en el repositorio del lado del cliente. Para administrar las imágenes de Doker, use el complemento Gradle .

Sincronizamos las versiones de nuestras imágenes con la versión del lanzamiento, que se publicará en Docker. Para un funcionamiento fluido, realizamos varias configuraciones:

1. Entre el entorno de prueba y los contenedores de comestibles no se vuelven a montar. Hicimos la parametrización para que el mismo contenedor pudiera funcionar sin reconstruir con todas las configuraciones, variables de entorno y servicios tanto en el entorno de prueba como en el producto.

2. Para actualizar la aplicación a través de Helm, debe especificar su versión. Tenemos el ensamblaje del backend, la interfaz de usuario y la actualización de la aplicación: estas son tres tareas diferentes, por lo que es importante usar la misma versión de la aplicación en todas partes. Para esta tarea, utilizamos datos del historial de Git, ya que tenemos una configuración de clúster K8S y las aplicaciones están en el mismo repositorio de Git.

Obtenemos la versión de la aplicación de los resultados del comando
git describe --tags --abbrev=7 .

4. Despliegue automático de todos los cambios en un entorno de prueba (UAT)


El siguiente paso en este script de compilación es actualizar automáticamente el clúster K8S. Esto sucede siempre que la aplicación completa esté ensamblada y todos los artefactos se publiquen en el Registro Docker. Después de eso, comienza la actualización del entorno de prueba.

La actualización del clúster se inicia utilizando Helm Update . Si, como resultado, algo salió mal, Helm revertirá automática e independientemente todos sus cambios. Su trabajo no necesita ser controlado.

Junto con el ensamblaje, entregamos la configuración del clúster K8S. Por lo tanto, el siguiente paso es actualizarlo: configMaps, implementaciones, servicios, secretos y cualquier otra configuración de K8S que hayamos cambiado.

Después de eso, Helm lanza RollOut y actualiza la aplicación en un entorno de prueba. Antes de que la aplicación se implemente en el producto. Esto se hace para que los usuarios verifiquen manualmente las características comerciales que hemos publicado en el entorno de prueba.

5. Implemente automáticamente todos los cambios en Prod


Para implementar la actualización en el entorno del producto, todo lo que queda es hacer clic en un botón en GitLab, y los contenedores se entregan inmediatamente al entorno del producto.

Una misma aplicación puede funcionar sin reconstrucción en diferentes entornos: prueba y producción. Usamos los mismos artefactos sin cambiar nada en la aplicación, y establecemos los parámetros desde el exterior.

La parametrización flexible de la configuración de la aplicación depende del entorno en el que se ejecutará esta aplicación. Eliminamos todos los ajustes del entorno: todo se parametriza a través de la configuración de K8S y los parámetros de Helm. Cuando Helm implementa un ensamblaje en un entorno de prueba, los parámetros de prueba se aplican a él y los parámetros del producto se aplican al entorno del producto.

Lo más difícil fue parametrizar todos los servicios y variables utilizados, que dependen del entorno, y traducirlos en variables de entorno y una descripción-configuración de los parámetros de entorno para Helm.

Los parámetros de la aplicación utilizan variables de entorno. Sus valores se establecen en contenedores usando el mapa de configuración K8S, que se crea con plantillas usando las plantillas Go. Por ejemplo, configurar una variable de entorno para un nombre de dominio se puede hacer así:

 APP_EXTERNAL_DOMAIN: {{ (pluck .Values.global.env .Values.app.properties.app_external_domain | first) }} 

.Values.global.env : el nombre del entorno (prod, stage, UAT) se almacena en esta variable.
.Values.app.properties.app_external_domain : en esta variable, en el archivo .Values.yaml establecemos el dominio deseado

Al actualizar la aplicación, Helm crea el archivo configmap.yaml a partir de las plantillas y completa el valor APP_EXTERNAL_DOMAIN con el valor requerido según el entorno en el que comienza la actualización de la aplicación. Esta variable ya está establecida en el contenedor. El acceso a él es desde la aplicación, respectivamente, en cada entorno de la aplicación habrá un valor diferente de esta variable.

Relativamente reciente, Spring Cloud introdujo el soporte K8S, incluido el trabajo con configMaps: Spring Cloud Kubernetes . Si bien el proyecto se está desarrollando activamente y cambiando drásticamente, no podemos usarlo en la producción. Pero monitoreamos activamente su condición y la usamos en configuraciones DEV. Tan pronto como se estabilice, cambiaremos de usar variables de entorno.

Total


Por lo tanto, la implementación continua está en funcionamiento. Todas las actualizaciones ocurren con el clic de un botón. La entrega de cambios al entorno alimentario es automática. Y, lo que es más importante, las actualizaciones no detienen el sistema.



Planes futuros: migración base automática


Pensamos en actualizar la base de datos y la capacidad de revertir estos cambios. Después de todo, dos versiones diferentes de la aplicación funcionan simultáneamente: la anterior funciona y la nueva se eleva. Y apagaremos la anterior solo cuando estemos convencidos de que la nueva versión está funcionando. La migración de la base de datos debería permitir trabajar con ambas versiones de la aplicación.

Por lo tanto, no podemos simplemente cambiar el nombre de la columna u otros datos. Pero podemos crear una nueva columna, copiar los datos de la columna anterior en ella y escribir activadores que, cuando se actualizan los datos, los copie y actualice simultáneamente en otra columna. Y después de la implementación exitosa de la nueva versión de la aplicación, después del período de soporte posterior al lanzamiento, podemos eliminar la columna anterior y el activador que se ha vuelto innecesario.

Si la nueva versión de la aplicación no funciona correctamente, podemos volver a la versión anterior, incluida la versión anterior de la base de datos. En una palabra, nuestros cambios permitirán trabajar simultáneamente con varias versiones de la aplicación.

Planeamos automatizar la migración de la base de datos a través del trabajo K8S incorporándola en el proceso del CD. Y seguramente compartiremos esta experiencia en Habré.

Source: https://habr.com/ru/post/447812/


All Articles