Saltar al contenido

Opciones mejoradas de AutoScaling para aplicaciones impulsadas por eventos

KEDA proporciona un entorno rico para escalar su aplicación aparte del enfoque tradicional de HPA usando CPU y Memoria

Foto de Markus Winkler en Unsplash

El escalado automático es una de las grandes ventajas de los entornos nativos de la nube y nos ayuda a proporcionar un uso optimizado de las operaciones. Kubernetes ofrece muchas opciones para hacerlo, siendo una de ellas el enfoque del Escalador Automático de Pods Horizontal (HPA).

HPA es la forma en que Kubernetes detecta si es necesario escalar alguno de los pods, y se basa en métricas como el uso de CPU o memoria.

https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/

A veces esas métricas no son suficientes para decidir si el número de réplicas que tenemos disponibles es suficiente. Otras métricas pueden proporcionar una mejor perspectiva, como el número de solicitudes o el número de eventos pendientes.

Escalado Automático Basado en Eventos de Kubernetes (KEDA)

Aquí es donde KEDA viene a ayudar. KEDA significa Escalado Automático Basado en Eventos de Kubernetes y proporciona un enfoque más flexible para escalar nuestros pods dentro de un clúster de Kubernetes.

Se basa en escaladores que pueden implementar diferentes fuentes para medir el número de solicitudes o eventos que recibimos de diferentes sistemas de mensajería como Apache Kafka, AWS Kinesis, Azure EventHub y otros sistemas como InfluxDB o Prometheus.

KEDA funciona como se muestra en la imagen a continuación:

Tenemos nuestro ScaledObject que vincula nuestra fuente de eventos externa (es decir, Apache Kafka, Prometheus ..) con el Despliegue de Kubernetes que nos gustaría escalar y registrar eso en el clúster de Kubernetes.

KEDA monitoreará la fuente externa y, basado en las métricas recopiladas, comunicará al Escalador Automático de Pods Horizontal para escalar la carga de trabajo según lo definido.

Probando el Enfoque con un Caso de Uso

Entonces, ahora que sabemos cómo funciona, haremos algunas pruebas para verlo en vivo. Vamos a mostrar cómo podemos escalar rápidamente una de nuestras aplicaciones usando esta tecnología. Y para hacer eso, lo primero que necesitamos hacer es definir nuestro escenario.

En nuestro caso, el escenario será una aplicación nativa de la nube simple desarrollada usando una aplicación Flogo que expone un servicio REST.

El primer paso que necesitamos hacer es desplegar KEDA en nuestro clúster de Kubernetes, y hay varias opciones para hacerlo: gráficos Helm, Operación o archivos YAML. En este caso, vamos a usar el enfoque de gráficos Helm.

Entonces, vamos a escribir los siguientes comandos para agregar el repositorio helm y actualizar los gráficos disponibles, y luego desplegar KEDA como parte de nuestra configuración de clúster:

helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda

Después de ejecutar este comando, KEDA se despliega en nuestro clúster K8S, y al escribir el siguiente comando kubectl get all proporcionará una situación similar a esta:

pod/keda-operator-66db4bc7bb-nttpz 2/2 Running 1 10m
pod/keda-operator-metrics-apiserver-5945c57f94-dhxth 2/2 Running 1 10m

Ahora, vamos a desplegar nuestra aplicación. Como ya se comentó, para hacerlo vamos a usar nuestra Aplicación Flogo, y el flujo será tan simple como este:

Aplicación Flogo escuchando las solicitudes
  • La aplicación expone un servicio REST usando /hello como el recurso.
  • Las solicitudes recibidas se imprimen en la salida estándar y se devuelve un mensaje al solicitante

Una vez que tenemos nuestra aplicación desplegada en nuestra aplicación de Kubernetes, necesitamos crear un ScaledObject que sea responsable de gestionar la escalabilidad de ese componente:

Configuración de ScaleObject para la aplicación

Usamos Prometheus como un disparador, y debido a eso, necesitamos configurar dónde está alojado nuestro servidor Prometheus y qué consulta nos gustaría hacer para gestionar la escalabilidad de nuestro componente.

En nuestro ejemplo, usaremos el flogo_flow_execution_count que es la métrica que cuenta el número de solicitudes que son recibidas por este componente, y cuando esto tiene una tasa superior a 100, lanzará una nueva réplica.

