Skip to main content

General

Karpenter v1 is the first stable Karpenter API. Any future incompatible API changes will require a v2 version.
See Configuring NodePools for information on how Karpenter configures and manages nodes.
AWS is the first cloud provider supported by Karpenter, although it is designed to be used with other cloud providers as well.
Yes, but there is no documentation yet for it. Start with Karpenter’s GitHub cloudprovider documentation to see how the AWS provider is built. Note that other sections of the code will also require changes.
Karpenter uses the OS defined by the AMI Family in your EC2NodeClass.
Yes. Karpenter has multiple mechanisms for configuring the operating system for your nodes.
Yes. Karpenter is flexible to multi-architecture configurations using well known labels.
All required RBAC rules can be found in the Helm chart templates:
Yes, as long as the controller has network and IAM/RBAC access to the Kubernetes API and your cloud provider API.
Refer to Reporting Security Issues for information on how to report Karpenter security issues.
Do not create a public GitHub issue for security vulnerabilities.

Compatibility

See the Compatibility Matrix in the Upgrade Section to view the supported Kubernetes versions for each Karpenter release.
Karpenter documents integration with fresh or existing installations of the latest AWS Elastic Kubernetes Service (EKS). Other Kubernetes distributions (KOPs, etc.) can be used, but setting up cloud provider permissions for those distributions has not been documented.
NodePools are designed to work alongside static capacity management solutions like EKS Managed Node Groups and EC2 Auto Scaling Groups. You can:
  • Manage all capacity using NodePools
  • Use a mixed model with both dynamic (Karpenter) and statically managed capacity
  • Use a fully static approach
Most users are expected to use a mixed approach near-term and migrate to fully NodePool-managed capacity over time.
  • Kubernetes Cluster Autoscaler: Karpenter can work alongside Cluster Autoscaler. See Kubernetes Cluster Autoscaler for details.
  • Kubernetes Scheduler: Karpenter focuses on scheduling pods that the Kubernetes scheduler has marked as unschedulable. See Scheduling for details.

Provisioning

See the NodePool API docs for NodePool examples and descriptions of features.
Yes. NodePools can identify multiple teams based on labels. See the NodePool API docs for details.
Pending pods will be handled by any NodePool that matches the pod’s requirements. There is no ordering guarantee if multiple NodePools match.
Set up NodePools to be mutually exclusive. To explicitly target a specific NodePool, use the node selector karpenter.sh/nodepool: my-nodepool.
There is no native support for namespace-based provisioning. Karpenter can be configured to provision a subset of pods using a combination of taints/tolerations and node selectors. This ensures that Karpenter, kube-scheduler, and other scheduling mechanisms all share an identical understanding of which pods can schedule on which nodes.We recommend using Kubernetes native scheduling constraints to achieve namespace-based scheduling segregation. This can be enforced via policy agents — see this example for reference.
Karpenter does not offer a way to add SSH keys via NodePools or secrets to managed nodes. However, you can use Session Manager (SSM) or EC2 Instance Connect to gain shell access.If you need access without AWS credentials, you can add SSH keys using EC2NodeClass User Data. See the User Data section in the EC2NodeClass documentation for details. This approach is not recommended.
Yes. See the NodePool API docs for examples and configuration details.
Yes. See the NodePool API docs for an example of combining Spot and On-Demand using a single NodePool with multiple capacity types.
  • Attribute-based requests (e.g. “give me instances with at least X vCPUs”) are currently not possible via direct attributes.
  • You can select instances with special hardware, such as GPUs.
  • Use the node.kubernetes.io/instance-type label in your NodePool’s requirements to restrict to specific instance types.
