Karpenter — Deploy to a Specific Node Type

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.