Después de golpear el servicio con una Prueba de Carga, podemos ver que tan pronto como el servicio alcanza el umbral, lanza una nueva réplica para comenzar a manejar solicitudes como se esperaba.

Escalado automático realizado usando métricas de Prometheus.

Todo el código y los recursos están alojados en el repositorio de GitHub que se muestra a continuación:

https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/


Resumen

Este post ha mostrado que tenemos opciones ilimitadas para decidir las opciones de escalabilidad para nuestras cargas de trabajo. Podemos usar las métricas estándar como CPU y memoria, pero si necesitamos ir más allá, podemos usar diferentes fuentes externas de información para activar ese escalado automático.

Enhanced AutoScaling Options for Event-Driven Applications

KEDA provides a rich environment to scale your application apart from the traditional HPA approach using CPU and Memory

Photo by Markus Winkler on Unsplash

Autoscaling is one of the great things of cloud-native environments and helps us to provide an optimized use of the operations. Kubernetes provides many options to do that being one of those the Horizontal Pod Autoscaler (HPA) approach.

HPA is the way Kubernetes has to detect if it is needed to scale any of the pods, and it is based on the metrics such as CPU usage or memory.

https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/

Sometimes those metrics are not enough to decide if the number of replicas we have available is enough. Other metrics can provide a better perspective, such as the number of requests or the number of pending events.

Kubernetes Event-Driven Autoscaling (KEDA)

Here is where KEDA comes to help. KEDA stands for Kubernetes Event-Driven Autoscaling and provides a more flexible approach to scale our pods inside a Kubernetes cluster.

It is based on scalers that can implement different sources to measure the number of requests or events that we receive from different messaging systems such as Apache Kafka, AWS Kinesis, Azure EventHub, and other systems as InfluxDB or Prometheus.

KEDA works as it is shown in the picture below:

We have our ScaledObject that links our external event source (i.e., Apache Kafka, Prometheus ..) with the Kubernetes Deployment we would like to scale and register that in the Kubernetes cluster.

KEDA will monitor the external source, and based on the metrics gathered, will communicate the Horizontal Pod Autoscaler to scale the workload as defined.

Testing the Approach with a Use-Case

So, now that we know how that works, we will do some tests to see it live. We are going to show how we can quickly scale one of our applications using this technology. And to do that, the first thing we need to do is to define our scenario.

In our case, the scenario will be a simple cloud-native application developed using a Flogo application exposing a REST service.

The first step we need to do is to deploy KEDA in our Kubernetes cluster, and there are several options to do that: Helm charts, Operation, or YAML files. In this case, we are going to use the Helm charts approach.

So, we are going to type the following commands to add the helm repository and update the charts available, and then deploy KEDA as part of our cluster configuration:

helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda

After running this command, KEDA is deployed in our K8S cluster, and it types the following command kubectl get all will provide a situation similar to this one:

pod/keda-operator-66db4bc7bb-nttpz 2/2 Running 1 10m
pod/keda-operator-metrics-apiserver-5945c57f94-dhxth 2/2 Running 1 10m

Now, we are going to deploy our application. As already commented to do that we are going to use our Flogo Application, and the flow will be as simple as this one:

Flogo application listening to the requests
  • The application exposes a REST service using the /hello as the resource.
  • Received requests are printed to the standard output and returned a message to the requester

Once we have our application deployed on our Kubernetes application, we need to create a ScaledObject that is responsible for managing the scalability of that component:

ScaleObject configuration for the application

We use Prometheus as a trigger, and because of that, we need to configure where our Prometheus server is hosted and what query we would like to do to manage the scalability of our component.

In our sample, we will use the flogo_flow_execution_count that is the metric that counts the number of requests that are received by this component, and when this has a rate higher than 100, it will launch a new replica.

After hitting the service with a Load Test, we can see that as soon as the service reaches the threshold, it launch a new replica to start handling requests as expected.

Autoscaling being done using Prometheus metrics.

All of the code and resources are hosted in the GitHub repository shown below:

https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/


Summary

This post has shown that we have unlimited options in deciding the scalability options for our workloads. We can use the standard metrics like CPU and memory, but if we need to go beyond that, we can use different external sources of information to trigger that autoscaling.