Yes. Karpenter supports provisioning metal instance types when a NodePool’s node.kubernetes.io/instance-type requirements only include metal instance types. If other instance types also fulfill pod requirements, Karpenter will prioritize all non-metal instance types before provisioning metal ones.
Karpenter batches pending pods and binpacks them based on CPU, memory, and GPU requirements — accounting for node overhead, VPC CNI resources, and DaemonSets. Karpenter recommends C, M, and R instance families at Gen 3 or newer for most generic workloads, but this can be constrained in the NodePool spec.After identifying the most efficient instance type (smallest that fits the pod batch), Karpenter selects 59 additional larger instance types and passes all 60 options to the Amazon EC2 Fleet API.The Fleet API uses the Price Capacity Optimized allocation strategy. For on-demand capacity this is equivalent to lowest-price. For spot, Fleet selects the instance type with the lowest price combined with the lowest interruption probability — this may not be the strictly cheapest spot option.
Karpenter currently calculates applicable DaemonSets at the NodePool level using label selectors and taints. It does not evaluate whether DaemonSet requirements would exclude them from particular instance types that a NodePool could launch.
Use multiple NodePools with taints/tolerations or label selectors to limit DaemonSets to nodes launched from specific NodePools.
The best defense against running out of spot capacity is to allow Karpenter to provision from as many distinct instance types as possible. Instance types with higher specs than required can still be cheaper in the spot market than on-demand instances.When spot capacity is constrained, on-demand capacity may also be constrained since spot is fundamentally spare on-demand capacity. A diverse set of instance types increases the chance of continuing to launch both spot and on-demand capacity.Karpenter models each instance type as a set of “offerings” (combinations of zone and capacity type). When the Fleet API returns an insufficient capacity error for spot, those specific offerings are temporarily removed from consideration so Karpenter can make forward progress with other options.
Yes. Karpenter dynamically detects if you are running an IPv6 cluster by checking the kube-dns service’s cluster IP. When using an AMI family such as AL2, Karpenter will automatically configure the EKS bootstrap script for IPv6.Some EC2 instance types do not support IPv6. The Amazon VPC CNI only supports instance types running on the Nitro hypervisor. Add a requirement to your NodePool to restrict to Nitro instances:
apiVersion: karpenter.sh/v1
kind: NodePool
spec:
  template:
    spec:
      requirements:
        - key: karpenter.k8s.aws/instance-hypervisor
          operator: In
          values:
            - nitro
For more information, see the EKS IPv6 CNI docs.
Windows nodes do not support IPv6.
A DaemonSet, userData configuration, or other workload may apply a taint after a node is provisioned. Once the taint is applied, Karpenter detects that the original pod cannot schedule on the new node and provisions another node.Typically, the taint is eventually removed from the original node and the pod schedules there, leaving the extra node unused and removed by consolidation. If the taint is not removed quickly enough, Karpenter may remove the original node before the pod can schedule, potentially creating an infinite loop.Configure startupTaints to make Karpenter aware of temporary taints. For example, for Cilium:
apiVersion: karpenter.sh/v1
kind: NodePool
spec:
  template:
    spec:
      startupTaints:
        - key: node.cilium.io/agent-not-ready
          effect: NoSchedule

Scheduling

kube-scheduler is responsible for scheduling pods, while Karpenter launches capacity. When using preferred scheduling constraints, kube-scheduler will schedule pods to any available node as soon as possible.For example: if you scale up a deployment with a preferred zonal topology spread and no existing capacity can run the pods, Karpenter launches multiple nodes to satisfy the preference. If one node becomes ready slightly faster and has enough capacity for multiple pods, kube-scheduler schedules as many pods as possible to that single ready node — it doesn’t consider the in-flight capacity that will be ready in a few seconds. If all pods fit on the single node, the remaining Karpenter-launched nodes are unused and removed by consolidation.
Karpenter will not scale up capacity for an additional DaemonSet on its own. The only pod that would schedule on a new node in that case is the DaemonSet pod itself, which provides no scaling benefit. Karpenter only accounts for DaemonSet overhead when calculating scale-ups for workload pods.To prevent new DaemonSet pods from failing to schedule on existing nodes, set a high priority with preemptionPolicy: PreemptLowerPriority on your DaemonSet pods. This guarantees DaemonSet pods schedule on all nodes and causes lower-priority pods to be preempted and rescheduled onto new capacity that Karpenter will launch.
Karpenter provisions nodes according to topologySpreadConstraints. However, if the minDomains field is not set, the Kubernetes scheduler may schedule pods to nodes that do not fulfill zonal spread constraints — particularly when multiple nodes initialize at different times and one has enough capacity for several pods.
Use the minDomains field in topologySpreadConstraints, which is enabled by default starting in Kubernetes 1.27.
An alternative workaround (before minDomains was available) is to launch lower-priority pause containers in each zone before launching your target pods. The pause pods would be preempted when your higher-priority pods are scheduled.

