Karpenter

Buoy detects Karpenter through its two groups: karpenter.sh (NodePool, NodeClaim) and the cloud-provider classes (karpenter.k8s.aws EC2NodeClass, AKSNodeClass, GCENodeClass). When any of these kinds are present, Buoy surfaces dedicated tabs that walk the NodePool, NodeClaim, and Node graph, and the scheduling explainer evaluates per-pool fit.

The sidebar’s cluster-scoped section lists NodePools, NodeClaims, and any NodeClass kinds when present, so you can jump in without typing.

The Karpenter Object Graph

EC2NodeClass ◄── nodeClassRef ── NodePool ── produces ──► NodeClaim ── becomes ──► Node

Karpenter sets two labels Buoy reads everywhere:

  • karpenter.sh/nodepool=<name> on every NodeClaim and on every Node the claim produces.
  • karpenter.sh/nodeclaim=<name> on the Node, when set.

NodeClaim names usually match the Node name they produce; the NodeClaim’s status.nodeName is authoritative.

On a NodePool

The detail view exposes the standard Overview, YAML, Events, and Related tabs, plus two fleet tabs:

TabContents
RelatedAn upstream link to the referenced NodeClass, plus a compact NodeClaims list and a Nodes list. Each section header shows the count, total CPU (in cores), and total memory (binary suffix).
NodeClaimsFull ResourceTable scoped to karpenter.sh/nodepool=<name>. Cluster-scoped, so no namespace column.
NodesFull ResourceTable for the Nodes those claims produced, scoped to the same label.

The Related tab is the right place to glance at fleet health; the NodeClaims and Nodes tabs are for sorting, filtering, and selecting rows to act on. Anything you can do to a Node from its own detail view (cordon, drain, delete) applies through bulk actions on the Nodes tab.

On a NodeClass

EC2NodeClass, AKSNodeClass, and GCENodeClass all use the same renderer. There is no direct label on NodeClaims or Nodes that points at a NodeClass; the link runs through the NodePools that reference it.

TabContents
RelatedThe list of NodePools whose spec.template.spec.nodeClassRef.name and kind match this class, plus the unioned NodeClaim and Node lists for every matching pool. Empty when nothing references the class.
NodeClaimsFull ResourceTable scoped by the unioned label selector karpenter.sh/nodepool in (pool1, pool2, ...).
NodesSame union, but for the Nodes those claims produced.

If no NodePool references the class, the fleet tabs show an empty state (“no NodePools reference this NodeClass”) rather than the entire cluster’s nodes.

On a NodeClaim

NodeClaim is 1:1 with a Node, so it does not get the fleet tabs. The Related tab links upstream to the parent NodePool and NodeClass, and downstream to the Node it produced (when status.nodeName is set).

Pool Requirements

NodePool requirements (spec.template.spec.requirements[]) are NodeSelectorRequirement entries. Buoy renders them in a readable form on the Overview tab:

karpenter.sh/capacity-type in [on-demand, spot]
node.kubernetes.io/instance-type in [m6i.large, m6i.xlarge]
kubernetes.io/arch in [amd64]
karpenter.sh/nodepool not in [reserved]

The same requirements drive the scheduling explainer’s pool-fit verdicts.

The Pod Scheduling tab’s NodePools sub-tab evaluates each Karpenter NodePool against the pod’s constraints using requirement intersection, taint coverage, limits, and an instance-type fit heuristic. See scheduling.md for the rule sources, the verdict shape, and the instance-type catalog caveat (the catalog is built from observed instance types on existing nodes, so a fresh cluster may report false negatives).


Edit this page on GitLab