Implementación de Canary utilizando Jenkins-X Istio Flagger
Realizaremos la implementación de Canary manualmente a través de GitOps y crearemos/modificaremos los recursos principales de Kubernetes. Este artículo está destinado principalmente a la introducción. con cómo funciona la implementación en Kubernetes Canary, ya que existen métodos de automatización más efectivos, que consideraremos en los siguientes artículos.
Con la estrategia Canary, las actualizaciones se aplican primero solo a un subconjunto de usuarios. A través de monitoreo, datos de registro, pruebas manuales u otros canales de retroalimentación, la versión se prueba antes de lanzarse a todos los usuarios.
Implementación de Kubernetes (actualización continua)
La estrategia predeterminada para la implementación de Kubernetes es la actualización continua, donde se lanza una cierta cantidad de pods con nuevas versiones de las imágenes. Si se crearon sin problemas, los pods con versiones antiguas de imágenes se finalizan y se crean nuevos pods en paralelo.
GitOps
Usamos GitOps en este ejemplo porque:
usando Git como única fuente de verdad
Usamos Git Operations para la compilación y la implementación (no se necesitan comandos distintos de git tag/merge)
ejemplo
Adoptemos una buena práctica: tener un repositorio para el código de la aplicación y otro para la infraestructura.
Repositorio de aplicaciones
Esta es una API Python+Flask muy simple que devuelve una respuesta como JSON. Construiremos el paquete a través de GitlabCI y enviaremos el resultado al Registro de Gitlab. En el registro tenemos dos versiones de lanzamiento diferentes:
wuestkamp/k8s-deployment-example-app:v1
wuestkamp/k8s-deployment-example-app:v2
La única diferencia entre ellos es el cambio en el archivo JSON devuelto. Utilizamos esta aplicación para visualizar lo más fácilmente posible con qué versión nos estamos comunicando.
Repositorio de infraestructura
En este nabo implementaremos vía GitlabCI en Kubernetes, .gitlab-ci.yml выглядит следующим образом:
Tenga en cuenta que app-deploy aún no tiene ninguna réplica definida.
Realizar la implementación inicial
Para iniciar la implementación inicial, puede iniciar la canalización de GitlabCI manualmente en la rama maestra. Después kubectl debería generar lo siguiente:
Nosotros vemos app implementación con 10 réplicas y app-canary con 0. También hay un LoadBalancer desde el que podemos acceder a través de curl vía IP externa:
while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done
Vemos que nuestra aplicación de prueba solo devuelve "v1".
Ejecutando la implementación de Canary
Paso 1: lanzar una nueva versión para algunos usuarios
Establecemos el número de réplicas en 1 en el archivo implementar-canary.yaml y la imagen de la nueva versión:
Enviamos estos cambios al repositorio desde donde comenzará la implementación (a través de GitlabCI) y vemos el resultado:
Nuestro Servicio apuntará a ambas implementaciones, ya que ambas tienen el selector de aplicaciones. Debido a la aleatorización predeterminada de Kubernetes, deberíamos ver respuestas diferentes para aproximadamente el 10 % de las solicitudes:
El estado actual de nuestra aplicación (GitOps, tomado de Git as a Single Source Of Truth) es la presencia de dos implementaciones con réplicas activas, una para cada versión.
~10% de los usuarios se familiarizan con una nueva versión y la prueban sin querer. Ahora es el momento de comprobar si hay errores en los registros y en los datos de seguimiento para encontrar problemas.
Paso 2: Lanzar la nueva versión para todos los usuarios
Decidimos que todo salió bien y ahora necesitamos implementar la nueva versión para todos los usuarios. Para ello simplemente actualizamos deploy.yaml instalar una nueva versión de la imagen y el número de réplicas igual a 10. En deploy-canary.yaml volvemos a establecer el número de réplicas en 0. Después de la implementación, el resultado será el siguiente:
En resumen
Para mí, ejecutar la implementación manualmente de esta manera me ayuda a comprender con qué facilidad se puede configurar usando k8s. Dado que Kubernetes le permite actualizar todo a través de una API, estos pasos se pueden automatizar mediante scripts.
Otra cosa que debe implementarse es un punto de entrada del probador (LoadBalancer o mediante Ingress) a través del cual solo se puede acceder a la nueva versión. Se puede utilizar para la navegación manual.
En artículos futuros, revisaremos otras soluciones automatizadas que implementan la mayor parte de lo que hemos hecho.