Hedronite · Cert Lesson · Cert-Prep / CNCF · Sun 2026-08-16 · Trio #91

CKA Workloads and Scheduling — the knob that does not place

Four knobs. One owner. HPA multiplies a no. PriorityClass cannot invent leftover.

Lesson Class: Cert (CKA Workloads and Scheduling 15%)
Sprint: K8s track · day 25 · trio #91 · k8s_day_counter 8 even
Blueprint: Last unopened CKA domain on this arc. Architecture / Services / Troubleshooting already closed.
Paired Ops: AKS pools and the Pending that is not storage
Paired Dev: Python fit-checker, no bind
Grounding: K8sUR3 pp.86-88 · CKA Q10 Q4 Q19 Q7 Q5
Request
The packing input. Insufficient cpu names this number, not the limit.
Taint
Q10. NoSchedule refuses. NoExecute evicts. Exists-with-no-key is the add-on escape.
HPA
How many, not where. Scaling a refused template is the knob that does not place.
More copies of a no are still a no.

<!-- hal:authoritative:yaml -->

§I — Frame

CKA on this arc is 75% closed. Cluster Architecture 25%, Services and Networking 20%, Troubleshooting 30%. Storage 10% was taken on the 08-10 Ops slot. The last unopened domain is Workloads and Scheduling at 15%.

The exam will not ask you to explain AKS. It will hand you a Pending Pod and four knobs: a request, a taint, a PriorityClass, and an HPA. Only one of them places the Pod. The other three change what the scheduler sees, or how many copies exist, or which running Pod dies so this one can live.

Call the failure the knob that does not place. You scale the HPA. The replica count rises. Every replica is Pending. The scheduler already said no. More copies of a no are still a no.

§II — Requests and limits

A request is the number kube-scheduler reserves. A limit is the number the kubelet enforces after bind (K8sUR3, pp. 86-88). Q4 and Q19 are the drill: write both, then watch which one the Pending event names. The event names the request. Insufficient cpu means the request does not fit allocatable leftover. Raising the limit does not create leftover.

CPU over the request is throttled. Memory over the request can be killed when the node is tight, because pages cannot be stolen the way idle CPU can (K8sUR3, p. 88). A limit below the request is invalid and the API rejects it. A request of zero is valid and is how a burst eats the node.

On the exam, kubectl describe node is the packing sheet. Allocatable minus the requests already bound is the leftover. DaemonSets are already bound. Forgetting them is the usual wrong leftover.

§III — Taints and tolerations

Q10: taint node01 PERMISSION=granted:NoSchedule. Schedule a Pod that names the matching toleration. A Pod without it stays Pending with untolerated taint.

Three effects, three verbs.

EffectNew PodsRunning Pods
NoScheduleRefused if no matchUntouched
PreferNoScheduleAvoided if possibleUntouched
NoExecuteRefused if no matchEvicted if no match

The exam loves NoSchedule and a candidate who types NoExecute and deletes a running workload. Match is key, value, and effect. operator: Exists with no key is the add-on escape. Do not put it on the app Pod unless the question asked you to land on a tainted node and named no key.

The day's Ops lesson is Q10 at cluster scale: AKS already tainted the system pool CriticalAddonsOnly=true:NoSchedule. Your user Pod should fail that predicate. That is success.

§IV — PriorityClass and preemption

Q7 is the knob you reach when no node fits and a lower-priority Pod is sitting on the leftover you need. A PriorityClass is an integer. Higher wins. The scheduler, if preemption is enabled, deletes the lower Pod so the higher one can bind.

Priority does not create capacity. A 2 CPU Pod on a cluster whose largest allocatable leftover is 1 CPU stays Pending at any priority. Preemption needs a victim whose request, once gone, makes the leftover large enough.

Priority also does not bypass taints. A system-cluster-critical Pod still needs the toleration the system pool requires. The add-on Pods have both.

On the exam: create the PriorityClass, set spec.priorityClassName on the Pod, do not invent spec.priority as a raw integer unless the question shows that form. The class is the object the integer lives on.

§V — HPA is not a scheduler

Q5: an HPA adds or removes replicas from a Deployment (or a scale subresource). The new replica is a new Pod. That Pod goes through the same predicates. If the Deployment's template does not fit, the HPA's currentReplicas climbs and readyReplicas does not.

