Running EKS for a year now. Bills are getting stupid. Need to cut costs but can't afford downtime or a huge ops lift.
Current setup:
* 3 managed node groups, mixed instance types (m5.large, c5.xlarge)
* Cluster autoscaler, but it's conservative.
* Lots of low-utilization pods during off-hours.
What are the most effective levers to pull? I'm thinking:
* Right-sizing nodes with a better mix of spot/on-demand.
* Tuning the autoscaler profiles.
* Maybe looking at Karpenter?
Need real configs or proven steps. What actually works for you at ~50 nodes? What broke?
YAML all the things.
Your three initial ideas are the right starting points, but their order and execution are critical. Tuning the autoscaler first is often a trap - it's polishing a potentially flawed foundation.
Based on my last cost audit, the sequence should be: 1) implement a Spot/on-demand mix via separate managed node groups, 2) switch to Karpenter for consolidation, *then* 3) tune scaling. A mixed instance type node group with Cluster Autoscaler is fighting itself; you can't optimize spot interruption handling and bin-packing simultaneously. At your scale, I saw a 37% immediate cost drop just by splitting out a dedicated spot node group with a clear node selector/toleration strategy, before any autoscaler changes.
Karpenter is the real step-change, though. Its provisioning model lets you specify a much wider instance family list, which directly addresses your "better mix" goal. My configuration for a similar workload uses a provisioner like this, focusing on flexible CPU/memory shapes rather than fixed types. The consolidation feature alone reclaimed 20% of wasted capacity from those low-utilization pods.
```
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: default
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: node.kubernetes.io/instance-type
operator: In
values: ["m5.*", "m6a.*", "c5.*", "c6a.*"]
consolidation:
enabled: true
```
What broke? Any StatefulSet without graceful handling for spot termination. You'll need to verify your PDBs and rollout strategies. Also, Karpenter's default deprovisioning can be aggressive; start with `consolidationPolicy: WhenUnderutilized` and a longer `ttlSecondsUntilExpired`.
benchmarks or bust