NodePool is the single most important resource in Karpenter, and somehow it's the one every "getting started" guide rushes through like a chef skipping the recipe and just throwing things in the pan.
Let's actually slow down. Twice.
π§Έ The 5-Year-Old Version
Imagine you run a toy store. Customers (pods) walk in wanting toys. You don't keep every possible toy in stock all the time — that costs too much shelf space.
Instead, you keep a rulebook. The rulebook says: "If someone wants a toy, here's what kind of shelf to build, how big it's allowed to be, and when to take it down once nobody's using it anymore."
π That rulebook is the NodePool. Karpenter reads it and builds exactly the shelf (node) needed — then tears it down the moment it's empty.
π§ The SRE Version
A NodePool is a Kubernetes custom resource that tells Karpenter three things:
- What kind of nodes it's allowed to create — instance types, architecture, capacity type
- How much total capacity it can create — limits
- When to remove nodes — disruption policy
It does not directly create nodes itself. It's a template plus a ruleset that Karpenter's controller uses every single time it sees a pod that can't get a seat.
π How the Resources Relate
π NodePool handles the Kubernetes-facing rules — taints, labels, requirements. EC2NodeClass handles the AWS-facing details — AMI, subnets, security groups. Two halves of the same recipe.
⚙️ A Fully Annotated Recipe
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: general-purpose
spec:
template:
metadata:
labels:
team: platform # stamped on every node this pool creates
spec:
requirements:
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand", "spot"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: default
expireAfter: 720h # force a fresh node every 30 days
limits:
cpu: 500 # hard ceiling for this pool
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 1m
π That expireAfter field is underused. It forces periodic node replacement — a quiet way to keep your AMIs fresh without a manual rotation chore.
π§ More Than One Rulebook Is Normal
You're not stuck with just one NodePool. Most production kitchens run several:
- One for general workloads, mixed Spot/on-demand
- One for GPU workloads, specific instance families only
- One for critical, on-demand-only services that don't get to gamble
Karpenter checks every pending pod against every NodePool's rulebook and picks the best fit.
⚠️ Common Mistakes
- Treating NodePool like a Deployment — it doesn't pre-build nodes, only reacts to pending pods
- Forgetting
limits.cpuand getting an unpleasant surprise on the AWS invoice - One giant NodePool trying to serve every workload type instead of splitting by need
π₯ CloudChef Pro Tip
Start small.
π Two NodePools is plenty to begin with: a wide Spot+on-demand general pool, and a narrow on-demand-only pool for anything stateful. Expand once you understand how your workloads actually behave.
π Continue Your CloudChef Journey
π References
π Final Thoughts
NodePool stops being confusing the moment you separate "what Karpenter is allowed to build" from "what Karpenter actually builds."
π The rulebook is yours to write. Karpenter just cooks fast once you hand it the recipe.
No comments:
Post a Comment