HPA answers "how many." The scheduler answers "where." Requests, taints, and affinity answer "where" first. Scaling a refused template is the knob that does not place.

A question that says "the app is slow, CPU is 90%, Pods are Pending" has two clocks. HPA is the 90%. The Pending is the scheduler. Fix the template (request, taint, pool) before you raise maxReplicas.

§VI — Workloads that change the count, not the fit

Deployments, ReplicaSets, Jobs, CronJobs, and DaemonSets are the rest of the 15%. They change how many Pods exist and which controller owns the restart. They do not change the predicate list.

A DaemonSet is the exception that looks like a bypass: it places one Pod per eligible node, and it often carries the tolerations that land on the system pool. That is why CNI and kube-proxy run there. A DaemonSet without those tolerations still skips tainted nodes. It is not a second scheduler. It is a controller that asks the scheduler once per node.

A Job with parallelism: 10 is ten scheduler decisions. One failed predicate times ten is ten Pendings. backoffLimit does not retry placement. It retries the container after a bind.

§VII — Exam traps

Describe the Pod, then the node. 08-10 Troubleshooting already taught this order for disks. Same order for scheduling. The Pod event names the predicate. The node allocatable confirms it.

**Do not tolerate CriticalAddonsOnly to "make it schedule" unless the question is about add-ons.** That is the AKS fence and the Q10 fence. Opening it is a running app on the wrong node.

HPA vs scheduler. Count vs place. If readyReplicas is 0 and replicas is 5, you do not have an HPA problem.

Priority vs request. Priority picks a victim. The request still has to fit after the victim is gone.

Affinity vs taint. Labels invite. Taints refuse. A node can match your selector and still refuse on a taint. Both predicates run.

§VIII — Practice

Question 1
A Deployment's Pods are Pending with 0/3 nodes are available: 3 node(s) had untolerated taint {PERMISSION: granted}. What is the smallest fix that lands them on node01 only if the question asked for that node?
tap to reveal
Add a toleration for PERMISSION=granted:NoSchedule. If the question also requires that node, add the nodeName or a selector. The toleration alone makes every node with that taint legal.
Question 2
The same Deployment is Pending with Insufficient cpu. HPA maxReplicas is 10. What do you change first?
tap to reveal
The request (or the node capacity). HPA will only create more Pendings.
Question 3
A PriorityClass of 1000 is set. The Pod is still Pending. kubectl describe node shows 500m leftover and the Pod requests 1 CPU. What will preemption not do?
tap to reveal
It will not invent 500m. There is no victim large enough, or no victim at all.
Question 4
You need a Pod on a node you just tainted NoExecute. What happens to a running Pod on that node that has no toleration?
tap to reveal
It is evicted. NoSchedule would have left it. The type is the question.
Question 5
A DaemonSet should run on every node including the AKS system pool. What does the template need that a user Deployment must not copy?
tap to reveal
A toleration for CriticalAddonsOnly. The user Deployment should fail that predicate.
Question 6
Which CKA domain owns a Pending whose event is had volume node affinity conflict?
tap to reveal
Storage, taken on 08-10 Ops. Do not spend the 15% on it. Describe the PVC.

§IX — Close

Workloads and Scheduling is the last CKA domain this arc had not opened. The domain is four knobs and one owner. The owner is kube-scheduler. Requests feed it. Taints restrict it. PriorityClass lets it evict. HPA multiplies the question. The day's Ops lesson is the AKS topology those knobs sit on. The day's Dev lesson is a Python function that prints the no without binding.

CKA blueprint on this arc is now 90% if you count the 08-10 Ops storage fire, 75% on the Cert slot alone. The remaining 10% Storage can wait for a Cert revisit. Next K8s day 2026-08-19 returns to CKS (counter 9, odd): Cluster Hardening 15% or System Hardening 15%.

Related

🫡 ⚖️ 📜
Leo.Syri — Praetor Consulate, Imperium Luminaura
Filed 2026-08-16 at Fajr catch-up · Trio #91 · sprint day 25 · CKA 15%
Ops · Dev · Cert trio shipped MD + HTML in-cycle