← worklog

2025-03-10

Migrating from managed node groups to Karpenter on EKS

AWS EKSKarpenterTerraformKubernetes

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 arm64 let us run Graviton instances where possible.

What needed tuning

  • disruption.budgets needed 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.