Blog de Amazon Web Services (AWS)

Crear un pipeline con despliegue canary para Amazon EKS con AWS App Mesh

Por Tiago Reichert, Arquitecto de Soluciones AWS Brasil e
Bruno Emer, Arquitecto de Soluciones AWS Brasil

 

En esta publicación, demostraremos cómo utilizar diferentes servicios de AWS junto con AWS App Mesh para implementar una estrategia de despliegue canary para aplicaciones que se ejecutan en Amazon Elastic Kubernetes Service (Amazon EKS).

Mediante el uso de orquestadores de contenedores como Amazon EKS y Amazon ECS, los clientes pueden ejecutar millones de contenedores. Sin embargo, al aprovechar la potencia de estas herramientas, los clientes aún necesitan pensar en cómo administrar la conectividad, las operaciones y la seguridad entre microservicios en estas arquitecturas distribuidas para ejecutar grupos de servicios altamente descentralizados.

AWS App Mesh es un servicio de mesh que facilita la supervisión y el control de los servicios. App Mesh estandariza cómo se comunican sus servicios, proporcionando visibilidad integral y ayudando a garantizar una alta disponibilidad para sus aplicaciones. App Mesh proporciona visibilidad y controles de tráfico de red consistentes para cada servicio de una aplicación.

 

1. Despliegues canary

El proceso de despliegue de aplicaciones monolíticas suele ser doloroso y arriesgado, ya que todas las necesidades empresariales existen en un solo software y la infraestructura proporcionada para ejecutar estas aplicaciones debe actualizarse con frecuencia. Este enfoque puede causar muchos problemas cuando los despliegues no tienen éxito y las versiones anteriores de las aplicaciones ya no existen.

Hay, por supuesto, formas de lidiar con esto, como copias de seguridad y despliegues blue/green, donde se crea un entorno completamente nuevo y el tráfico cambia a la nueva versión de la aplicación, manteniendo el antiguo entorno activo y funcionando. La tecnología de contenedores también ayuda aquí jugando un papel importante en el empaquetado de todos los elementos necesarios para ejecutar aplicaciones, pero una cosa que no se aborda en estos enfoques es la experiencia del usuario, y aquí es donde el concepto de despliegues canary comienza a tener más sentido.

Con los despliegues canary, usted cambia el tráfico en pequeños incrementos porcentuales después de desplegar una nueva versión de una aplicación concreta. Un despliegue canary también puede monitorear el estado de la nueva versión, por lo que, si hay un problema, es posible cambiar automáticamente el tráfico a la versión anterior, disminuyendo drásticamente el impacto de los errores en las nuevas versiones de aplicaciones. Este enfoque ayuda no solo con nuevas implementaciones, sino que también aborda la necesidad de realizar pruebas en microservicios complejos y distribuidos, donde puede enviar una cantidad específica de tráfico a versiones más recientes de manera controlada:

 

 

2. Descripción de la arquitectura

El siguiente diagrama de arquitectura representa una descripción general de los servicios de AWS que se

utilizarán para crear el pipeline:

 

 

Para demostrar esta arquitectura, utilizaremos una aplicación llamada Yelb. Yelb permite a los usuarios votar sobre un conjunto de alternativas, como restaurantes, y actualiza los gráficos dinámicamente en función de los votos. Además, Yelb realiza un seguimiento del número de páginas vistas y muestra el nombre de host yelb-appserver que cumple con la solicitud de API en una votación o actualización de página. Los componentes de Yelb incluyen:

  • Una interfaz llamada yelb-ui que es responsable de proporcionar código JS al navegador.
  • Un servidor de aplicaciones llamado yelb-appserver, una aplicación Sinatra que lee y escribe en un servidor de caché (redis-server) y una base de datos Postgres (yelb-db).
  • Redis almacena el número de páginas vistas y Postgres almacena los votos.

Descripción general de la arquitectura de Yelb:

 

 

Yelb utiliza discos efímeros para todos los contenedores. La ejecución de bases de datos de esta manera se realiza únicamente con fines de demostración.

 

3. Configurar la infraestructura

Durante los próximos pasos de esta publicación, utilizaremos la región de AWS llamada Oregón.

Para los siguientes pasos, necesitará tener un entorno con algunas herramientas. Utilizamos una instancia de AWS Cloud9 para ejecutar este tutorial. Si desea crear una instancia de Cloud9 en su cuenta, siga los pasos del taller de EKS desde el capítulo «Crear un espacio de trabajo» hasta «Actualizar la configuración de IAM para su espacio de trabajo».

3.1 Requisitos

Existen algunos requisitos para instalar y configurar antes de crear el pipeline. Comience por clonar el repositorio de GitHub:

git clone https://github.com/aws/aws-app-mesh-examples.git
cd aws-app-mesh-examples/blogs/eks-canary-deployments-pipeline/

