Commit Graph

26 Commits

Author SHA1 Message Date
e3f5ecd8a6 fix: Q37/Q114 DNS checks were unpassable - busybox ignores search domains
Both checks ran `nslookup kubernetes.default` inside a busybox:1.36 pod and
required it to succeed. busybox's nslookup does not apply the pod's resolv.conf
`search` list - it queries the name literally - so that lookup returns NXDOMAIN
no matter how correctly CoreDNS is configured. Verified in-cluster: from a pod
with a correct `search default.svc.cluster.local svc.cluster.local cluster.local`
and a healthy Corefile, `kubernetes`, `kubernetes.default` and
`kubernetes.default.svc` all return NXDOMAIN while the full
`kubernetes.default.svc.cluster.local` resolves to 10.96.0.1.

The result was a task that could never score more than 3/6: the local drill
history shows this check failing on 4 of 4 attempts with the Corefile fully
repaired.

Use the FQDN in both checks, and say so in the task text so the candidate
verifies the same way the grader does. Q216 in bank_sim_a already used an FQDN;
these two were the outliers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fqcio9TXkEXH35UHebTgoL
2026-09-14 20:54:25 -06:00
df04c56533 fix: create exam contexts when needed, widen baseline reset, bind ttyd to loopback
Three fixes from an audit of the repo:

1. setup_contexts() deleted all three k8s-c?-? contexts and recreated none
   unless the session was started with --hard. But './exam drill <ids>' and
   './exam drill weak' don't filter by difficulty, so hard tasks land in
   hard=False sessions - and 24 of them open with "kubectl config use-context
   ...", which then fails outright. Q121 was unpassable that way: it says to
   deploy into the context's namespace without -n, and its check requires that
   namespace, so the context was the only way to learn the name. Contexts are
   now created whenever a task in the session references one.

   Also fixes how k8s-c2-AC's namespace was chosen: it took the first ns in the
   whole session, which is arbitrary when several tasks share a context. A
   context has one default namespace, so it belongs to the task that actually
   reads it - Q121, now marked "ctx_ns": True.

