docs: add Kubernetes CKS study notes

This commit is contained in:
2026-08-04 23:18:45 +02:00
parent a6ee7a2b07
commit 91a1849009
57 changed files with 8313 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
# CKA Range Bring-Up — kind + Cilium (matches Mock Exam Pack v1)
> Produces cluster `drills` on Kubernetes **v1.35.0** (= exam version) with nodes named exactly as the drill/mock packs expect: `drills-control-plane`, `drills-worker`, `drills-worker2`.
> CNI: **Cilium 1.19.x** — real NetworkPolicy enforcement (kindnet has none; netpol drills would silently pass on it).
> Versions verified 2026-07-29. Re-check pins if you're reading this much later: kind releases page, cilium.io stable docs.
---
## 0. Host prerequisites
- Docker (or compatible), ≥ 8GB RAM free for the 3 nodes
- **cgroup v2 on the host** — mandatory: k8s 1.35 node images dropped cgroup v1. Check: `stat -fc %T /sys/fs/cgroup` → must print `cgroup2fs`. Any current distro qualifies.
- Tools: `kind` ≥ v0.31.0 (ships the v1.35.0 default image), `kubectl`, `helm`
```bash
kind version # v0.31.x
helm version # v3.x
```
## 1. Cluster config — `kind-drills.yaml`
```yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: drills # ⇒ node names drills-control-plane / drills-worker / drills-worker2
networking:
disableDefaultCNI: true # kindnet out, Cilium in
nodes:
- role: control-plane
image: kindest/node:v1.35.0 # pin explicitly = exam version, survives kind upgrades
- role: worker
image: kindest/node:v1.35.0
- role: worker
image: kindest/node:v1.35.0
```
Note: kube-proxy stays (default). Do NOT enable Cilium's kube-proxy replacement — the exam cluster runs kube-proxy, and iptables-visible Services are part of the troubleshooting surface you're training.
## 2. Bring-up — `range-up.sh`
```bash
#!/usr/bin/env bash
set -euo pipefail
CILIUM_VER=1.19.6
kind create cluster --config kind-drills.yaml
# nodes will sit NotReady until CNI lands — expected
# --- Cilium (per cilium.io kind guide) ---
docker pull quay.io/cilium/cilium:v${CILIUM_VER}
kind load docker-image quay.io/cilium/cilium:v${CILIUM_VER} --name drills # skip registry pulls on each node
helm repo add cilium https://helm.cilium.io/ 2>/dev/null; helm repo update
helm install cilium cilium/cilium --version ${CILIUM_VER} \
--namespace kube-system \
--set image.pullPolicy=IfNotPresent \
--set ipam.mode=kubernetes
kubectl -n kube-system rollout status ds/cilium --timeout=180s
kubectl wait --for=condition=Ready node --all --timeout=180s
# --- Gateway API CRDs (standard channel) ---
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml
# --- metrics-server (for HPA TARGETS + kubectl top) ---
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl -n kube-system patch deploy metrics-server --type=json \
-p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
# ^ mandatory on kind: kubelet serves self-signed certs; without this metrics-server never goes Ready
# --- helm repo used by drill K4 / mock Q8 ---
helm repo add bitnami https://charts.bitnami.com/bitnami 2>/dev/null; helm repo update
echo "RANGE UP"
```
## 3. Smoke test — run before ANY drill session
```bash
kubectl get nodes -o wide
# drills-control-plane / drills-worker / drills-worker2 — all Ready, VERSION v1.35.0
kubectl get pods -A | grep -v Running | grep -v Completed # empty
kubectl api-resources | grep -i httproute # gateway.networking.k8s.io present
kubectl top nodes # numbers (may need ~60s after install)
kubectl -n kube-system exec ds/cilium -- cilium status --brief # OK
# NetworkPolicy ENFORCEMENT check — the one that matters (kindnet would pass traffic anyway):
kubectl create ns smoke
kubectl -n smoke run a --image=nginx --labels=app=a --port=80
kubectl -n smoke run b --image=busybox -- sleep 600
kubectl -n smoke wait --for=condition=Ready pod --all --timeout=60s
kubectl -n smoke apply -f - <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: deny-all}
spec:
podSelector: {}
policyTypes: [Ingress]
EOF
AIP=$(kubectl -n smoke get pod a -o jsonpath='{.status.podIP}')
kubectl -n smoke exec b -- wget -qO- -T 2 $AIP && echo "FAIL: netpol NOT enforced" || echo "OK: netpol enforced"
kubectl delete ns smoke --wait=false
```
If that last line prints FAIL, the CNI install went sideways — do not run K1/Q3 until fixed (`kubectl -n kube-system logs ds/cilium | tail`).
## 4. Static pod path sanity (mock Q17 depends on it)
```bash
docker exec drills-worker grep staticPodPath /var/lib/kubelet/config.yaml
# expect: staticPodPath: /etc/kubernetes/manifests
```
## 5. Teardown / rebuild
```bash
kind delete cluster --name drills # full nuke, ~10s
# rebuild = run range-up.sh again, ~3 min total
```
Rebuild is cheap — prefer a fresh cluster over archaeologically cleaning a broken one between mock attempts. The mock pack's RESET script is for same-day reruns; a new day gets a new cluster.
## 6. Known deltas vs the real exam (accept, don't fight)
| Real exam | This range |
|---|---|
| `ssh nodeX` | `docker exec -it drills-<node> bash` |
| multiple kubectl contexts | one context; discipline = read each task's target ns/node |
| kubeadm package upgrades (apt) | not possible — node image is baked; upgrade tasks stay on KodeKloud/killer |
| several CNIs possible | Cilium everywhere (netpol semantics are standard, so drills transfer) |