Blog de Amazon Web Services (AWS)

Uso de multi-container pods para logs de aplicaciones stateful en Amazon EKS

Por Lucas Duarte, Arquitecto Especialista en Containers AWS
Vinicius Silva, Arquitecto de Soluciones AWS

 

En la actualidad hay muchas organizaciones que ya trabajan con aplicaciones en contenedores y muchas otras que están en proceso de migración para utilizarlas en producción, pero hay algunos supuestos básicos que debemos tener en cuenta al crear contenedores y una de las más importantes es trabajar con aplicaciones stateless en lugar de stateful.

Sabemos que, a menudo, aplicar cambios dentro de nuestras aplicaciones puede ser un trabajo costoso y difícil para el equipo de desarrollo debido a que en su mayor parte la prioridad de este tipo de actividad, cuando no es crítica, es baja. Y en las aplicaciones stateful, uno de los problemas más comunes que podemos destacar son los logs, que en la mayoría de las aplicaciones legacy persisten en discos y no se envían a stdout (standard out), como indican las mejores prácticas de The Twelve-Factor App.

En este blog, mostraremos de manera simple cómo utilizar un pod de varios contenedores (pod multicontenedor) para que los logs de las aplicaciones que se conservan en el disco se envíen a stdout y sean recolectados un procesador de logs como Fluentd o Fluent Bit en un clúster de Amazon EKS.

 

¿Qué es un Pod Multi-contenedor?

Por definición, en la documentación oficial de Kubernetes, los pods son las unidades informáticas desplegables más pequeñas que puedes crear y administrar.

Un pod de Kubernetes puede tener uno o varios contenedores asociados; estos contenedores de este pod comparten algunos recursos, como almacenamiento y redes. De esta forma se produce la interacción entre contenedores (Cross-container Interaction) y es cuando los contenedores comparten el mismo pod e interactúan entre sí mediante recursos compartidos.

Caso de uso

En nuestro escenario, crearemos una aplicación stateful en Python que utiliza una biblioteca de generación de logs, por lo que la aplicación persiste algunos datos en el disco y, en nuestro caso, los logs. De esta forma, usaremos pods de varios contenedores para recopilar los logs de esta aplicación que persisten en el disco y los enviaremos a stdout. Una vez enviados a standard out, se recopilarán a través de un Daemonset de Fluent Bit y se enviarán a Amazon CloudWatch Logs. Cada demostración se realizará utilizando un clúster de Kubernetes de Amazon EKS.

 

Requisitos previos

  • Tener una cuenta de AWS. Si no tienes una, puedes crearla aquí y aprovechar la capa gratuita de AWS.
  • AWS CLI instalada y configurada con credenciales para tu cuenta de AWS.
  • Docker para el build de imágenes.
  • kubectl para ejecutar comandos y administrar nuestro clúster de Amazon EKS.
  • eksctl para crear de forma simple un clúster de Amazon EKS.

 

Solución

A continuación tenemos una arquitectura representativa (Figura 1.1) de nuestra solución que utiliza varios contenedores en un pod para recopilar logs y enviarlos a stdout, por lo que podemos usar un log forwarder  para capturarlos y enviarlos a un agregador de logs como Amazon CloudWatch Logs o Amazon Elasticsearch. Utilizaremos un volumen compartido entre contenedores para poder mapear los logs de nuestra aplicación a la salida stdout del contenedor sidecar. Este mapeo se realiza mediante el comando tail de Linux en el archivo de logs montado en el volumen compartido entre contenedores (figura 1.2)

 

Figura 1.1: Arquitectura de pods multi-containers  de nuestra solución

 

Figura 1.2 — Declaración de Contenedores Sidecar para capturar logs

 

 

 

 

 

 

Nota: Para la implementación de esta solución, utilizaremos la región us-east-1 (North Virginia), por lo que tus credenciales de CLI de AWS deben configurarse para utilizar esta región. Puedes utilizar otras regiones siempre que se modifiquen algunos parámetros en el manifiesto de implementación de clúster de Amazon EKS. También podemos actualizar el manifiesto para utilizar variables de entorno según la región seleccionada al momento de establecer tus credenciales.

Los pasos que se indican a continuación se utilizarán para guiarte durante la implementación de la solución.

 

Paso 1: Aprovisionar el clúster de Amazon EKS

  1. Clona el repositorio git disponible aquí
git clone https://github.com/aws-samples/eks-multi-container-pod-logging.git
  1. Ejecuta el comando para crear el clúster de Amazon EKS:
eksctl create cluster -f kubernetes-cluster-us-east-1.yaml