Para su comodidad, hemos creado algunos scripts que se encuentran dentro de la carpeta de configuración de los recursos que acaba de descargar. Estos scripts están diseñados para su uso con una instancia de AWS Cloud9. Siéntete libre de leerlos si quieres saber exactamente lo que hacen.

Necesitará jq, eksctl, kubectl, aws-cli y timón instalados mientras ejecuta los siguientes pasos:

./setup/install_dependencies.sh

También tendrá que exportar algunas variables de entorno (puede personalizar estas variables de acuerdo a sus necesidades):

./setup/export_environment_variables.sh && source ~/.bash_profile

3.2 Clúster de Amazon EKS

Amazon EKS es un servicio gestionado que facilita el uso de Kubernetes en AWS sin tener que instalar, operar y mantener su propio plano de control de Kubernetes. Kubernetes es un sistema de orquestación de código abierto para automatizar el despliegue, escalado y administración de aplicaciones contenerizadas.

Ahora vamos a crear un clúster de EKS para ser utilizado durante los siguientes pasos:

./setup/create_eks_cluster.sh

¡Se tarda unos 15 minutos en crear el clúster, siéntase libre de tomar una taza de café! Para obtener más información sobre cómo crear el clúster, consulte esta documentación. Una vez completado, puede probar la conectividad del clúster de la siguiente manera:

$ kubectl get svc  
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   172.20.0.1   <none>        443/TCP   14m

3.3 AWS App Mesh Controller para Kubernetes

El controlador AWS App Mesh para Kubernetes le permite administrar recursos de AWS App Mesh, como mesh, servicios virtuales, nodos virtuales, rutas virtuales y rutas a través de Kubernetes. También agrega automáticamente imágenes sidecar del contenedor de App Mesh a las especificaciones del pod Kubernetes. Para obtener más información, puede consultar esta documentación.

Si está utilizando un clúster EKS existente, debe confirmar que no hay ninguna versión preliminar instalada:

curl -o pre_upgrade_check.sh https://raw.githubusercontent.com/aws/eks-charts/master/stable/appmesh-controller/upgrade/pre_upgrade_check.sh


chmod +x pre_upgrade_check.sh && ./pre_upgrade_check.sh

Debería devolver «Su clúster está listo para la actualización. Continúe con las instrucciones de instalación».

A continuación, instale el controlador App Mesh:

./setup/install_appmesh_controller.sh

3.4 Amazon CloudWatch Container Insights

CloudWatch Container Insights le permite recopilar, agregar y resumir métricas y registros de sus aplicaciones contenerizadas y microservicios. Las métricas incluyen la utilización de recursos como CPU, memoria, disco y red. Container Insights también proporciona información de diagnóstico, como errores de reinicio de contenedores, para ayudarle a aislar y resolver problemas rápidamente. Para obtener más información, puede consultar esta documentación.

./setup/install_cloudwatch_container_insights.sh

 

4. Creación del pipeline

Ahora que tiene todos los requisitos instalados y configurados, puede continuar con la creación del pipeline.

4.1 AWS Lambda Layer

Una AWS Lambda layer que tenga kubectl, awscli, helm y jq se utilizará en nuestro pipeline para comunicarse con el clúster de Amazon EKS. Para obtener más información acerca de la Lambda layer utilizada, vaya a este aws-samples:

./setup/aws_lambda_layer.sh

Sólo continúe con el siguiente paso, si el último comando devolvió CREATE_COMPLETE.

4.2 Pila compartida de AWS CloudFormation Stack

La pila compartida de AWS CloudFormation contiene varias funciones de Lambda y una máquina de estados AWS Step Functions que será responsable de la etapa de despliegue del pipeline. Dado que acepta todos los parámetros de configuración como entrada, puede utilizar los mismos recursos para todos los despliegues.

./setup/create_shared_cloudformation_stack.sh

Sólo continúe con el siguiente paso, si el último comando devolvió CREATE_COMPLETE.

Después de crear la pila de AWS CloudFormation, deberá agregar el role de IAM de AWS Lambda a partir de salida de AWS CloudFormation a Kubernetes RBAC para permitir despliegues en el clúster de Kubernetes.

./setup/add_iam_role_to_rbac.sh

4.3 Pila del Pipeline de AWS CloudFormation

La pila del pipeline de AWS CloudFormation está diseñada para utilizarse para cada microservicio que usted posee. La pila creará un repositorio de AWS CodeCommit y el pipeline que se activará mediante nuevos commit en la rama principal de ese repositorio.

Para fines de demostración, creará cuatro pilas con microservicios de Yelb. Puede cambiar la variable de entorno denominada USE_SAMPLE_MICROSERVICES a 'False' para crear todos los recursos necesarios para el pipeline con un repositorio vacío de AWS CodeCommit que se utilizará con su propio código fuente.

