feat(ckad): add Simulator Set A, a 20-task killer.sh-style mock

A fixed CKAD set (ids 38-57, 140 points, 120 minutes), run with
`./exam sim a`. It is kept out of the random pool, so reruns are
comparable. The scenarios are original - a fictional river-freight company,
one Namespace per river - and practise the techniques the killer.sh CKAD
environment is known for without reusing its questions: exact names and
file outputs, commands written to scripts, several steps per task.

It covers what the pool never asks: debugging a container with no shell
through an ephemeral container (the value lives only in the process's
environment), a Kustomize patch with a hashed configMapGenerator, a Helm
release stuck in `failed`, a CronJob run by hand while suspended, fsGroup
on a shared volume, RBAC proven by the app's own log, Pods rejected by a
LimitRange, and the two-source NetworkPolicy trap (enforced by kindnet).

Verified on a throwaway cluster: every task scores 0 untouched and 7/7 when
solved, and a full sitting (baseline, seed all 20, solve, grade at the end)
scored 140/140 twice on the final code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VchE1CFkJqwYhXSMTPZUtD
This commit is contained in:
vumast3r 2026-09-26 18:14:12 -06:00
parent e6ee219dfc
commit d3788be5e2
3 changed files with 1240 additions and 6 deletions

View File

@ -5,8 +5,8 @@ Entry point is `./exam` (renamed from `cka-sim` so it can't collide with the dir
Hands-on exam tasks graded **per check** against a real cluster, an exam clock, a browser Hands-on exam tasks graded **per check** against a real cluster, an exam clock, a browser
front end modelled on the real PSI exam, attempt history, and drills that rotate through the front end modelled on the real PSI exam, attempt history, and drills that rotate through the
domains before you sit a full exam. Tracks: **CKA** (102 tasks: a random pool of 43 normal + domains before you sit a full exam. Tracks: **CKA** (102 tasks: a random pool of 43 normal +
24 hard, plus two fixed simulator sets, C and D, of 18 and 17 tasks), **CKAD** (37 tasks, at 24 hard, plus two fixed simulator sets, C and D, of 18 and 17 tasks), **CKAD** (37 pool tasks, at
least one for every competency in the curriculum) and CKS (scaffolded — same format, add least one for every competency in the curriculum, plus a 20-task killer.sh-style Set A) and CKS (scaffolded — same format, add
questions when you get there). questions when you get there).
## How a session is built ## How a session is built
@ -93,6 +93,14 @@ A few tasks need more than kubectl on this machine: `podman` (Q13 builds an imag
(Q6, Q21), and network access the first time Q23 runs on a fresh cluster (it installs (Q6, Q21), and network access the first time Q23 runs on a fresh cluster (it installs
metrics-server). Drill a domain with `./exam --track ckad drill ENV`, as for CKA. metrics-server). Drill a domain with `./exam --track ckad drill ENV`, as for CKA.
**Simulator Set A** (`./exam --track ckad sim a`): 20 original killer.sh-style tasks, 140 points,
120 minutes, exam rules - a fixed set (ids 38-57) kept out of the random pool, so reruns are
comparable. Riverline, a fictional river-freight company, one Namespace per river. Expect several
steps per task, exact names and file outputs, and a few things the pool never asks: debugging a
container with no shell through an ephemeral container, a Kustomize patch with a hashed
configMapGenerator, a Helm release stuck in `failed`, fsGroup on a shared volume, and the
two-source NetworkPolicy trap.
## Scoring, history, drills ## Scoring, history, drills
Each task is a list of named, weighted checks (`tracks/cka/questions.py`). You get the points Each task is a list of named, weighted checks (`tracks/cka/questions.py`). You get the points

1223
tracks/ckad/bank_sim_a.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
"""CKAD track: 37 tasks, at least one per competency in the CKAD curriculum (1-12 here, 13-37 in """CKAD track: 37 pool tasks, at least one per competency in the CKAD curriculum (1-12 here, 13-37
bank_extra.py). Same format as the CKA banks. in bank_extra.py), plus Simulator Set A (38-57, bank_sim_a.py). Same format as the CKA banks.
CKAD is a build-things exam: less cluster surgery, more "produce the right object, fast". CKAD is a build-things exam: less cluster surgery, more "produce the right object, fast".
The clock is the adversary, so these are mostly single-object tasks graded exactingly. The clock is the adversary, so these are mostly single-object tasks graded exactingly.
@ -22,6 +22,8 @@ TRACK = {
# 8/7/7/10/5, so no two mocks are the same set. # 8/7/7/10/5, so no two mocks are the same set.
"quota": {"DESIGN": 3, "DEPLOY": 3, "OBS": 3, "ENV": 4, "NET": 3}, "quota": {"DESIGN": 3, "DEPLOY": 3, "OBS": 3, "ENV": 4, "NET": 3},
"quota_hard": {"DESIGN": 3, "DEPLOY": 3, "OBS": 3, "ENV": 4, "NET": 3}, "quota_hard": {"DESIGN": 3, "DEPLOY": 3, "OBS": 3, "ENV": 4, "NET": 3},
# fixed simulator sets (./exam sim a) - excluded from random sampling
"sets": {"a": "Simulator Set A (killer.sh-style)"},
} }
QUESTIONS = [ QUESTIONS = [
@ -579,6 +581,7 @@ EOF
] ]
# 13-37: the rest of the curriculum, one or more tasks per competency the starter bank left out. # 13-37: the rest of the curriculum, one or more tasks per competency the starter bank left out.
from tracks.ckad import bank_extra # noqa: E402 # 38-57: Simulator Set A, a fixed killer.sh-style mock. Numbering is contiguous - keep it that way.
from tracks.ckad import bank_extra, bank_sim_a # noqa: E402
QUESTIONS = QUESTIONS + bank_extra.QUESTIONS QUESTIONS = QUESTIONS + bank_extra.QUESTIONS + bank_sim_a.QUESTIONS