Karpenter is an open-source node autoscaler for Kubernetes. Instead of resizing predefined node groups, it watches for pods the scheduler cannot place, chooses instance types that fit their combined requirements, and launches those nodes directly through the cloud provider API. It also removes or replaces nodes that are empty, underused or out of date. It addresses two familiar costs of cluster autoscaling: slow scale-up through node group abstractions and wasted capacity from oversized, fixed instance shapes. Karpenter was created at AWS and released in 2021. The core library now lives in the Kubernetes SIG Autoscaling organisation, with cloud-specific providers built on it. NON CNCF: Karpenter is not a CNCF project. The CNCF Landscape lists it as a project hosted by Kubernetes SIG Autoscaling, without a CNCF maturity level, and this brief covers it as a Landscape item.
CNCF daily · Sprint 2, day 8 · Continuous Optimization · NON CNCF
At a glance
| Category | Observability and Analysis › Continuous Optimization |
| CNCF status | NON CNCF, listed in the CNCF Landscape. Developed under Kubernetes SIG Autoscaling |
| Written in | Go |
| License | Apache 2.0 |
| Providers | AWS (the original and most widely used), Azure (basis of AKS Node Auto Provisioning), with community providers for other platforms |
| Core resources | NodePool, NodeClaim and a provider-specific node class (EC2NodeClass on AWS) |
| Stable API | v1 APIs, generally available since 2024 |
Architecture
flowchart TB
POD[Pending pods<br/>unschedulable] ==>|watch| CORE[Karpenter controller<br/>scheduling and disruption]
NP[NodePool<br/>constraints and limits] ==>|rules| CORE
NC[Node class<br/>subnets AMI security groups] ==>|cloud settings| CORE
CORE ==>|NodeClaim| PROV[Cloud provider<br/>AWS or Azure]
PROV ==>|launch instance| NODE[New node<br/>joins the cluster]
NODE ==>|pods scheduled| POD2[Running pods]
CORE -.->|consolidate drift expire| NODE
CORE -.->|cordon and drain| POD2
classDef core fill:#0f766e,stroke:#064e4a,stroke-width:2px,color:#ffffff
classDef data fill:#e3f2fd,stroke:#1565c0,stroke-width:1.5px,color:#1d1c1a
classDef ctrl fill:#ede7f6,stroke:#5e35b1,stroke-width:1.5px,color:#1d1c1a
class CORE core
class POD,POD2,NODE data
class NP,NC,PROV ctrl
Key: teal is the Karpenter controller, blue are workloads and nodes, purple are configuration and the cloud API. Thick arrows show provisioning, dashed arrows show disruption of existing nodes.
| Component | Responsibility |
|---|---|
| Controller | Batches pending pods, simulates scheduling, picks the cheapest instance types that satisfy them, and decides which nodes to remove. |
| NodePool | Declares what Karpenter may launch: instance categories, architectures, capacity types (on-demand or spot), zones, taints, limits and disruption rules. |
| Node class | Provider-specific settings such as machine image, subnets, security groups, instance profile and tags. |
| NodeClaim | The request for one node, tracked through launch, registration and termination. |
| Provider | Calls the cloud API to create and delete instances. |
Design principle. Scale from workload requirements, not from node group definitions. Pods state what they need, NodePools state what is allowed, and Karpenter picks the cheapest machine that satisfies both, then continuously repacks the cluster as demand changes.
Production reference design
A common deployment is Amazon EKS with a small managed node group for system components and Karpenter provisioning the rest.
- Prepare the cluster. Run Karpenter itself on a node group or Fargate profile that it does not manage, with IAM permissions (for example through EKS Pod Identity or IRSA) and an interruption queue for spot and health events.
- Install. Use the official chart from the OCI registry, pinning the version listed in the documentation:
helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter \ --version <version> --namespace kube-system \ --set settings.clusterName=<cluster-name> - Define capacity. A NodePool with a node class, allowing spot and on-demand, with a cost-aware disruption policy:
apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: general spec: template: spec: nodeClassRef: group: karpenter.k8s.aws kind: EC2NodeClass name: default requirements: - key: karpenter.sh/capacity-type operator: In values: ["spot", "on-demand"] - key: kubernetes.io/arch operator: In values: ["amd64", "arm64"] limits: cpu: "1000" disruption: consolidationPolicy: WhenEmptyOrUnderutilized consolidateAfter: 1m - Set pod requirements. Give workloads accurate resource requests, topology spread constraints and PodDisruptionBudgets, because Karpenter sizes nodes from these.
- Observe. Scrape the controller metrics with Prometheus and watch provisioning latency, node count and cost per NodePool.
Typical uses include elastic web and API tiers, batch and CI workloads, spot-heavy clusters, and GPU capacity that should appear only when jobs need it. Confirm resource names against the documentation for your version and provider.
Operational considerations
- Resource requests drive everything. Pods without realistic requests produce poor packing. Combine Karpenter with right-sizing tools such as OpenCost reports or a vertical autoscaler.
- Disruption control. Consolidation, drift and expiration replace nodes. Use PodDisruptionBudgets,
do-not-disruptannotations and disruption budgets on the NodePool to protect sensitive workloads. - Spot resilience. Spot nodes can be reclaimed. Spread across instance types and zones, handle interruption signals, and keep critical pods on on-demand capacity.
- Limits. Set NodePool limits so a runaway deployment cannot launch unbounded nodes.
- Upgrades. Karpenter versions track Kubernetes versions. Follow the compatibility matrix and test upgrades, particularly around API and drift behaviour.
Adoption
- AWS created Karpenter, documents it as the recommended node autoscaler for Amazon EKS, and operates it as part of EKS Auto Mode.
- Microsoft Azure maintains the Azure provider, which underlies AKS Node Auto Provisioning.
- The project’s documentation and the ADOPTERS list in its repository name further organisations; consult them for current, first-party names rather than relying on third-party summaries.
Alternatives
| Solution | Model | Best suited to |
|---|---|---|
| Kubernetes Cluster Autoscaler | Scales predefined node groups | Multi-cloud estates and clusters with fixed node group designs |
| EKS Auto Mode / AKS Node Auto Provisioning | Managed offerings built on Karpenter | Teams that prefer the provider to operate node management |
| KEDA (CNCF Graduated) | Event-driven pod autoscaling | Scaling workloads on queues and metrics; see the KEDA brief |
| Commercial optimisers (for example Spot Ocean, Cast AI) | Managed cost optimisation | Multi-cloud automation with vendor support |
| Manual node groups | Static or scheduled capacity | Stable, predictable workloads |
Strengths and limitations
| Strengths | Limitations |
|---|---|
| Fast, right-sized provisioning from pod requirements | Not a CNCF project; governed through Kubernetes SIG Autoscaling |
| Consolidation lowers cost by repacking nodes | Mature on AWS and Azure; other providers vary in maturity |
| Strong spot and instance diversity support | Node churn can disrupt workloads without budgets and PDBs |
| Declarative NodePool policy replaces many node groups | Quality depends on accurate pod resource requests |
| GA v1 APIs and wide production use on EKS | Provider-specific node classes reduce portability |
Recommendation
Adopt on Amazon EKS and Azure AKS, where Karpenter has first-party support, and Assess elsewhere according to provider maturity. Begin with one NodePool for stateless workloads, enforce realistic resource requests and PodDisruptionBudgets, set limits, and widen the scope as consolidation behaviour is understood. Keep a small, separately managed node group for system components.
References: Karpenter documentation · Karpenter repository · Kubernetes SIG Autoscaling · CNCF Landscape