Skip to content

Karpenter — Deploy to a Specific Node Type

karpenter

EKS Auto mode comes with pre-installed Karpenter Autoscaler, a default NodeClass, and a default NodePool. The default NodePool provisions AMD architecture, on-demand servers.

Some applications require specific node types — GPU nodes, ARM-based servers, or Spot instances to reduce cost. Karpenter supports these requirements and, when combined with Kubernetes nodeAffinity and taints and tolerations, allows you to provision and run workloads on specific node types.

Default NodeClass is used here. To customise further, define your own NodeClass.

Schedule a workload on a specific server type

In this example, I am creating a NodePool that provisions Memory Optimised Spot instances. Taints are applied to the NodePool so that only pods with a matching toleration can run on these nodes. Since taints alone are not always sufficient to pin workloads to specific nodes, a node label is also added so pods can select the node using nodeAffinity.

Custom NodePool

The NodePool below provisions Memory Optimised M Spot instances only. It applies a node label instancegroup: spot-m-instancegroup and a taint so that only pods with the matching toleration can be scheduled here.

spot-m-nodepool.yaml

apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: spot-m-nodepool
spec:
  template:
    metadata:
      labels:
        instancegroup: spot-m-instancegroup
    spec:
      expireAfter: 336h
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
      requirements:
      - key: karpenter.sh/capacity-type
        operator: In
        values: ["spot"]
      - key: eks.amazonaws.com/instance-category
        operator: In
        values: ["m"]
      taints:
        - key: instance-type
          value: "spot-m"
          effect: NoSchedule

Application with nodeSelector and toleration

The deployment below has a nodeSelector and tolerations configured so it can only run on nodes labelled instancegroup: spot-m-instancegroup. Deploying this will trigger Karpenter NodePool spot-m-nodepool to provision a new node.

spot-m-echoserver.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echoserver
  namespace: default
spec:
  selector:
    matchLabels:
      app: echoserver
  replicas: 1
  template:
    metadata:
      labels:
        app: echoserver
    spec:
      containers:
        - image: k8s.gcr.io/e2e-test-images/echoserver:2.5
          name: demo-echo
          ports:
            - containerPort: 8080
      nodeSelector:
        instancegroup: spot-m-instancegroup
      tolerations:
        - key: "instance-type"
          operator: "Equal"
          value: "spot-m"
          effect: "NoSchedule"

Describing the pod will confirm that NodePool spot-m-nodepool was selected and the application is running on a Spot instance in the M series.