Services or capabilities described in AWS documentation might vary by Region. To see the differences applicable to the AWS European Sovereign Cloud Region, see the AWS European Sovereign Cloud User Guide.Set up event-driven auto scaling in Amazon EKS by using Amazon EKS Pod Identity and KEDA
Dipen Desai, Abhay Diwan, Kamal Joshi, and Mahendra Revanasiddappa, Amazon Web Services
Summary
Orchestration platforms, such as Amazon Elastic Kubernetes Service (Amazon EKS), have streamlined the lifecycle management of container-based applications. This helps organizations focus on building, securing, operating, and maintaining container-based applications. As event-driven deployments become more common, organizations are more frequently scaling Kubernetes deployments based on various event sources. This method, combined with auto scaling, can result in significant cost savings by providing on-demand compute resources and efficient scaling that is tailored to application logic.
KEDA is a Kubernetes-based event-driven autoscaler. KEDA helps you scale any container in Kubernetes based on the number of events that need to be processed. It is lightweight and integrates with any Kubernetes cluster. It also works with standard Kubernetes components, such as Horizontal Pod Autoscaling (HPA). KEDA also offers TriggerAuthentication, which is a feature that helps you delegate authentication. It allows you to describe authentication parameters that are separate from the ScaledObject and the deployment containers.
AWS provides AWS Identity and Access Management (IAM) roles that support diverse Kubernetes deployment options, including Amazon EKS, Amazon EKS Anywhere, Red Hat OpenShift Service on AWS (ROSA), and self-managed Kubernetes clusters on Amazon Elastic Compute Cloud (Amazon EC2). These roles use IAM constructs, such as OpenID Connect (OIDC) identity providers and IAM trust policies, to operate across different environments without relying directly on Amazon EKS services or APIs. For more information, see IAM roles for service accounts in the Amazon EKS documentation.
Amazon EKS Pod Identity simplifies the process for Kubernetes service accounts to assume IAM roles without requiring OIDC providers. It provides the ability to manage credentials for your applications. Instead of creating and distributing your AWS credentials to the containers or using the Amazon EC2 instance’s role, you associate an IAM role with a Kubernetes service account and configure your Pods to use the service account. This helps you use an IAM role across multiple clusters and simplifies policy management by enabling the reuse of permission policies across IAM roles.
By implementing KEDA with Amazon EKS Pod Identity, businesses can achieve efficient event-driven auto scaling and simplified credential management. Applications scale based on demand, which optimizes resource utilization and reduces costs.
This pattern helps you integrate Amazon EKS Pod Identity with KEDA. It showcases how you can use the keda-operator service account and delegate authentication with TriggerAuthentication. It also describes how to set up a trust relationship between an IAM role for the KEDA operator and an IAM role for the application. This trust relationship allows KEDA to monitor messages in the event queues and adjust scaling for the destination Kubernetes objects.
Prerequisites and limitations
Prerequisites
AWS Command Line Interface (AWS CLI) version 2.13.17 or later, installed
Python version 3.11.5 or later, installed
AWS SDK for Python (Boto3) version 1.34.135 or later, installed
Helm version 3.12.3 or later, installed
kubectl version 1.25.1 or later, installed
Docker Engine version 26.1.1 or later, installed
An Amazon EKS cluster version 1.24 or later, created
Prerequisites for creating the Amazon EKS Pod Identity agent, met
Limitations
Architecture
In this pattern, you create the following AWS resources:
Amazon Elastic Container Registry (Amazon ECR) repository – In this pattern, this repo is named keda-pod-identity-registry. This private repo is used to store Docker images of the sample application.
Amazon Simple Queue Service (Amazon SQS) queue – In this pattern, this queue is named event-messages-queue. The queue acts as a message buffer that collects and stores incoming messages. KEDA monitors the queue metrics, such as message count or queue length, and it automatically scales the application based on these metrics.
IAM role for the application – In this pattern, this role is named keda-identity. The keda-operator role assumes this role. This role allows access to the Amazon SQS queue.
IAM role for the KEDA operator – In this pattern, this role is named keda-operator. The KEDA operator uses this role to make the required AWS API calls. This role has permissions to assume the keda-identity role. Because of the trust relationship between the keda-operator and the keda-identity roles, the keda-operator role has Amazon SQS permissions.
Through the TriggerAuthentication and ScaledObject Kubernetes custom resources, the operator uses the keda-identity role to connect with an Amazon SQS queue. Based on the queue size, KEDA automatically scales the application deployment. It adds 1 pod for every 5 unread messages in the queue. In the default configuration, if there are no unread messages in the Amazon SQS queue, the application scales down to 0 pods. The KEDA operator monitors the queue at an interval that you specify.
The following image shows how you use Amazon EKS Pod Identity to provide the keda-operator role with secure access to the Amazon SQS queue.
The diagram shows the following workflow:
You install the Amazon EKS Pod Identity agent in the Amazon EKS cluster.
You deploy KEDA operator in the KEDA namespace in the Amazon EKS cluster.
You create the keda-operator and keda-identity IAM roles in the target AWS account.
You establish a trust relationship between the IAM roles.
You deploy the application in the security namespace.
The KEDA operator polls messages in an Amazon SQS queue.
KEDA initiates HPA, which automatically scales the application based on the queue size.
AWS services
Other tools
Code repository
The code for this pattern is available in the GitHub Event-driven auto scaling using EKS Pod Identity and KEDA repository.
Best practices
We recommend that you adhere to the following best practices:
Epics
| Task | Description | Skills required |
|---|
Create the IAM role for the KEDA operator. | Sign in to the AWS Management Console, and then open the IAM console. In the navigation pane, choose Roles. Choose Create role. Choose the Custom trust policy role type. In the Custom trust policy section, enter the following custom trust policy for this role: {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
On the Add permissions page, choose Next. You do not add any policies to this role. For Role name, enter keda-operator. Choose Create role.
| AWS administrator |
Create the IAM role for the sample application. | In the IAM console, in the navigation pane, choose Roles. Choose Create role. Choose the Custom trust policy role type. In the Custom trust policy section, enter the following custom trust policy for this role. Replace <account number> with your target account number: {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com",
"AWS": "arn:aws:iam::<account number>:role/keda-operator"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
On the Add permissions page, add the following AWS managed polices to the role: Choose Next. For Role name, enter keda-identity. Choose Create role.
| AWS administrator |
Create an Amazon SQS queue. | Open the Amazon SQS console. Choose Create queue. For Type, choose Standard. On Create queue page, for Name, enter event-messages-queue. Choose Create queue. You do not change any of the default settings for this queue.
| General AWS |
Create an Amazon ECR repository. | Open the Amazon ECR console. Choose Create repository. For Repository name, enter keda-pod-identity-registry. Choose Create repository. You do not change any of the default settings for this repository.
| General AWS |
| Task | Description | Skills required |
|---|
Deploy the Amazon EKS Pod Identity agent. | For the target Amazon EKS cluster, set up the Amazon EKS Pod Identity agent. Follow the instructions in Set up the Amazon EKS Pod Identity Agent in the Amazon EKS documentation. | AWS DevOps |
Deploy KEDA. | Enter the following commands to deploy KEDA on the target Amazon EKS cluster: # Add Helm Repo for Keda
helm repo add kedacore https://kedacore.github.io/charts
# Update Helm repo
helm repo update
# Install Keda
helm install keda kedacore/keda --namespace keda --create-namespace
For more information, see Deploying with Helm in the KEDA documentation. After successful deployment, in the output, validate that three deployments are created for the KEDA operator. The following is a sample output: NAME READY UP-TO-DATE AVAILABLE AGE
keda-admission-webhooks 1/1 1 1 89s
keda-operator 1/1 1 1 89s
keda-operator-metrics-apiserver 1/1 1 1 89s
| DevOps engineer |
Assign the IAM role to the Kubernetes service account. | Follow the instructions in Assign an IAM role to a Kubernetes service account in the Amazon EKS documentation. Use the following values: For IAM role, enter keda-operator. For Kubernetes namespace, enter keda. For Kubernetes service account, enter keda-operator.
| AWS DevOps |
Create a namespace. | Enter the following command to create a security namespace in the target Amazon EKS cluster: kubectl create ns security
| DevOps engineer |
| Task | Description | Skills required |
|---|
Clone the application files. | Enter the following command to clone the Event-driven auto scaling using EKS Pod Identity and KEDA repository from GitHub: git clone https://github.com/aws-samples/event-driven-autoscaling-using-podidentity-and-keda.git
| DevOps engineer |
Build the Docker image. | Enter the following command to navigate into the cloned repository: cd event-driven-autoscaling-using-podidentity-and-keda
Enter the following command to build the Docker image for the sample application: docker build -t keda-pod-identity-registry .
| DevOps engineer |
Push the Docker image to Amazon ECR. | In the terminal where you built the Docker image, enter the following command to log in to Amazon ECR. Replace <AWS_REGION> and <AWS_ACCOUNT_ID> with values from your AWS environment: aws ecr get-login-password \
--region <AWS_REGION> | docker login \
--username AWS \
--password-stdin <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com
Enter the following command to tag the image. Replace <AWS_REGION> and <AWS_ACCOUNT_ID> with values from your AWS environment: docker tag keda-pod-identity-registry:latest <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/keda-pod-identity-registry:latest
Enter the following command to push the image to Amazon ECR. Replace <AWS_REGION> and <AWS_ACCOUNT_ID> with values from your AWS environment: docker push <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/keda-pod-identity-registry:latest
You can find push commands by navigating to the Amazon ECR repository page and then choosing View push commands. | DevOps engineer |
Deploy the sample application. | In the cloned repository, open the deploy.yaml file. Replace <AWS_ACCOUNT_ID> and <AWS_REGION> with values from your environment. Save and close the deploy.yaml file. Enter the following command to deploy the sample application on the target Amazon EKS cluster: kubectl apply -f deploy.yaml
This command creates a deployment and service account in the cluster.
| DevOps engineer |
Assign the IAM role to the application service account. | Do one of the following to associate the keda-identity IAM role with the service account for the sample application: Follow the instructions in Assign an IAM role to a Kubernetes service account in the Amazon EKS documentation. Use the following values: For IAM role, enter keda-identity. For Kubernetes namespace, enter security. For Kubernetes service account, enter my-sqs-read-msgs.
Enter the following AWS CLI command. Replace <cluster-name> with the name of the target Amazon EKS cluster, and replace <role-ARN> with the Amazon Resource Name (ARN) of the keda-identity role: aws eks create-pod-identity-association \
--cluster-name <cluster-name> \
--role-arn <role-ARN> \
--namespace security \
--service-account my-sqs-read-msgs
| DevOps engineer |
Deploy ScaledObject and TriggerAuthentication. | In the cloned repository, open the keda.yaml file. Replace {{AWS_ACCOUNT_ID}} with the ID of your target AWS account. Replace {{AWS_REGION}} with your target AWS Region. (Optional) In lines 21–24, update the parameters for the ScaledObject scaling policy. See the following for more information about these parameters: Save and close the keda.yaml file. Enter the following command to deploy the ScaledObject and TriggerAuthentication resources: kubectl -n security apply -f keda.yaml
| DevOps engineer |
| Task | Description | Skills required |
|---|
Send messages to the Amazon SQS queue. | Enter the following command to navigate into the cloned repository: cd event-driven-autoscaling-using-podidentity-and-keda
Enter the following command to send test messages to the Amazon SQS queue: python sqs_send_msg.py
The sqs_send_msg.py script acts as an application that generates messages for testing auto scaling. If you're running Python 3, enter python3 sqs_send_msg.py.
| DevOps engineer |
Monitor the application pods. | In different terminal, enter the following command to monitor the pods: kubectl -n security get po
For every 5 unread messages in the Amazon SQS queue, KEDA adds one pod. In the output of the previous command, confirm that new pods are being added. The following is a sample output: kubectl -n security get po
NAME READY STATUS RESTARTS AGE
q-read-797f4c7589-2bj76 1/1 Running 0 2s
q-read-797f4c7589-4zxph 1/1 Running 0 49s
q-read-797f4c7589-cg9dt 1/1 Running 0 18s
q-read-797f4c7589-slc69 1/1 Running 0 33s
When you are finished testing, in the original terminal, enter CTRL + C (Windows) or CMD + C (macOS). This stops the python sqs_send_msg.py script.
| DevOps engineer |
Troubleshooting
| Issue | Solution |
|---|
The KEDA operator cannot scale the application. | Enter the following command to check the logs of the keda-operator IAM role: kubectl logs -n keda -l app=keda-operator -c keda-operator
If there is an HTTP 403 response code, then the application and the KEDA scaler do not have sufficient permissions to access the Amazon SQS queue. Complete the following steps: Check the IAM policies and statements for the keda-identity role to confirm that that queue read access is granted. Validate the trust relationship between the IAM roles. The following is an example: {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
If there is an Assume-Role error, then an Amazon EKS node IAM role is unable to assume the IAM role that is defined for TriggerAuthentication. Complete the following steps: Enter the following command to delete the keda-operator pod and create a new one: kubectl delete pod keda-operator-<alphenumeric-value> --namespace keda
Enter the following command to check the identity that the pod assumes: kubectl describe pod <keda-operator-pod-name> --namespace keda
When the pod successfully restarts, confirm that the following two variables are added to the pod description:
|
Related resources