Antes de desplegar microservicios, necesitará un Namespace de Kubernetes y un mesh de AWS App Mesh para los microservicios. Vamos a crear un namespace y un mesh llamados yelb:

NAMESPACE=yelb MESH=yelb envsubst < setup/namespace_and_mesh.yml | kubectl apply -f -

Ahora podemos crear microservicios. Dado que la arquitectura Yelb contiene cuatro microservicios, hemos creado un script que creará todas las pilas necesarias de AWS CloudFormation (puede abrir el script para ver sus detalles):

./setup/create_microservice_pipeline_stack.sh

Sólo continúe con el siguiente paso, si el último comando devolvió All four stacks created successfully!

 

5. Pruebas del pipeline

Ahora que ha construido completamente la arquitectura, puede comenzar a examinarla para ver cómo funciona.

5.1 Archivos de configuración

En primer lugar, echemos un vistazo a los repositorios de AWS CodeCommit, encontrará una carpeta llamada specfiles en cada repositorio con 3 archivos en él.

  1. yml tiene los pasos para crear la imagen de Docker y guardarla en Amazon ECR. También agrega dos parámetros adicionales para deploy.json:

a. container_image se agrega al archivo deploy.json con el URI de imagen de Docker después de cargarlo en Amazon ECR.

b. config_file se agrega al archivo deploy.json con contenido kubernetes_template.yml codificado en base64  .

  1. json tiene los parámetros de configuración para desplegar el microservicio.

a. cluster_name es el nombre del clúster EKS en el que desea desplegar.

b. kubernetes_namespace es el nombre del namespace de Kubernetes en el que desea desplegar.

c. microservice_name es el nombre del microservicio.

d. percentage_step representa la cantidad de tráfico cambiado a la nueva versión en incrementos.

e. wait_time representa el tiempo en segundos para esperar entre cada intercambio de tráfico.

f. failure_threshold_value es opcional y se utiliza para especificar el código HTTP de respuesta máxima permitida 5xx antes de activar una reversión automática. (predeterminado = 0)

g. failure_threshold_time es opcional y se utiliza para especificar el intervalo de tiempo en segundos para contar la cantidad de respuesta código HTTP 5xx. El valor mínimo recomendado es 60 porque el filtro de métricas de CloudWatch utiliza agregados e informes cada minuto. (predeterminado = 600)

  1. yml es la plantilla del specfile para crear el nuevo microservicio con kubectl. Notará que tiene algunas variables:

a. KUBERNETES_NAMESPACE se reemplazará con el valor kubernetes_namespace del archivo deploy.json .

b. MICROSERVICE_NAME se reemplazará con el valor microservice_name del archivo deploy.json .

c. CONTAINER_IMAGE se reemplazará con la nueva imagen de contenedor creada durante la ejecución del pipeline y se almacenará dentro de Amazon ECR.

d. CANARY_VERSION será reemplazado por la nueva versión durante el despliegue.

e. CANARY_ROUTES será reemplazado por incrementos de intercambio de tráfico durante el despliegue.

Todo lo demás dentro de los repositorios de AWS CodeCommit es el código fuente de la aplicación Yelb.

5.2 Recursos del pipeline

La forma más sencilla de examinar los recursos que crea es abrir AWS CodePipeline. Verá los cuatro pipelines que creó anteriormente

 

 

Puede abrir uno de ellos y ver los pasos Source, Build y Deploy. Todos estos pasos son personalizables. Puede agregar antes del despliegue, por ejemplo, comprobaciones de seguridad o aprobaciones manuales.

 

 

  1. El paso Source supervisa si hay algún cambio en la rama maestra del repositorio de AWS CodeCommit. Puede acceder al repositorio haciendo clic en el vínculo AWS CodeCommit dentro del paso.
  2. El paso Build crea la imagen de Docker con AWS CodeBuild y la almacena en Amazon ECR. Puede ver los registros de compilación haciendo clic en el vínculo Detalles del paso.
  3. El paso Deploy activa la máquina de estado de AWS Step Functions creada por la pila compartida de AWS CloudFormation. Puede ver su estado haciendo clic en el enlace Detalles.

 

 

 

 

 

 

 

 

 

 

Haga clic en el enlace de Detalles del paso Deploy y verá la entrada y salida de cada paso, así como las funciones de AWS Lambda y los registros de ejecución:

 

 

Un despliegue exitoso que cambió el 100% del tráfico a la nueva versión y pasó todas las comprobaciones de estado se parece a las siguientes imágenes:

 

 

5.3 Despliegue de una nueva versión

Ahora veamos que la aplicación Yelb funciona y hagamos algunos cambios para ver cómo se comporta el pipeline.

echo "http://$(kubectl get -nyelb service/yelb-ui-1 -o json | jq -r '.status.Loadbalancer.Ingress [0] .hostname)»

