Fleet constraints

Fleet constraints let you narrow the set of infrastructure a Fleet can provision. Instead of accepting every cloud, region, and instance type that the underlying provider offers, you pin a Fleet to a specific subset. Node auto-provisioning then considers only that subset when it picks nodes for your workloads.

Why use Fleet constraints

Without Fleet constraints, the node auto-provisioner chooses nodes from everything a Fleet exposes. Customers who need to keep workloads in a particular cloud, region, or instance family typically encode those requirements in every Pod specification with nodeSelector, nodeAffinity, or tolerations. This approach works, but it has two drawbacks:

  • You must repeat the rules across every workload.
  • A missing or misconfigured selector silently places a Pod on infrastructure it should not run on.

Fleet constraints move that policy out of the Pod spec and onto the Fleet itself. After you constrain a Fleet, every workload scheduled on it inherits the constraint by default, so:

  • Pod specifications stay simple. You no longer need to repeat the same node selectors and affinities on every Deployment, StatefulSet, or Job.
  • Misconfiguration is harder. A Pod with no scheduling hints still lands on infrastructure that matches your policy.
  • The cluster setup is easier to understand. The Fleet is a single place to declare “this group of workloads must run in eu-central-1 on the m7i family only”. You do not spread the same intent across many manifests.

What you can constrain

You can constrain a Fleet on the following attributes:

  • Region: restrict to one or more regions, for example eu-central-1 only.
  • Instance family: restrict to one or more families, for example only m7i and c7i. Because instance families are provider-specific, selecting families also pins the Fleet to the cloud that offers them.
  • CPU architecture: restrict to amd64 or arm64.
  • Purchase type: restrict to on-demand or spot instances.

These constraints combine. For example, you can limit a single Fleet to the m7i family in eu-central-1 on amd64 only.

How constraints interact with Pod scheduling

Pod-level scheduling rules continue to work and stack on top of Fleet constraints. A Pod’s selectors and affinities must fall within the Fleet’s constraints. If a Pod requests an instance type, region, or cloud that the Fleet does not allow, the Pod stays in Pending because no Fleet can satisfy it.

Flow from left to right. Pod requirements set on every Pod (resource requests, node selectors, node affinity, tolerations) pass through Fleet constraints set once on the Fleet (region, instance family, CPU architecture, purchase type) to produce the candidate instances, and node auto-provisioning picks the cheapest fit.

When a cluster has multiple Fleets, the auto-provisioner considers only Fleets whose constraints are compatible with the Pod’s scheduling rules. For example, you can constrain one Fleet to the g4dn GPU instance family for ML workloads and another Fleet to a general-purpose family for services. Pods then land on the right Fleet automatically based on their requests.

Configuring Fleet constraints

Configure constraints when you create or update a Fleet through the API or the console. In the API, set the constraints object on the Fleet. Each key restricts the values allowed for a Kubernetes label. Multiple keys are ANDed together. If you omit a key, it places no restriction on that label:

  • karpenter.sh/capacity-type: allowed purchase types (on-demand, spot).
  • kubernetes.io/arch: allowed CPU architectures (amd64, arm64).
  • cfke.io/instance-family: allowed instance families (for example m7i, c7i).
  • topology.kubernetes.io/region: allowed regions (for example eu-central-1).

For example, to constrain a Fleet to the m7i family in eu-central-1 on amd64, on-demand only:

json
{
  "constraints": {
    "karpenter.sh/capacity-type": ["on-demand"],
    "kubernetes.io/arch": ["amd64"],
    "cfke.io/instance-family": ["m7i"],
    "topology.kubernetes.io/region": ["eu-central-1"]
  }
}

Before constraining a Fleet that already runs workloads, check that the Pods currently scheduled on it match the new constraints. Otherwise they stay Pending because no Fleet can satisfy them.

On this page