Workloads

See Application developer for a description of how Karpenter matches nodes with pod requests.
Yes. Karpenter automatically detects PVC topology requirements. See Scheduling for details.
The difference between Core and Full variants is that Core is a minimal OS with no GUI or desktop experience. The Windows2019, Windows2022, and Windows2025 AMI families use Windows Server Core for simplicity.If required, you can specify a custom AMI to run Windows Server Full. For example, to use Windows Server 2022 Full for Kubernetes 1.34, configure an amiSelector that references the AMI name:
amiSelectorTerms:
  - name: Windows_Server-2022-English-Full-EKS_Optimized-1.34*
See the Amazon EKS optimized Windows AMI documentation for more details.
No. Karpenter is a node autoscaler — it creates new nodes in response to unschedulable pods. Scaling pods themselves is outside its scope.For pod scaling, consider:

Deprovisioning

See Deprovisioning nodes for information on how Karpenter deprovisions nodes.

Upgrading Karpenter

Karpenter is a controller that runs in your cluster, but unlike the Cluster Autoscaler, it is not tied to a specific Kubernetes version. Use your existing upgrade mechanisms to keep Karpenter up to date on bug fixes and new features.Karpenter requires proper permissions in the KarpenterNode IAM Role and the KarpenterController IAM Role. To upgrade to version $VERSION, ensure both roles have the permissions described in the CloudFormation template at https://karpenter.sh/$VERSION/getting-started/getting-started-with-karpenter/cloudformation.yaml.For full upgrade instructions, see the Upgrade Guide.

Upgrading a Kubernetes cluster

Always validate AMIs in lower environments before using them in production. Read Managing AMIs to understand best practices. If using a custom AMI, trigger the rollout of new worker node images by publishing a new AMI with matching tags or updating the amiSelector field.
Karpenter’s default behavior will upgrade your nodes after you upgrade your EKS cluster. Karpenter uses drift to keep nodes in sync with the EKS control plane version. Drift is enabled by default starting in v0.33 and will auto-discover new AMIs as soon as the cluster is upgraded.
1

Upgrade the EKS cluster control plane

2

Karpenter drifts and replaces nodes automatically

After the upgrade, Karpenter detects that Karpenter-provisioned nodes are using AMIs for the previous cluster version and begins replacing them with nodes using the new EKS Optimized AMIs. Karpenter respects Pod Disruption Budgets and automatically replaces, cordons, and drains nodes.
Follow Kubernetes best practices by setting appropriate pod Resource Quotas and configuring PDBs to best support pods moving to new nodes during the upgrade.

Interruption handling

No. We recommend against using Node Termination Handler (NTH) alongside Karpenter due to conflicts that can occur when both components handle the same events.
Karpenter’s native interruption handling offers two main benefits over the standalone NTH component:
  1. You don’t need to manage and maintain a separate component exclusively for interruption events.
  2. Karpenter’s native interruption handling coordinates with other deprovisioning mechanisms (consolidation, expiration, etc.) so they are mutually aware.
Karpenter requires an SQS queue that receives event messages from EC2 and health services in order to process interruption events for nodes.

Consolidation

Consolidation packs pods tightly onto nodes, which can leave little free allocatable CPU/memory. If a deployment uses a non-zero maxSurge strategy (the default is 25%), the surge pods may have no room to run on existing nodes. Karpenter launches a new node for the surge pods and then removes it once it’s no longer needed.

Logging

Karpenter uses uber-go/zap for logging. Customize log output by editing the data.zap-logger-config field in the configmap-logging.yaml ConfigMap.Available configuration options are specified in the zap.Config godocs.

Build docs developers (and LLMs) love