Abra la URL devuelta por el comando anterior en su navegador preferido. Debería ver una página similar a la siguiente (el nombre DNS puede tardar unos minutos en propagarse):

 

 

Haga clic en algunos botones para votar y ver cómo se actualizan los valores. ¿Notaste algo malo al votar?

Intencionalmente agregamos un problema al microservicio yelb-appserver para que se incremente en dos cada vez que hay una votación. Ahora solucionemos este problema y veamos cómo se aplica.

Abra AWS CodeCommit y vaya al repositorio yelb-appserver, abra el archivo modules/restaurantsdbupdate.rb y haga clic en el botón Editar para solucionar el problema. Cambie la línea:

 

con.prepare('statement1', 'UPDATE restaurants SET count = count +2 WHERE name = $1')

por:

con.prepare('statement1', 'UPDATE restaurants SET count = count +1 WHERE name = $1')

y haga commit de los cambios.

 

Vaya a AWS CodePipeline y después de unos segundos verá que el yelb-appserver-pipeline está en curso. Ábralo para ver el progreso del despliegue. Espere hasta llegar a la etapa de Deploy y, a continuación, actualice la pestaña del navegador con la aplicación Yelb varias veces. Verá que la versión de App Server (como se muestra en la captura de pantalla a continuación) cambiará entre yelb-appserver-1 y yelb-appserver-2, es decir, se está produciendo un despliegue canary.

 

 

Abra el router virtual de AWS App Mesh para el microservicio yelb-appserver y podrá ver cómo son los pesos en este momento. También puede abrir el archivo deploy.json en el repositorio de AWS CodeCommit yelb-appserver para ver los parámetros de percentage_step y wait_time para ver cuánto tiempo tomará cambiar todo el tráfico. Para este ejemplo, los valores porcentage_step : 10 y wait_time: 60 se han utilizado y tardará un total de 10 minutos en cambiar todo el tráfico.

Una vez completado el despliegue, puede intentar votar por la aplicación Yelb de nuevo y ver que ahora aumenta los votos uno a uno.

5.4 Despliegue de una versión que desencadena una reversión

Abra el archivo yelb-appserver.rb desde el repositorio de AWS CodeCommit yelb-appserver y cambie el puerto de la aplicación en la configuración de producción (línea 33) de 4567 a 4568 y haga commit de los cambios.

Esto activará el yelb-appserver-pipeline y desplegará una nueva versión del microservicioyelb-appserver que no funciona. Abra yelb-appserver-pipeline en AWS CodePipeline y espere hasta que la etapa de despliegue esté en curso. A continuación, haga clic en Detalles en la etapa de despliegue. En esta página, verá el flujo visual durante el despliegue.

Intente actualizar la aplicación Yelb varias veces. Verás que a veces al actualizar, no se devuelven datos de votación y no puedes votar. Esto se debe a que está siendo redirigido a la nueva versión que no funciona.

Espere unos minutos y verá en el flujo visual que se activó una reversión porque la nueva versión no pasó la comprobación de estado. Es importante tener en cuenta que la comprobación de estado es una función de AWS Lambda que se puede personalizar si es necesario.

 

 

Ahora puede actualizar la aplicación Yelb varias veces de nuevo y funcionará correctamente usando la versión anterior (yelb-appserver-2).

 

6. Conclusión

En esta publicación, demostramos cómo puede utilizar AWS App Mesh e implementar una estrategia de despliegue canary junto con otros servicios de AWS, como AWS CodePipeline y AWS Step Functions.

Otra forma de realizar despliegues canary con AWS App Mesh y Amazon EKS es utilizar Weave Flagger. Flagger utiliza métricas de Prometheus para determinar el éxito o el fracaso de los despliegues canary y utiliza controles de enrutamiento de App Mesh para cambiar el tráfico entre el despliegue actual y el canary.

Además, algunos enlaces útiles si desea profundizar en AWS App Mesh:

Puede realizar un seguimiento de las próximas funciones a través de la hoja de ruta de App Mesh y experimentar nuevas características utilizando el canal de vista previa de App Mesh. También puedes unirte a nosotros en la comunidad de Slack de App Mesh para compartir experiencias y discutir con el equipo y tus colegas.

 

Este artículo fue traducido del Blog de AWS en Inglés.

 

 


Sobre los autores

Tiago es arquitecto de soluciones en AWS Brasil con el objetivo de ayudar a los socios ISV en su viaje a la nube. Tiene un gran interés en IoT, contenedores y DevOps.

 

 

 

 

Bruno es arquitecto de soluciones en São Paulo, Brasil. Cuando no estás trabajando con clientes o escribiendo contenido, le gusta viajar y escuchar música, especialmente samba y R&B.

 

 

 

 

Herbert es arquitecto de soluciones en Bogotá, Colombia.