2. restore_baseline() cleared taint keys dedicated/workload/team, but Q107
   draws from pool/lane and Q307 pins maintenance=inprogress, and nothing
   uncordoned a node. A leaked cordon or taint silently fails every later task
   that counts pods per node (Q26/Q211 DaemonSet coverage, Q212's spread) -
   W1 had been cordoned and tainted across sessions for two days. Clears all
   six keys now and uncordons all three workers.

3. ttyd was launched with -W (writable) and no interface binding, so it listened
   on 0.0.0.0 while the API server correctly bound localhost. That exposed an
   unauthenticated root-equivalent shell with the cluster kubeconfig to the whole
   network. Pinned to loopback, overridable via CKA_TTYD_INTERFACE.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fqcio9TXkEXH35UHebTgoL
2026-09-14 19:43:15 -06:00
595003e377 fix: repair stale reference solutions and Q33's grading check
tracks/cka/solutions.py had drifted out of sync with the actual current
task text for several questions (Q06, 11, 12, 13, 14, 22, 32, 40, 109,
110, 120, 122) - wrong namespaces/resource names, missing required steps,
or output files that were never actually written. Rewrote each to match
its task's real requirements.

tracks/cka/bank_extra.py's Q33 grading check queried
`.spec.aggregationRule` on a ClusterRole, but ClusterRole has no `.spec`
field - `aggregationRule` and `rules` are top-level. Fixed the jsonpath
so a correct answer actually passes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fqcio9TXkEXH35UHebTgoL
2026-09-14 19:23:54 -06:00
fb8cb2a649 files: add yaml for question 3 2026-09-14 16:35:51 -06:00
bf39248ae8 Modified kustomization.yaml and deleted trackers for tasks 2026-09-14 16:33:43 -06:00
63e2503c59 chore: update drill history and weak-spots from today's ARCH/TSHOOT sessions
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 15:53:04 -06:00
0d1604a2bd chore: ignore workspace/ task scratch files
Task setup scripts regenerate workspace/qNN/ on every seed, so it's
runtime output, not source - same reasoning as the earlier q03/q21
untrack. Ignore workspace/* by default, keeping q03 and q21 as the
two already-tracked seed-template exceptions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 15:52:06 -06:00
d755c4017c fix: reset control-plane/node state to baseline before every session
Disruptive tasks corrupt shared state (static pod manifests, kubelet
config, CoreDNS) keyed by a "breaks" target, but a session's setup only
touches the questions it actually contains. If a task isn't re-picked in
a later session, its damage lingers indefinitely - e.g. Q39 wrecking W1's
kubelet config persisted across two unrelated TSHOOT drills that never
included Q39 again.

Add restore_baseline(), run unconditionally in begin_session() before
seeding, that repairs every known "breaks" target (scheduler,
controller-manager, CoreDNS, all three worker kubelets, W1's demo
taints) regardless of which questions are in the new session. Hard-mode-
only breaks (etcd, certs, apiserver) aren't covered yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 15:50:30 -06:00
7dd3763e68 Revert "chore: untrack workspace/q03 seed output"
This reverts commit 7440613f96b1a1554cdba98da4f5a2af4b02afb2.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 10:28:38 -06:00
7440613bfd chore: untrack workspace/q03 seed output
workspace/q03's Q03 setup script wipes and regenerates this base
every time the task is seeded (rm -rf "$WS/q03"; mkdir -p ...), so
these were runtime output that had been accidentally committed
rather than source files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 10:26:49 -06:00
86bf245c19 style: redesign exam web UI with a dark developer theme
The UI was light everywhere except the embedded terminal, which felt
disjointed. Switch to a cohesive dark palette with layered surfaces,
tinted state colors for pass/fail/warn/flag, and polish on buttons,
cards, overlays, and the question nav (hover/active states, shadows,
custom scrollbars).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 10:24:38 -06:00
b7c059151d fix: use kind load image-archive instead of docker-image for podman
kind load docker-image shells out to the docker CLI internally
regardless of KIND_EXPERIMENTAL_PROVIDER, so it can't see images that
only exist in podman's store and fails when the docker socket isn't
reachable. Save each image with podman save and load the tar via
kind load image-archive, which is runtime-agnostic.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-12 10:17:36 -06:00
58a357d7d2 feat: add kube-apiserver failure and node-join-verification tasks
Close two of the four CKA-relevant gaps identified against Killercoda's
scenario catalog:

- Q123 (TSHOOT, hard): kube-apiserver itself crash-loops on a static-pod
  manifest typo, same pattern as the existing scheduler/controller-manager
  failures (Q20/Q118) but with the added twist that kubectl is completely
  unusable until it's fixed, forcing node-level diagnosis (crictl,
  journalctl).
- Q124 (ARCH, hard): produce a real node-join handoff file by
  independently computing the CA discovery hash kubeadm join verifies
  against, and finding the API server's actual in-cluster address rather
  than the local kubeconfig's port-forwarded one.

Cluster-upgrade and operator-authoring remain unimplemented and are
documented as genuine infrastructure gaps in CKA_SOLUTIONS_EXPLAINED.md
(kind's node images have no apt-installable multi-version kubelet/kubeadm,
and operator authoring needs a real built/pushed image) rather than faked.

Also updates the Killercoda cross-reference table with the gaps closed,
and logs an ended drill session to history-cka.jsonl/weak-spots-cka.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 21:25:18 -06:00
3959c072e6 docs: rewrite solutions guide with deeper explanations for all 65 questions
Expand every entry with a concept section explaining the underlying
mechanism, exact commands/YAML pulled from tracks/cka/solutions.py,
and gotchas tied to what each question's grader checks actually
verify. Doc grows from ~750 to ~1540 lines.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 21:05:35 -06:00
e731bda6b1 docs: add missing Q21, Q105, Q106, Q110, Q113, Q121 write-ups
Filled six gaps in the solutions guide (Helm, Kustomize generators,
CRD validation, cluster audit, Gateway API canary, context namespace)
so every question id in the bank (1-43, 101-122) has a section.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 17:11:05 -06:00
ea6878066f docs: updated weak-spots and history files 2026-09-08 20:04:11 -06:00
48342ed097 feat: added kustomize for task on question 3 of exam 2026-09-08 20:03:22 -06:00
23a9774a9f fix: install etcdctl/etcdutl on the control-plane node for the etcd tasks
The Q02/Q102 seeds tried to copy etcdctl out of the running etcd pod with
`kubectl exec -- cat`, which cannot work: registry.k8s.io/etcd is distroless
(no cat, no sh, no tar). The copy failed, stderr went to /dev/null and seeding
still printed a green tick, so the snapshot task had no etcdctl on the node.
Q102 was worse: it also ran `exec -- sh -c 'etcdctl ... snapshot save'` inside
that container, so its /opt/cka/backup.db was never created at all.

- etcd-tools.sh installs both binaries on the control-plane node, taking them
  from the etcd image already in the node's containerd (offline, exactly the
  server version), falling back to the upstream release tarball, then apt.
- setup.sh runs it at bootstrap; ensure_etcd_tools in the exam prelude installs
  them through CKA_NODE_ACCESS when a task is seeded, so ssh/vagrant clusters
  get them too, and both etcd setups now fail with a reason instead of hiding it.
- Q102 takes its snapshot with the node's etcdctl; Q02 no longer documents a
  kubectl cp fallback that cannot work on a distroless image.

Co-authored-by: Junie <junie@jetbrains.com>
2026-09-07 13:51:37 -06:00
9cfef63ea1 feat: added workspace/q03 for the whole sim 2026-09-07 12:05:21 -06:00
71f57de121 refactor: refer to to previous commit 2026-09-07 12:04:19 -06:00
9715b45481 docs: CKA_SOLUTIONS_EXPLAINED.md created to give a depper step-by-step guide and understanding of the exam 2026-09-07 12:03:05 -06:00
99f833db68 docs: add history-cka and weak-spots for mental notes and to keep up with progression 2026-09-07 09:30:53 -06:00
3a13b50cde docs: add CKA exam preparation guide and cheat sheet
Co-authored-by: Junie <junie@jetbrains.com>
2026-09-07 08:44:55 -06:00
40dca1dab1 fix: output single checkmark line when seeding scenarios
Co-authored-by: Junie <junie@jetbrains.com>
2026-09-06 22:06:55 -06:00
dece60fd8a feat: add CKA/CKAD/CKS exam simulator and question banks
Co-authored-by: Junie <junie@jetbrains.com>
2026-09-06 19:06:10 -06:00
936ba69b05 Initial commit 2026-09-07 00:45:37 +00:00