AWS Compute Blog
Scaling Kubernetes deployments with Amazon CloudWatch metrics
This post is contributed by Kwunhok Chan | Solutions Architect, AWS
In an earlier post, AWS introduced Horizontal Pod Autoscaler and Kubernetes Metrics Server support for Amazon Elastic Kubernetes Service. These tools make it easy to scale your Kubernetes workloads managed by EKS in response to built-in metrics like CPU and memory.
However, one common use case for applications running on EKS is the integration with AWS services. For example, you administer an application that processes messages published to an Amazon SQS queue. You want the application to scale according to the number of messages in that queue. The Amazon CloudWatch Metrics Adapter for Kubernetes (k8s-cloudwatch-adapter
) helps.
Amazon CloudWatch Metrics Adapter for Kubernetes
The k8s-cloudwatch-adapter
is an implementation of the Kubernetes Custom Metrics API and External Metrics API with integration for CloudWatch metrics. It allows you to scale your Kubernetes deployment using the Horizontal Pod Autoscaler (HPA) with CloudWatch metrics.
Prerequisites
Before starting, you need the following:
Getting started
Before using the k8s-cloudwatch-adapter
, set up a way to manage IAM credentials to Kubernetes pods. The CloudWatch Metrics Adapter requires the following permissions to access metric data from CloudWatch:
cloudwatch:GetMetricData
Create an IAM policy with the following template:
For demo purposes, I’m granting admin permissions to my Kubernetes worker nodes. Don’t do this in your production environment. To associate IAM roles to your Kubernetes pods, you may want to look at kube2iam or kiam.
If you’re using an EKS cluster, you most likely provisioned it with AWS CloudFormation. The following command uses AWS CloudFormation stacks to update the proper instance policy with the correct permissions:
aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess \
--role-name $(aws cloudformation describe-stacks --stack-name ${STACK_NAME} --query 'Stacks[0].Parameters[?ParameterKey==`NodeInstanceRoleName`].ParameterValue' | jq -r ".[0]")
Make sure to replace ${STACK_NAME}
with the nodegroup stack name from the AWS CloudFormation console .
You can now deploy the k8s-cloudwatch-adapter
to your Kubernetes cluster.
$ kubectl apply -f https://raw.githubusercontent.com/awslabs/k8s-cloudwatch-adapter/master/deploy/adapter.yaml
This deployment creates a new namespace—custom-metrics
—and deploys the necessary ClusterRole, Service Account, and Role Binding values, along with the deployment of the adapter. Use the created custom resource definition (CRD) to define the configuration for the external metrics to retrieve from CloudWatch. The adapter reads the configuration defined in ExternalMetric
CRDs and loads its external metrics. That allows you to use HPA to autoscale your Kubernetes pods.
Verifying the deployment
Next, query the metrics APIs to see if the adapter is deployed correctly. Run the following command:
There are no resources from the response because you haven’t registered any metric resources yet.
Deploying an Amazon SQS application
Next, deploy a sample SQS application to test out k8s-cloudwatch-adapter
. The SQS producer and consumer are provided, together with the YAML files for deploying the consumer, metric configuration, and HPA.
Both the producer and consumer use an SQS queue named helloworld
. If it doesn’t exist already, the producer creates this queue.
Deploy the consumer with the following command:
$ kubectl apply -f https://raw.githubusercontent.com/awslabs/k8s-cloudwatch-adapter/master/samples/sqs/deploy/consumer-deployment.yaml
You can verify that the consumer is running with the following command:
$ kubectl get deploy sqs-consumer
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
sqs-consumer 1 1 1 0 5s
Set up Amazon CloudWatch metric and HPA
Next, create an ExternalMetric
resource for the CloudWatch metric. Take note of the Kind
value for this resource. This CRD resource tells the adapter how to retrieve metric data from CloudWatch.
You define the query parameters used to retrieve the ApproximateNumberOfMessagesVisible
for an SQS queue named helloworld
. For details about how metric data queries work, see CloudWatch GetMetricData API
Create the ExternalMetric resource:
$ kubectl apply -f https://raw.githubusercontent.com/awslabs/k8s-cloudwatch-adapter/master/samples/sqs/deploy/externalmetric.yaml
Then, set up the HPA for your consumer. Here is the configuration to use:
This HPA rule starts scaling out when the number of messages visible in your SQS queue exceeds 30, and scales in when there are fewer than 30 messages in the queue.
Create the HPA resource:
$ kubectl apply -f https://raw.githubusercontent.com/awslabs/k8s-cloudwatch-adapter/master/samples/sqs/deploy/hpa.yaml
Generate load using a producer
Finally, you can start generating messages to the queue:
$ kubectl apply -f https://raw.githubusercontent.com/awslabs/k8s-cloudwatch-adapter/master/samples/sqs/deploy/producer-deployment.yaml
On a separate terminal, you can now watch your HPA retrieving the queue length and start scaling the replicas. SQS metrics generate at five-minute intervals, so give the process a few minutes:
$ kubectl get hpa sqs-consumer-scaler -w
Clean up
After you complete this experiment, you can delete the Kubernetes deployment and respective resources.
Run the following commands to remove the consumer, external metric, HPA, and SQS queue:
$ kubectl delete deploy sqs-producer
$ kubectl delete hpa sqs-consumer-scaler
$ kubectl delete externalmetric sqs-helloworld-length
$ kubectl delete deploy sqs-consumer
$ aws sqs delete-queue helloworld
Other CloudWatch integrations
AWS recently announced the preview for Amazon CloudWatch Container Insights, which monitors, isolates, and diagnoses containerized applications running on EKS and Kubernetes clusters. To get started, see Using Container Insights.
Get involved
This project is currently under development. AWS welcomes issues and pull requests, and would love to hear your feedback.
How could this adapter be best implemented to work in your environment? Visit the Amazon CloudWatch Metrics Adapter for Kubernetes project on GitHub and let AWS know what you think.