feat: Simulator Set C - 18-task mock modelled on a commercial CKA sitting

`./exam sim c` - 18 tasks, 163 points, 120 minutes, exam rules. Built after a
23% result on a paid mock, so reruns cost nothing and the weak topics can be
drilled as often as needed.

Original scenarios, not copies, exercising the same techniques as an 18-question
sitting: hostPath PV/PVC bound by volumeName, data migration between claims onto
a Retain volume, Helm render-then-install, Gateway API header canary, RBAC with
the answer written to a file, probe/selector/targetPort repair, HPA v2 behavior
blocks, and three "write the output to an exact path" data-extraction tasks.

Ids 401-418, set="c", difficulty="hard". cmd_sim is already generic over SETS so
no harness change was needed; set-tagged tasks stay out of POOL and cannot leak
into `./exam start` or drills. CKA bank goes 101 -> 119 tasks.

Two scenarios are deliberately adapted, because the originals would destroy the
practice cluster:

  - 410 audits the installed CNI and applies a default-deny, rather than
    installing Calico over the running kindnet. The Flannel-vs-Calico
    "does this CNI actually enforce NetworkPolicy" judgement is kept as a
    written answer.
  - 413 plans a control-plane upgrade - versions, ordered command sequence,
    `kubeadm upgrade node` for workers - and never runs `kubeadm upgrade apply`.
    The grader checks the ordering, modelled on Q316.

Verified end to end: every task seeded, solved with its own reference solution
and graded, 163/163 across all 18, in four batches. Checks were also confirmed
to fail cleanly against an unsolved cluster rather than erroring.

Three environment facts cost a round of debugging and are now encoded in the
tasks and their solutions:

  - The StorageClass on this kind cluster is named `standard`, not `local-path`,
    and is WaitForFirstConsumer - a PVC stays Pending until its pod can be
    scheduled, which is what interlocks the two faults in 414.
  - Under rootless podman the host cannot route to node IPs, so a host-side
    openssl against a NodePort just hangs (rc=124). 417 probes TLS from inside a
    node via nx against 127.0.0.1:<nodePort>. Nodes have openssl and curl but
    not nc or wget.
  - hostPath PV data must be seeded on every node (401, 405), since nothing
    pins the pod to the node holding the directory.

Seeding all 18 creates ~24 pods, which on this host needs
kernel.keys.maxkeys raised above the 200 default or container starts fail with
"unable to join session keyring: disk quota exceeded".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NziZdvBvy7CpEAAbZNgp8i
This commit is contained in:
vumast3r 2026-09-18 09:05:20 -06:00
parent 49fcb76166
commit 65c2fbfd43
2 changed files with 1290 additions and 5 deletions

1283
tracks/cka/bank_sim_c.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -23,8 +23,8 @@ TRACK = {
# tasks per domain drawn into a session (weights follow the exam blueprint) # tasks per domain drawn into a session (weights follow the exam blueprint)
"quota": {"ARCH": 5, "WORK": 4, "NET": 4, "STOR": 2, "TSHOOT": 5}, # 20 tasks "quota": {"ARCH": 5, "WORK": 4, "NET": 4, "STOR": 2, "TSHOOT": 5}, # 20 tasks
"quota_hard": {"ARCH": 6, "WORK": 5, "NET": 5, "STOR": 3, "TSHOOT": 6}, # 25 tasks, hard ones preferred "quota_hard": {"ARCH": 6, "WORK": 5, "NET": 5, "STOR": 3, "TSHOOT": 6}, # 25 tasks, hard ones preferred
# fixed simulator sets (./exam sim a|b) - excluded from random sampling # fixed simulator sets (./exam sim a|b|c) - excluded from random sampling
"sets": {"a": "Simulator Set A", "b": "Simulator Set B"}, "sets": {"a": "Simulator Set A", "b": "Simulator Set B", "c": "Simulator Set C"},
"domains": { "domains": {
"ARCH": "Cluster Architecture, Installation & Configuration (25%)", "ARCH": "Cluster Architecture, Installation & Configuration (25%)",
"WORK": "Workloads & Scheduling (15%)", "WORK": "Workloads & Scheduling (15%)",
@ -630,9 +630,11 @@ $K -n default delete pod sched-probe --wait=false >/dev/null 2>&1
}, },
] ]
# ---- aggregate the banks: 1-20 here, 21-43 in bank_extra, 101-122 (hard) in bank_hard # ---- aggregate the banks: 1-20 here, 21-43 in bank_extra, 101-124 (hard) in bank_hard,
from tracks.cka import bank_extra, bank_hard, bank_sim_a, bank_sim_b # ---- 201-217 / 301-317 / 401-418 in the three fixed simulator sets
QUESTIONS = QUESTIONS + bank_extra.QUESTIONS + bank_hard.QUESTIONS + bank_sim_a.QUESTIONS + bank_sim_b.QUESTIONS from tracks.cka import bank_extra, bank_hard, bank_sim_a, bank_sim_b, bank_sim_c
QUESTIONS = (QUESTIONS + bank_extra.QUESTIONS + bank_hard.QUESTIONS
+ bank_sim_a.QUESTIONS + bank_sim_b.QUESTIONS + bank_sim_c.QUESTIONS)
QUESTIONS.sort(key=lambda q: q["id"]) QUESTIONS.sort(key=lambda q: q["id"])
_ids = [q["id"] for q in QUESTIONS] _ids = [q["id"] for q in QUESTIONS]
assert len(_ids) == len(set(_ids)), "duplicate question ids" assert len(_ids) == len(set(_ids)), "duplicate question ids"