Use this file to discover all available pages before exploring further.
This guide shows you how to switch from the Kubernetes Cluster Autoscaler (CAS) to Karpenter for automatic node provisioning. The migration is non-destructive: Karpenter is installed alongside CAS before CAS is disabled, so your workloads remain available throughout.
Before migrating, it helps to understand how the two systems differ conceptually:
Cluster Autoscaler
Karpenter
Scaling model
Scales existing Auto Scaling Groups
Launches EC2 instances directly via RunInstances
Instance selection
Fixed per node group
Dynamically chosen per workload requirement
Configuration
One node group per instance type set
One NodePool covers many instance types and zones
Node lifecycle
ASG manages nodes
Karpenter manages the full instance lifecycle
Spot support
Separate Spot node groups
Native karpenter.sh/capacity-type requirement
Consolidation
Limited (scale down)
Continuous bin-packing and right-sizing
With Karpenter you will replace your ASG-based node groups (for workload capacity) with one or a few NodePool and EC2NodeClass objects. Your existing managed node groups can be kept at a minimal size to host Karpenter itself and other critical cluster components.
Nodes launched by Karpenter need their own IAM role with the standard EKS worker-node policies. Create it with a trust policy that allows EC2 to assume the role:
aws iam attach-role-policy --role-name "KarpenterNodeRole-${CLUSTER_NAME}" \ --policy-arn "arn:${AWS_PARTITION}:iam::aws:policy/AmazonEKSWorkerNodePolicy"aws iam attach-role-policy --role-name "KarpenterNodeRole-${CLUSTER_NAME}" \ --policy-arn "arn:${AWS_PARTITION}:iam::aws:policy/AmazonEKS_CNI_Policy"aws iam attach-role-policy --role-name "KarpenterNodeRole-${CLUSTER_NAME}" \ --policy-arn "arn:${AWS_PARTITION}:iam::aws:policy/AmazonEC2ContainerRegistryPullOnly"aws iam attach-role-policy --role-name "KarpenterNodeRole-${CLUSTER_NAME}" \ --policy-arn "arn:${AWS_PARTITION}:iam::aws:policy/AmazonSSMManagedInstanceCore"
3
Create the Karpenter controller IAM role
The Karpenter controller uses IAM Roles for Service Accounts (IRSA) to call AWS APIs. Create a role with a trust policy that allows your cluster’s OIDC provider to issue credentials to the Karpenter service account:
Create and attach the controller policy granting Karpenter the permissions it needs to manage EC2 instances, IAM instance profiles, and SQS interruption queues:
Allow nodes using the new Karpenter node IAM role to join the cluster by adding a mapping to the aws-auth ConfigMap:
kubectl edit configmap aws-auth -n kube-system
Add the following entry to the mapRoles section. Replace ${AWS_PARTITION} and ${AWS_ACCOUNT_ID} with your actual values, but do not replace{{EC2PrivateDNSName}}:
Before applying, edit karpenter.yaml to set node affinity so Karpenter runs on your existing managed node group rather than on a Karpenter-provisioned node. Find the Karpenter Deployment and update its affinity:
If you have critical cluster add-ons like CoreDNS or metrics-server that you want to keep on managed node group nodes during the transition, set a similar nodeAffinity on those deployments too:
Create a NodePool that covers the workload requirements previously handled by your CAS-managed node groups. The example below requests Spot capacity across the c, m, and r instance families — adjust the requirements to match your workloads.You can find additional NodePool examples at github.com/aws/karpenter/tree/v1.9.0/examples/v1.
Then reduce your managed node groups to a minimal size. Karpenter will take over provisioning capacity for your workloads. Keeping a small number of managed node group nodes ensures Karpenter itself and other critical components have a stable place to run.
If your workloads do not have pod disruption budgets configured, scaling down node groups will cause workload disruption.
If you have a large number of nodes, scale down gradually — a few instances at a time — and watch for workloads that might not have enough replicas or disruption budgets configured.
9
Validate the migration
As managed node group nodes are drained, verify that Karpenter is provisioning new nodes to replace them:
With CAS you typically created one node group per combination of instance type, availability zone, and capacity type (on-demand vs Spot). Karpenter collapses this into a single NodePool with a requirements block that expresses the same constraints declaratively.For example, a CAS setup with separate on-demand and Spot node groups across three instance types and three availability zones (18 node groups) maps to a single NodePool: