Context
Our EKS clusters were running managed node groups with cluster autoscaler. Node group proliferation made it hard to balance coverage across instance types and availability zones. Karpenter promised to simplify this.
Migration approach
I kept the existing node groups running during migration and used node selectors to route new workloads to Karpenter-provisioned nodes. Once confidence was built, I drained the old groups and deleted them.
The Terraform side involved setting up the Karpenter controller via Helm, the IRSA role with the right EC2 permissions, and NodePool/EC2NodeClass resources.
What worked well
- Consolidation mode is aggressive but effective. Idle nodes drain and terminate within minutes.
- Spot fallback with
capacityType: ["spot", "on-demand"]handles interruptions transparently. - Multi-arch NodePools with
arm64let us run Graviton instances where possible.
What needed tuning
disruption.budgetsneeded explicit configuration for stateful workloads to avoid unexpected evictions during business hours.- Some legacy pods had hardcoded node selectors that needed cleanup before Karpenter could fully take over.
Result
Node count dropped for the same workload. Graviton instances cover a significant portion of non-GPU compute now, which meaningfully reduces cost per vCPU hour.