In this post, I will create a small Node.js app containing the publisher and message processor, and publish it as an image to Docker Hub.
Then, I will use the same image to demonstrate scaling Kubernetes Jobs using KEDA, triggered by Amazon SQS.
For demonstration purposes, I will be using a Minikube local Kubernetes cluster, but in reality, this would be done in a production Kubernetes cluster
Here is the architectural diagram for our workflow.
In the above diagram, we can see that the producer (pod) is publishing a message, which will be done by running a CLI to input the prompt and push the message to Amazon SQS.
When a message arrives in the queue, KEDA will create a job for each message that lands on the Amazon SQS queue. If there are no messages, no jobs are created. Each job will pull one message from the queue and process it.
Introduction
KEDA stands for Kubernetes (k8s) Event-Driven Autoscaling. With KEDA, you can scale any deployment or jobs in Kubernetes according to the number of events that need to be processed.
Sometimes Kubernetes Jobs need to be scaled to handle long-running tasks, such as processing files in real-time after an upload. Your application might need to process thousands of files, and processing multiple files within a single deployment may not be efficient. In this case, it is better to have an individual job to process each file separately.
In my professional life, I have used KEDA to scale Kubernetes jobs as an alternative to Amazon Web Services(AWS) Lambda functions for processing long-running jobs.
Steps
Create Node App
First, let’s create a Node.js app with the folder structure shown below. You’ll also need to install the aws-sdk
npm package.
Your package.json
file will look like as below file.
|
|
Create Landing Page
Let’s create the index.js
file and start a server,
which will serve as the main entry point for our app.
I am creating it to ensure that our app runs without any issues.
Load AWS configuration
Create an awsConfig.js
file to load AWS credentials from environment variables.
The environment variables are populated from Kubernetes secrets, which we will create later in this post.
Create Publisher
Let’s create a publisher (publisher.js
) that will read input from the CLI and publish messages to AWS SQS.
|
|
You need to SSH into the container and run node publisher.js
,
which will prompt for message input in the CLI and publish it to SQS.
Create Processor
Let’s create a processor (processor.js) that will read message from the SQS process it and delete form SQS.
|
|
To ensure that your processor is processing messages,
you need to check the logs, which can be done by running the command:
kubectl logs {pod name}
Dockrize the app
To Dockerize the app, you need to create a Dockerfile
in the root of the project and add the following code.
The code installs Node.js version 19 and exposes port 8081.
After completing all the steps above, run the following command in the terminal to build the image:
|
|
Sharing Docker image with a registry
There are many registry to publish docker images. Here, I am using Docker Hub to publish image publicly.
Login to Docker Hub
Use below command to login to the Docker Hub. This command will help you to login in the Docker Hub.
|
|
Push the Image to the Registry:
|
|
In my case, my docker push command will be like:
|
|
The app is created, and the image is published to the public registry. Now, we need to focus on the actual work, which is scaling the processor job using K8S KEDA, triggered by Amazon SQS.
I will explain how this can be done in the following steps:
Install Minikube
I will use Minikube to run the job locally on my machine. If you don’t have Minikube on your machine, download and install download and install
Install KEDA
Once your minikube is running install KEDA via the below command.
|
|
Create SQS queue and IAM User
In AWS, you need to create an SQS queue, IAM User, and attach the AmazonSQSFullAccess
policy.
Once you create an IAM user you will get AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
. You need to keep it safe and used in your Secret.
Now, need to create the manifest files for k8s. All the files will be created inside k8s folder
Secret manifest
There are three types of Authentication Parameters in KEDA:
- Pod identity based authentication
- Role based authentication
- Credential based authentication
Here, I am using 3rd one (Credential based authentication) which will require above created
AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
.
Let me create a Kubernetes Secret manifest aws-secrets.yaml
to stores AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
(sensitive information) in a secure way.
If you don’t know how to encode the AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
,
you can use the terminal to encode the keys in base64
as shown below.
Run the below command to create the secrets:
|
|
If successful, result will be like this:
|
|
KEDA TriggerAuthentication Manifest
Need to create a Kubernetes manifest file keda-trigger-auth-aws-credentials.yaml
to define a KEDA TriggerAuthentication
resource,
which is used to securely authenticate triggers in KEDA that require credentials.
In our case, it configures authentication for an AWS SQS using access keys stored in Kubernetes secrets.
|
|
Run the below command to create the secrets:
|
|
If successful, result will be like this:
ScaledJob Manifest
Create a keda-sqs-processor.yaml
file that will pull the image we published earlier to Docker Hub and scale the processor job as soon as a message lands in Amazon SQS.
|
|
Run the command to create the processor scaled job:
|
|
If successful, result will be like this:
|
|
Once you completed the above steps run the below command to see the created scaled job.
|
|
If successful, the result will be like this in the console:
Create Publisher Deployment Manifest
Create a sqs-publisher.yaml
file that will pull the image we published earlier to Docker Hub and runs the publisher CLI app.
|
|
Run the command to create the sqs-publisher deployment :
|
|
If successful, result will be like this:
|
|
Verify Processor Scaled Jobs and Publisher
Verify Publisher
Publisher will be running in the pod. To see the running pods by executing the below command.
|
|
If successful, result will be like in console:
You can ssh into the pods by executing the below command:
|
|
To publish message form publisher pod you need to execute below commend in the container
|
|
The above command will prompt you to input a message from the terminal that you want to publish to AWS SQS.
If successful, you will see result like this:
Verify Processor Scaled Jobs
To see the running/successful/failed jobs you can run below command.
|
|
If successful, result will be like in console:
If you have any GUI tool, you can also view it under Pods. I can see it in Lens, as shown in the image below. Here you will see running jobs, failed jobs, and successful jobs.
The number of successful and failed jobs can be defined in the ScaledJob Manifest file ie. successfulJobsHistoryLimit: 5
failedJobsHistoryLimit: 5
New jobs will be created until you purge the SQS or delete the jobs after processing them from the app.
you can see the logs from processor job by running the below command.
|
|
If successful, result will be like this:
Publish Message from SQS
You can also use the AWS UI to publish messages to SQS as below. This is only the alternative option.
Conclusion
Scaling Kubernetes jobs with KEDA provides an efficient way to handle event-driven workloads, such as processing messages from an Amazon SQS queue. By using Kubernetes KEDA, you can dynamically scale jobs based on the number of incoming messages. This solution is ideal for scenarios where long-running tasks need to be processed individually.
In this post, I created a small Node.js app containing the publisher and message processor, and published it as an image to Docker Hub.
Then, I used the same image to demonstrate scaling Kubernetes jobs using KEDA, triggered by Amazon SQS. I used a Minikube local K8s cluster for demonstration and explained the steps, which can be easily replicated in a production Kubernetes cluster to handle large volumes of long-running tasks as individual jobs.
GitHub Repository
Here is the GitHub repository used for demonstration purposes; you can clone it and create the app in your own way. https://github.com/dev-scripts/keda-sqs