Deploying & Using KEDA

We’re often using HPA (Horizontal Pod Autoscaling) or may looked at VPA (Vertical Pod Autoscaling) but there’s also KEDA (Kubernetes Event-driven Autoscaling) which is an operator to scale workloads based upon (as the name suggests) events, for example queue triggers could come from a message bus/queue such as RabbitMQ. KEDA can also be used in such scenarios to scale to 0 pods (almost like the way we might use Azure functions).

Installing

To install KEDA, just add the repo to helm then update

Note: see official documentation https://keda.sh/docs/2.19/deploy, which I’ve partially reproduced here

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

Now to install KEDA run

  • helm install keda kedacore/keda –namespace keda –create-namespace

As you’ll probably expect from this line, a new namespace keda is added to our Kubernetes cluster.

Kubernetes kind ScaledObject

We’ll want to configure K8s to scale our objects. Let’s use an example already on the web as it’s a perfectly simple illustration of using RabbitMQ to trigger scaling of our service. In this case we’ll scale down to 0 so essentially when our service is not being used (obviously you’d probably only want this for less frequently uses service due to cold-start etc.) we can scale the resources to zero to free up available namespace based memory etc.

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: my-scaledobject
spec:
  scaleTargetRef:
    name: my-deployment
  minReplicaCount: 0
  maxReplicaCount: 10
  triggers:
    - type: rabbitmq
      metadata:
        queueName: my-queue
        host: amqp://user:pass@rabbitmq:5672/
        mode: QueueLength
        value: "10"   # messages per pod
      authenticationRef:
        name: rabbitmq-secret 

In this example we are using ScaledObject as the kind (this is a KEDA object). This YAML will allow K8s to auto-scale my-deployment pods based upon RabbitMQ queue activity, as stated previously this will scaled down to zero and we ensure a max scaling of 10 – we need to ensure that even if the backlog on the queue is large, we’re not going to scale out of control.

The scaleTargetRef tells KEDA which K8s workload to scale, in this case we expect a deployment names my-deployment.

The triggers section tells KEDA what metric to monitor, in this case KEDA will monitor queue metrics, of the queue my-queue. When messages appear in the queue, KEDA scale up the consumer pods and when the queue drains KEDA scales down the pods.

In our example we also use authenticationRef to securely store RabbitMQ credentials within K8s secrets.

For example, if your queue suddenly receives 100 messages and with this threshold of 1- messages per pod then KEDA will scale to 10 pods.

What KEDA gives us is the ability to use event-driven scaling based upon real workloads as opposed to using CPU or memory.

More uses

KEDA has a built in Azure Blob Storage scaler, allowing is to scale based upon the number of blobs in a container, this can be useful when long running jobs are triggered by files being written into blob storage. For example, processing uploads files, batch process triggered by blobs presence etc.

Support exists for Rabbit MQ as already seen but also for Azure Service Bus where (again) we can scaled based upon queue length as well as topic and subscription message count. Examples would include REST API to worker pods scaling, background processing as well as event driven microservices.

Redis List or Redis stream scalers are supported as well as Azure Managed Redis. Here we could scale based upon job queues within Redis lists, stream based event processing etc.

References

KEDA scalers
KEDA with Azure services