Home › CKA › Topics › Practice tasks › Node Scheduling & Maintenance
CKA · Workloads & Scheduling

Node Scheduling & Maintenance

A worker node has been tainted with dedicated=gpu:NoSchedule and labeled gpu=true. Task: Create a pod named gpu-pod in namespace cka-taints that: Uses image nginx:1.25 Has a toleration for the taint…

Check live lab access → All CKA tasks

Live lab access

This task description is public. Its live lab requires full access; six other CKA labs are available in Free Practice with AI Lab Coach.

Create an account to continue →

Explore the six free labs with AI Lab Coach →

Read the brief on any device. Use a desktop or laptop for the terminal lab. Nothing starts until you choose Start.

The task

A worker node has been tainted with dedicated=gpu:NoSchedule and labeled gpu=true.

Task: Create a pod named gpu-pod in namespace cka-taints that:

Original Prepium workshop · Tested on Kubernetes v1.35.0 on 1 October 2026 in a kind cluster with one control-plane node and two workers. Use a disposable cluster with at least two schedulable workers: this workshop taints a node, and a single-node cluster cannot show where Pods go instead.

Taints repel, tolerations permit, selectors attract

A taint on a node keeps Pods away unless they carry a matching toleration. A toleration does not pull a Pod towards the node; it only removes the objection. To place a Pod on a dedicated node you need both: a toleration so it is allowed there, and a nodeSelector or node affinity so it is not allowed anywhere else.

                       taint reserved=batch:NoSchedule   label workload=batch
no toleration, no selector ──✗──→ tainted worker     ✓ other nodes
selector only              ──✗──→ tainted worker     ✗ other nodes  → Pending
toleration + selector      ──✓──→ tainted worker     ✗ other nodes  → Running there

1. Reserve one worker

kubectl create namespace prepium-tutorial
WORKER=$(kubectl get nodes -l '!node-role.kubernetes.io/control-plane' -o jsonpath='{.items[0].metadata.name}')
kubectl label node "$WORKER" workload=batch
kubectl taint node "$WORKER" reserved=batch:NoSchedule
kubectl describe node "$WORKER" | grep -A2 Taints

The taint has three parts: key reserved, value batch, effect NoSchedule. A toleration must match the key, the effect and (with operator: Equal) the value.

2. Ordinary Pods avoid it

kubectl -n prepium-tutorial create deployment spread --image=registry.k8s.io/pause:3.10 --replicas=6
kubectl -n prepium-tutorial get pods -l app=spread -o wide

None of the six Pods lands on the reserved worker. They all go to the other worker, because the control-plane node carries its own NoSchedule taint too.

3. A selector alone is not enough

Save this as taint-pods.yaml. Both Pods select the reserved node; only the second tolerates its taint.

apiVersion: v1
kind: Pod
metadata:
  name: selector-only
  namespace: prepium-tutorial
spec:
  nodeSelector:
    workload: batch
  containers:
    - name: pause
      image: registry.k8s.io/pause:3.10
---
apiVersion: v1
kind: Pod
metadata:
  name: selector-and-toleration
  namespace: prepium-tutorial
spec:
  nodeSelector:
    workload: batch
  tolerations:
    - key: reserved
      operator: Equal
      value: batch
      effect: NoSchedule
  containers:
    - name: pause
      image: registry.k8s.io/pause:3.10
kubectl apply -f taint-pods.yaml
kubectl -n prepium-tutorial get pods -o wide
kubectl -n prepium-tutorial describe pod selector-only | tail -3

selector-and-toleration runs on the reserved worker. selector-only stays Pending, and the scheduler explains why in one line: 0/3 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 2 node(s) had untolerated taint(s). Read it as a filter: the one node without the label was excluded by the selector, and the two remaining nodes (the reserved worker and the control plane) were excluded by taints.

The reverse case, a toleration without a selector, schedules fine but may land on any node. That is the usual reason a "dedicated node" Pod ends up somewhere else in practice: the toleration made the node possible, nothing made it required.

4. NoExecute evicts what is already running

kubectl taint node "$WORKER" maintenance=true:NoExecute
kubectl -n prepium-tutorial get pods -o wide --watch

NoSchedule only affects scheduling decisions; Pods already on the node stay. NoExecute also evicts running Pods that do not tolerate it, so selector-and-toleration disappears: it tolerates reserved, not maintenance. A toleration for a NoExecute taint can add tolerationSeconds to stay for a limited time before eviction.

5. Remove the taints

kubectl taint node "$WORKER" maintenance=true:NoExecute- reserved=batch:NoSchedule-
kubectl -n prepium-tutorial get pod selector-only -o wide
kubectl label node "$WORKER" workload-

The trailing - removes a taint or label. As soon as the taints are gone, selector-only schedules onto the worker, because its label still matches: the taint was the only thing blocking it. Removing the label afterwards does not evict it. A nodeSelector is checked when the Pod is scheduled, not continuously.

Example checkEvidence
Pod tolerates the taintA toleration with matching key, value and effect in the Pod spec
Pod is placed on the intended nodenodeSelector matches the node label; -o wide shows that node
Pod is actually runningPhase Running, not Pending

Cleanup: kubectl delete namespace prepium-tutorial, and confirm with kubectl describe node "$WORKER" | grep Taints that the worker shows <none>. Reference: Taints and Tolerations. Next, try Pod priority and preemption.

Exam
CKA
Domain
Workloads & Scheduling
Grading
Programmatic · partial credit

What this tests

Run and schedule workloads - deployments, autoscaling, taints and tolerations, affinity, and resource limits. On the CKA exam, Workloads & Scheduling tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.

Practice it for real

The public description lets you study the task before signing up. Full access includes every live lab. Six selected CKA scenarios are included in Free Practice, with five shared sessions each week. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.

Related CKA tasks