Home

Awesome

pd-tech-fest-2019

Demo code for Programmers Developers Tech Fest 2019

Scaling containers with KEDA

There are multiple options for scaling with Kubernetes and containers in general. This demo uses Kubernetes-based Event Driven Autoscaling (KEDA). RabbitMQ is used as an event source.

Prerequisites

If you wish to use Kubernetes cluster apart from AKS, you can skip the Step 2.1 of provisioning the cluster and install KEDA on your own kubernetes cluster.

Similarly, if you do not wish to execute the Powershell scripts, you can execute the commands which are part of those scripts manually.

1 - Code organization

Contains the source code for a model classes for a hypothetical Tech Talks management application. TechTalksMQProducer contains the code for generating the events / messages which are published to a RabbitMQ queue. TechTalksMQConsumer contains the consumer code for processing RabbitMQ messages.

Both the Producer and Consumer uses the common data model. In order to build these using Dockerfile, we define the TechTalksMQProducer and TechTalksMQConsumer. These are built docker-compose-build file.

The docker images can be built using the following command


Measure-Command { docker-compose -f docker-compose-build.yml build | Out-Default }


Once the images are built successfully, we can push them to the DockerHub registry using the command


Measure-Command { docker-compose -f docker-compose-build.yml push | Out-Default }

Contains the helper Powershell scripts to provision AKS cluster, to proxy into the Kubernetes control plane, to delete the resource group, to deploy the application and also to delete the application.

Contains Kubernetes manifest files for deploying the Producer, Consumer and the Autoscalar components to the Kubernetes cluster.

Contains the Helm RBAC enabling yaml file which add the Cluster Role Binding for RBAC enabled Kubernetes cluster. This was required before Helm 3.0 for the Tiller service.With helm 3.0, Tiller is no longer required.


2 - Demo setup

2.1 Initialize AKS cluster with KEDA

Run initializeAKS powershell script with default values from Powershell directory


.\initializeAKS.ps1

Note: The default options can be overwritten by passing arguments to the initializeAKS script. In the below example, we are overriding the number of nodes in the AKS cluster to 4 instead of 3 and resource group name as kedaresgrp.


.\initilaizeAKS `
-workerNodeCount 4 `
-resourceGroupName "kedaresgrp"

2.2 Deploy KEDA


.\deployKEDA.ps1

Verify KEDA is installed correctly on the Kubernetes cluster.


kubectl get all -n keda

2.3 Deploy RabbitMQ queue


.\deployRabbitMQ.ps1

2.4 Deploy RabbitMQ Producer & Consumers

Execute the deployTechTalks-AKS.ps1 powershell script.


.\deployTechTalks-AKS.ps1

The deployTechTalks powershell script deploys the RabbitMQConsumer and RabbitMQProducer in the correct order. Alternately, all the components can also be deployed directly using the kubectl apply command recursively on the k8s directory as shown below.

Run the kubectl apply recursively on k8s directory


kubectl apply -R -f .

2.5 Deploy Auto scalar for RabbitMQ consumer deployment

Execute the deployAutoScaler.ps1 powershell script.


.\deployAutoScaler.ps1

If you do not wish to run the individual PowerShell scripts, you can run one single script which will deploy all the necessary things by running the above scripts in correct order.


.\deployAll.ps1

2.6 Get list of all the services deployed in the cluster

We will need to know the service name for RabbitMQ to be able to do port forwarding to the RabbitMQ management UI and also the public IP assigned to the TechTalks producer service which will be used to generate the messages onto RabbitmQ queue.


kubectl get svc

List of all Kubernetes services

As we can see above, RabbitMQ service is available within the Kubernetes cluster and it exposes 4369, 5672, 25672 and 15672 ports. We will be using 15672 port to map to a local port.

Also note the public LoadBalancer IP for the techtalksapi service. In this case the IP is 52.139.237.252. Note: This IP will be different when the services are redeployed on a different Kubernetes cluster.

2.7 Watch for deployments

The rabbitmq ScaledObject will be deployed as part of the deployment. Watch out for the deployments to see the changes in the scaling as the number of messages increases


kubectl get deployment -w

kubectl get deploy -w

List of all Kubernetes services

Initially there is 1 instance of rabbitmq-consumer and 2 replicas of the techtalksapi (producer) deployed in the cluster.

2.8 Port forward for RabbitMQ management UI

We will use port forwarding approach to access the RabbitMQ management UI.


kubectl port-forward svc/rabbitmq 15672:15672

2.9 Browse RabbitMQ Management UI

http://localhost:15672/

Login to the management UI using credentials as user and PASSWORD. Remember that these were set during the installation of RabbitMQ services using Helm. If you are using any other user, please update the username and password accordingly.

2.10 Generate load using Postman

I am using Postman to submit a POST request to the API which generates 1000 messages onto a RabbitMQ queue named hello. You can use any other command line tool like CURL to submit a GET request.

Use the EXTERNAL-IP -52.139.237.252 with port 8080 to submit a GET request to the API. http://52.139.237.252:8080/api/TechTalks/Generate?numberOfMessages=2000

postman success

Note that we are setting the number of messages to be produced by Producer as 2000 in this case. You can change the number to any other integer value.

After building the GET query, hit the blue Send button on the top right. If everything goes fine, you should receive a 200 OK as status code.

postman success

The Producer will produce 2000 messages on the queue named hello. The consumer is configured to process 10 messages in a batch. The consumer also simulates a long running process by sleeping for 2 seconds.

2.11 Auto-scaling in action

See the number of containers for consumer grow to adjust the messages and also the drop when messages are processed.

autoscaling consumers

On the left hand side of the screen you can see the pods auto scaled and on the right we see the deploymnets autoscaled progressively to 2,4,8, 16 and 30.

While the messages are being processed, we can also observe the RabbitMQ management UI.

autoscaling consumers

Our consumer processes 50 messages in a batch by prefetching them together. This can be verified by looking at the details of the consumers.

Prefetch messages

Once all the messages are processed, KEDA will scale down the pods and the deployments.

autoscaled down consumers

List Custom Resource Definition


kubeclt get crd

autoscaled down consumers


As part of the KEDA installation, ScaledObject and TriggerAuthentications are deployed on the Kubernetes cluster.

YouTube videos

As part of my YouTube channel, I also did a multi-part series on this project. The videos published on the channel are available below :

Part 1 - Autoscaling containers with KEDA - Provision AKS cluster

Part 2 - Autoscaling containers with KEDA - Deploy Application Containers

Part 3 - Autoscaling containers with KEDA - KEDA Autoscale in action

Slides

Here are the links to slides from the presentation

Slideshare

Scaling containers with KEDA

Speakerdeck

Scaling containers with KEDA

Different talks where this repo is used