CKAD — Node Selection

3 minute read

Why Control Node Placement?

By default, the Kubernetes scheduler places Pods on any node with enough resources. Sometimes you need more control — you might want Pods on GPU nodes, in specific availability zones, or away from certain workloads.

Kubernetes provides several mechanisms for controlling Pod placement:

Mechanism Complexity Use Case
nodeSelector Simple Match specific node labels
Node affinity Medium Flexible rules with preferences
Taints & tolerations Medium Prevent scheduling on certain nodes
Pod affinity/anti-affinity Advanced Co-locate or spread Pods relative to each other

nodeSelector (Simple)

The simplest way to constrain Pods to specific nodes. The Pod will only be scheduled on nodes that have ALL the specified labels.

apiVersion: v1
kind: Pod
metadata:
  name: gpu-app
spec:
  nodeSelector:
    accelerator: nvidia-gpu
  containers:
  - name: app
    image: my-gpu-app:v1
# Label a node first
kubectl label node worker-1 accelerator=nvidia-gpu

# Verify the label
kubectl get nodes --show-labels | grep accelerator

# Now create the Pod — it will be scheduled on worker-1
kubectl apply -f gpu-pod.yaml

nodeSelector Behavior

Scenario Result
Node with matching labels exists Pod scheduled on that node
Multiple nodes match Scheduler picks the best one based on resource availability
No nodes match Pod stays in Pending state
Label removed from node Running Pods stay; new Pods won’t schedule there

Node Affinity (Advanced)

Node affinity is a more expressive version of nodeSelector. It supports “preferred” rules (soft constraints) and set-based operators.

Required Affinity (Hard Constraint)

The Pod MUST be scheduled on a matching node. If no nodes match, the Pod stays Pending.

apiVersion: v1
kind: Pod
metadata:
  name: zone-app
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - us-east-1a
            - us-east-1b
  containers:
  - name: app
    image: nginx:1.27

Preferred Affinity (Soft Constraint)

The scheduler TRIES to place the Pod on a matching node, but will use other nodes if necessary.

apiVersion: v1
kind: Pod
metadata:
  name: preferred-zone
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 80
        preference:
          matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - us-east-1a
      - weight: 20
        preference:
          matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - us-east-1b
  containers:
  - name: app
    image: nginx:1.27

Node Affinity Operators

Operator Description Example
In Value is in the set zone In [us-east-1a, us-east-1b]
NotIn Value is NOT in the set zone NotIn [us-west-2a]
Exists Key exists (any value) gpu Exists
DoesNotExist Key does not exist spot DoesNotExist
Gt Value is greater than cores Gt 4
Lt Value is less than cores Lt 16

nodeSelector vs Node Affinity

Feature nodeSelector Node Affinity
Syntax Simple key-value pairs Expressive match expressions
Hard constraint Yes (only) Yes (required)
Soft constraint No Yes (preferred) with weights
Multiple conditions AND only AND and OR (multiple nodeSelectorTerms)
Set operators No Yes (In, NotIn, Exists, etc.)
When to use Simple cases Complex scheduling requirements

Taints and Tolerations (Preview)

Taints are the opposite of affinity — they repel Pods from nodes. A Pod must have a matching toleration to be scheduled on a tainted node.

# Add a taint to a node
kubectl taint nodes worker-1 gpu=nvidia:NoSchedule

# Remove a taint
kubectl taint nodes worker-1 gpu=nvidia:NoSchedule-
# Pod with a toleration
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  tolerations:
  - key: "gpu"
    operator: "Equal"
    value: "nvidia"
    effect: "NoSchedule"
  containers:
  - name: app
    image: my-gpu-app:v1
Taint Effect Behavior
NoSchedule Don’t schedule new Pods without matching toleration
PreferNoSchedule Try to avoid scheduling, but allow if necessary
NoExecute Evict existing Pods that don’t have matching toleration

Exam tip: For the CKAD exam, focus on nodeSelector and basic node affinity. Taints and tolerations appear more frequently in the CKA exam, but you should understand the basic concept.

Common Node Labels

Kubernetes automatically adds labels to nodes that you can use for scheduling:

Label Description Example Value
kubernetes.io/hostname Node hostname worker-1
kubernetes.io/os Operating system linux
kubernetes.io/arch CPU architecture amd64, arm64
topology.kubernetes.io/zone Availability zone us-east-1a
topology.kubernetes.io/region Region us-east-1
node.kubernetes.io/instance-type Instance type (cloud) m5.large
# View all labels on a node
kubectl get node worker-1 --show-labels

# Filter by a specific label
kubectl get nodes -l topology.kubernetes.io/zone=us-east-1a

Next: Put it all together with Hands-On Lab & Practice →

Updated: