{"id":840,"date":"2022-12-27T12:47:23","date_gmt":"2022-12-27T04:47:23","guid":{"rendered":"https:\/\/vinta.ws\/code\/?p=840"},"modified":"2026-03-17T00:03:41","modified_gmt":"2026-03-16T16:03:41","slug":"amazon-eks-setup-cluster-autoscaler","status":"publish","type":"post","link":"https:\/\/vinta.ws\/code\/amazon-eks-setup-cluster-autoscaler.html","title":{"rendered":"Amazon EKS: Setup Cluster Autoscaler"},"content":{"rendered":"<p>Kubernetes' Cluster Autoscaler automatically adjusts the number of nodes in your cluster when pods fail or are rescheduled onto other nodes. Here we're going to deploy the AWS implementation that implements the decisions of Cluster Autoscaler by communicating with AWS products and services such as Amazon EC2.<\/p>\n<p>ref:<br \/>\n<a href=\"https:\/\/docs.aws.amazon.com\/eks\/latest\/userguide\/cluster-autoscaler.html\">https:\/\/docs.aws.amazon.com\/eks\/latest\/userguide\/cluster-autoscaler.html<\/a><\/p>\n<h2>Configure IAM Permissions<\/h2>\n<p>If your existing node groups were created with\u00a0<code>eksctl create nodegroup --asg-access<\/code>, then this policy already exists and you can skip this step.<\/p>\n<p>in <code>cluster-autoscaler-policy-staging.json<\/code><\/p>\n<pre class=\"line-numbers\"><code class=\"language-json\">{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"VisualEditor0\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"autoscaling:SetDesiredCapacity\",\n                \"autoscaling:TerminateInstanceInAutoScalingGroup\"\n            ],\n            \"Resource\": \"*\",\n            \"Condition\": {\n                \"StringEquals\": {\n                    \"aws:ResourceTag\/k8s.io\/cluster-autoscaler\/perp-staging\": \"owned\"\n                }\n            }\n        },\n        {\n            \"Sid\": \"VisualEditor1\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"autoscaling:DescribeAutoScalingGroups\",\n                \"autoscaling:DescribeAutoScalingInstances\",\n                \"autoscaling:DescribeLaunchConfigurations\",\n                \"autoscaling:DescribeTags\",\n                \"autoscaling:SetDesiredCapacity\",\n                \"autoscaling:TerminateInstanceInAutoScalingGroup\",\n                \"ec2:DescribeLaunchTemplateVersions\"\n            ],\n            \"Resource\": \"*\"\n        }\n    ]\n}<\/code><\/pre>\n<pre class=\"line-numbers\"><code class=\"language-bash\">aws --profile perp iam create-policy \n  --policy-name AmazonEKSClusterAutoscalerPolicyStaging \n  --policy-document file:\/\/cluster-autoscaler-policy-staging.json\n\neksctl --profile=perp create iamserviceaccount \n  --cluster=perp-staging \n  --namespace=kube-system \n  --name=cluster-autoscaler \n  --attach-policy-arn=arn:aws:iam::xxx:policy\/AmazonEKSClusterAutoscalerPolicy \n  --override-existing-serviceaccounts \n  --approve<\/code><\/pre>\n<p>ref:<br \/>\n<a href=\"https:\/\/docs.aws.amazon.com\/eks\/latest\/userguide\/autoscaling.html\">https:\/\/docs.aws.amazon.com\/eks\/latest\/userguide\/autoscaling.html<\/a><\/p>\n<h2>Deploy Cluster Autoscaler<\/h2>\n<p>Download the deployment yaml of <code>cluster-autoscaler<\/code>:<\/p>\n<pre class=\"line-numbers\"><code class=\"language-bash\">curl -o cluster-autoscaler-autodiscover.yaml \nhttps:\/\/raw.githubusercontent.com\/kubernetes\/autoscaler\/master\/cluster-autoscaler\/cloudprovider\/aws\/examples\/cluster-autoscaler-autodiscover.yaml<\/code><\/pre>\n<p>Before you apply the file, it's recommended to check whether the version of <code>cluster-autoscaler<\/code> matches the Kubernetes major and minor version of your cluster. Find the version number on <a href=\"https:\/\/github.com\/kubernetes\/autoscaler\/releases\">GitHub releases<\/a>.<\/p>\n<pre class=\"line-numbers\"><code class=\"language-bash\">kubectl apply -f cluster-autoscaler-autodiscover.yaml\n# or\nkubectl set image deployment cluster-autoscaler \n  -n kube-system \n  cluster-autoscaler=k8s.gcr.io\/autoscaling\/cluster-autoscaler:v1.21.3<\/code><\/pre>\n<p>Do some tweaks:<\/p>\n<ul>\n<li><code>--balance-similar-node-groups<\/code> ensures that there is enough available compute across all availability zones.<\/li>\n<li><code>--skip-nodes-with-system-pods=false<\/code> ensures that there are no problems with scaling to zero.<\/li>\n<\/ul>\n<pre class=\"line-numbers\"><code class=\"language-bash\">kubectl patch deployment cluster-autoscaler \n  -n kube-system \n  -p '{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"cluster-autoscaler.kubernetes.io\/safe-to-evict\": \"false\"}}}}}'\n\nkubectl -n kube-system edit deployment.apps\/cluster-autoscaler\n# change the command to the following:\n# spec:\n#   containers:\n#   - command\n#     - .\/cluster-autoscaler\n#     - --v=4\n#     - --stderrthreshold=info\n#     - --cloud-provider=aws\n#     - --skip-nodes-with-local-storage=false\n#     - --expander=least-waste\n#     - --node-group-auto-discovery=asg:tag=k8s.io\/cluster-autoscaler\/enabled,k8s.io\/cluster-autoscaler\/perp-staging\n#     - --balance-similar-node-groups\n#     - --skip-nodes-with-system-pods=false<\/code><\/pre>\n<p>ref:<br \/>\n<a href=\"https:\/\/aws.github.io\/aws-eks-best-practices\/cluster-autoscaling\/\">https:\/\/aws.github.io\/aws-eks-best-practices\/cluster-autoscaling\/<\/a><br \/>\n<a href=\"https:\/\/github.com\/kubernetes\/autoscaler\/tree\/master\/charts\/cluster-autoscaler#additional-configuration\">https:\/\/github.com\/kubernetes\/autoscaler\/tree\/master\/charts\/cluster-autoscaler#additional-configuration<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kubernetes' Cluster Autoscaler automatically adjusts the number of nodes in your cluster when pods fail or are rescheduled onto other nodes. Here we're going to deploy the AWS implementation that implements the decisions of Cluster Autoscaler by communicating with AWS products and services such as Amazon EC2. ref: https:\/\/docs.aws.amazon.com\/eks\/latest\/userguide\/cluster-autoscaler.html Configure IAM Permissions If your existing&hellip; <a href=\"https:\/\/vinta.ws\/code\/amazon-eks-setup-cluster-autoscaler.html\" class=\"more-link\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":841,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[38,116],"tags":[16,136,123],"class_list":["post-840","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-about-devops","category-about-web-development","tag-amazon-web-services","tag-aws-eks","tag-kubernetes"],"_links":{"self":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts\/840","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/comments?post=840"}],"version-history":[{"count":0,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/posts\/840\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/media\/841"}],"wp:attachment":[{"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/media?parent=840"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/categories?post=840"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vinta.ws\/code\/wp-json\/wp\/v2\/tags?post=840"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}