Fleet constraints

Fleet constraints let you narrow the set of infrastructure a Fleet is allowed to provision. Instead of accepting every cloud, region, and instance type that the underlying provider offers, you can pin a Fleet to a specific subset, and node auto-provisioning will only consider 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 using nodeSelector, nodeAffinity, or tolerations. This works, but it has two drawbacks: the rules must be repeated across every workload, and a missing or misconfigured selector silently lands a pod on infrastructure it should not run on.

Fleet constraints move that policy out of the pod spec and onto the Fleet itself. Once a Fleet is constrained, 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 reason about. The Fleet is a single place to declare “this group of workloads must run in eu-central-1 on the m7i family only” rather than spreading the same intent across many manifests.

What you can constrain

A Fleet can be constrained 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 compose: a single Fleet can be limited to, for example, 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.

When a cluster has multiple Fleets, the auto-provisioner only considers Fleets whose constraints are compatible with the pod’s scheduling rules. This makes it natural to run a cluster where, for example, one Fleet is constrained to the g4dn GPU instance family for ML workloads and another Fleet is constrained to a general-purpose family for services, and pods 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, and omitting a key places no restriction on it:

  • 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:

{
  "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 will stay Pending because no Fleet can satisfy them.

On this page