Behind the scenes, Karpenter is a controller that listens for unscheduled pods, selects a matching NodePool, then calls the cloud provider to launch nodes. This episode breaks down the architecture, NodePool, NodeClass, the disruption controller, and karpenter.sh labels.

In episode 1 you understood why Karpenter exists: replacing the reactive, slow nodegroup model with fast, efficient, and simple provisioning. Now it's time to see how Karpenter works behind the scenes.
This episode breaks down Karpenter's core architecture: the flow from an unscheduled pod to a ready-to-use node, the two key concepts that will stay with us throughout the series — NodePool and NodeClass — as well as the CRD components and labels that form Karpenter's "language".
Karpenter runs as a controller inside the cluster. It's not part of the control plane, but a regular deployment you can see in the karpenter namespace. The flow looks like this:
Unscheduled pod (Pending / Unschedulable)
│
▼
Karpenter controller detects the pod
│
▼
Matching NodePool is selected (scheduling & capacity)
│
▼
Cloud provider (AWS) launches the instance
│
▼
Node registers to the cluster, pod gets scheduledTip
The key point: Karpenter doesn't wait for a nodegroup. It directly brings the pods' needs to the cloud provider and picks the most suitable instance. That's why its latency is far below Cluster Autoscaler.
These two concepts are the foundation of all Karpenter configuration. Understanding how their roles are divided will save you from confusion in the upcoming episodes.
NodePool answers the question what is allowed to be scheduled. It defines:
A NodePool points to a NodeClass for infrastructure matters.
NodeClass answers the question where and how nodes are created. On AWS, it's EC2NodeClass and defines:
| Aspect | NodePool | NodeClass |
|---|---|---|
| Role | Scheduling & capacity | Infrastructure |
| Question | What is allowed to be scheduled | Where and how it's created |
| On AWS | karpenter.sh/v1 NodePool | karpenter.k8s.aws/v1 EC2NodeClass |
| Example contents | Requirements, weight, disruption | AMI, subnet, security group, userData |
This division lets one NodeClass be used by many NodePools, or one NodePool point to different NodeClasses — a flexible combination for various workload types.
Karpenter 1.14.0 works through a set of CustomResourceDefinitions:
karpenter.sh/v1) — scheduling policy, successor to the old provisioner resource.karpenter.k8s.aws/v1) — AWS infrastructure specification.The v1 API is GA. Since Karpenter 1.1.0, the old v1beta1 API was removed, so all configuration in this series uses the v1 API.
When creating nodes, Karpenter attaches labels and annotations that are very useful for operations:
| Name | Type | Purpose |
|---|---|---|
| karpenter.sh/nodepool | label | Which NodePool the node came from |
| karpenter.sh/capacity-type | label | spot or on-demand |
| node.kubernetes.io/instance-type | label | The EC2 instance type used |
| topology.kubernetes.io/zone | label | The node's availability zone |
| karpenter.sh/registered | annotation | Marks the node as registered to the cluster |
| karpenter.sh/do-not-disrupt | annotation | Protects a pod from disruption |
kubectl get nodes -l karpenter.sh/nodepool=default -o wide
kubectl get nodepools
kubectl get nodeclaimsPay attention to the labels in the output of kubectl get nodes -l karpenter.sh/nodepool=default -o wide — you'll see the instance type, zone, and capacity type Karpenter chose for each node.
This episode dissected Karpenter's architecture. Karpenter is an in-cluster controller that detects Unschedulable pods, selects a matching NodePool, then calls the cloud provider to launch the optimal node. The two key concepts you must hold onto are NodePool (scheduling and capacity policy) and NodeClass (infrastructure specification). CRDs like NodeClaim and the disruption controller complete the architecture, while karpenter.sh labels serve as the observability bridge.
Key takeaways:
In episode 3 we go hands-on: setup and installation. We'll create an EKS cluster from scratch, install the CRDs and Karpenter controller via Helm, build a minimal IAM role, then verify with our first NodePool and EC2NodeClass examples. See you in the next episode!