Files
kodekloud-engineer/kubernetes/cks/exam-by-claude
Jan Novak 6f28c97319 cks: swap kind CNI to Cilium, fix broken ingress-nginx setup
kindnet's NetworkPolicy enforcement isn't guaranteed, undermining the
Task 1 lab; Cilium (with kube-proxy replacement) enforces it
deterministically. Also fixes ingress-nginx, which was silently broken:
missing ingress-ready node label left the controller Pending forever,
and hostPorts 80/443 were never mapped in kind-config.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 23:23:04 +02:00
..
2026-08-04 23:18:45 +02:00

CKS Mock Exam — k8s v1.35

Timed practice that mirrors the current CKS (17 tasks, 2h, six domains). Runs on kind (k8s v1.35.5) with the host-side / kernel bits on your Ubuntu VM.

Prereqs (Ubuntu VM)

  • docker, kind >= v0.32.0, kubectl v1.35, helm (used to install Cilium — load-bearing, not optional)
  • host tools installed latest: kube-bench, trivy, kubesec, falco (v0.44.x), optional cosign, optional cilium-cli for cilium status/cilium connectivity test
  • host must have AppArmor enabled (default on Ubuntu) for Task 7

Quickstart

chmod +x bootstrap.sh seed.sh
./bootstrap.sh     # creates 'cks' cluster (1 cp + 2 workers) + ingress-nginx
./seed.sh          # plants the target/vulnerable objects
# set a 2h timer, open exam.md, go.

Files

  • kind-config.yaml — cluster topology, v1.35.5 pinned digest, exam-files mount
  • bootstrap.sh — cluster + ingress controller + tooling checklist
  • seed.sh — objects for the kubectl-only tasks
  • exam.md — the 17 tasks (per-task setup + statement, no answers)
  • answers/solutions.md — worked solutions (don't peek until you've timed a full run)

Domain coverage (weights)

Cluster Setup 15 · Cluster Hardening 15 · System Hardening 10 · Microservice Vuln 20 · Supply Chain 20 · Monitoring/Logging/Runtime 20.

Reset

kind delete cluster --name cks && ./bootstrap.sh && ./seed.sh

Notes / kind caveats

  • Version: exam is on v1.35 per the Linux Foundation page. k8s 1.36 shipped ~May 2026; the exam env aligns "within 48 weeks" of a release, so it may have rolled to 1.36 by your date — verify on the LF exam page. Nothing in this set changes between 1.35/1.36. To bump: swap the digest in kind-config.yaml for a kindest/node:v1.36.x one.
  • CNI is Cilium, not kindnet — disableDefaultCNI: true in kind-config.yaml, installed by bootstrap.sh via Helm. It runs with the kube-proxy replacement (kubeProxyMode: none), so there is no kube-proxy DaemonSet in kube-system; kube-bench's kube-proxy CIS checks are N/A (Task 3's four target checks — kubelet ×3, apiserver ×1 — are unaffected). This also means Task 1's NetworkPolicy is genuinely enforced, not a maybe.
  • Between kind create cluster and the Cilium install finishing, nodes sit NotReady and CoreDNS is Pending — expected, not a failure; bootstrap.sh waits it out.
  • Ingress reaches the cluster on host ports 80/443 (mapped in kind-config.yaml) via the control-plane node, which is labelled ingress-ready=true so the ingress-nginx kind manifest schedules onto it.
  • AppArmor needs a real AppArmor host; works on Ubuntu, not on Docker Desktop/macOS.
  • gVisor (Task 11) pod stays Pending in kind (no runsc in kind's containerd) — the config is the graded artifact.
  • ImagePolicyWebhook / audit / encryption edit the live apiserver: always cp the manifest first so you can revert fast.