Aproximadamente toma 15 minutos aprovisionar el clúster. Mientras esperamos a que se cree el clúster, en paralelo, podemos ejecutar el paso 2.

  1. Actualiza el contexto del archivo ~/.kube/config para acceder al clúster a través de kubectl:
aws eks --region us-east-1 update-kubeconfig —name kubelogs-cluster
  1. Prueba tu acceso al clúster de EKS:
kubectl get nodes

Paso 2: Crear una imagen Docker y enviarla a Amazon ECR

  1. Crea un repositorio ECR para que podamos insertar la imagen docker:
aws ecr create-repository —repository-name multi-container-pod-demo
  1. Crea el build de la imagen de Docker:
cd log-app && docker build -t multi-container-pod-demo .
  1. Autentica el cliente Docker en el registry de Amazon ECR:
aws ecr get-login-password --region <REGION> | docker login --username AWS --password-stdin <ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com

Sustituye las <variables> en el comando anterior y los siguientes comandos  según la región (en nuestro caso, la región utilizada es us-east-1) y el ID de su cuenta de AWS.

  1. Etiqueta tu imagen para que hagamos push:
docker tag multi-container-pod-demo:latest <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/multi-container-pod-demo:latest
  1. Por último, envía la imagen al repositorio de Amazon ECR:
docker push <ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/multi-container-pod-demo:latest

Passo 3: Implantando a aplicação em nosso cluster criado previamente

    1. Abre el archivo log-app/eks/01-deployment.yaml y cambia __IMAGE_URI__ por la URL de la imagen que hemos introducido

Antes:

containers:
- name: python-app
image: __IMAGE_URI__
ports:
- containerPort: 5000

Depois:

containers:
- name: python-app
image: <ACCOUNT_ID>.dkr.ecr.<region>.amazonaws.com/multi-container-pod-demo:latest
ports:
- containerPort: 5000
  1. Implemente la aplicación en el clúster de Amazon EKS:
kubectl apply -f eks/

 

Paso 4: Consulte los logs de la aplicación

  1. Compruebe si el pod se está running y anote el nombre del pod para utilizar el nombre anotado en lugar de las variables que aparecen a continuación. <POD_NAME>
kubectl get pods -n prd
  1. Consulte el registro de nuestra aplicación Python:
kubectl logs po/<POD_NAME> -c python-app -n prd

El comando anterior devolverá los logs de inicio del servidor mientras los logs de solicitudes se escriben en un archivo.

  1. Obtenga los registros del contenedor responsable de la salida de los registros de stdout:
kubectl logs po/<POD_NAME> -c sidecar -n prd -f

Como puedes ver, se muestran los logs de solicitudes.

  1. Abre una nueva terminal y copia la URL del servicio, que se utilizará para reemplazar la variable <SERVICE_URL> del comando en el siguiente paso:
kubectl get svc -n prd | awk '{print $4}'
  1. Ahora realiza una solicitud de la URL pública del servicio:
curl -IL -XGET http:///<SERVICE_URL>/log

 

 

 

 

 

 

Como se ha visto anteriormente, se generarán nuevos logs aleatorios.

Conclusión

Como se menciona en  The Twelve-Factor App, los logs son flujos de eventos agregados y ordenados por tiempo de recopilación de estos flujos de salida de todos los procesos en ejecución y servicios de soporte. Una aplicación nativa en la nube no debería preocuparse por enrutar y almacenar estos logs, por lo que debería enviar su flujo de eventos a stdout.

En este blog hemos visto que es posible realizar esta implementación incluso si sus aplicaciones siguen conservando los logs en disco, y que con pocas modificaciones en su manifiesto de implementación, podemos gestionar todas las aplicaciones y sus flujos de eventos de la misma manera centralizando los logs en Amazon CloudWatch Logs.

 

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

 


Sobre los autores

Lucas Duarte es arquitecto experto en contenedores de AWS que se centra en los clientes de LATAM. Entusiasta de la automatización, la nube y la cultura DevOps. Con experiencia previa en proyectos centrados en este segmento en empresas como iFood, Guiabolso y Mandic. Ha trabajado en diferentes proyectos relacionados principalmente con la orquestación de contenedores y microservicios.

 

 

 

Vinicius Silva es arquitecto de soluciones en AWS y apoya a los clientes del sector de energía y servicios públicos para lograr sus objetivos con la nube de AWS. Interesado en el desarrollo y la cultura de DevOps, ha contribuido previamente al desarrollo de plataformas web distribuidas y escalables.

 

 

 

 

Revisor

Gabriela Diaz es arquitecta de soluciones en AWS y apoya a los clientes del sector público en Canada. Su experiencia previa involucra proveedores de servicios en la industria de telecomunicaciones en LATAM.