Hedronite · Cert-Prep Synthesis Lesson · CNCF / CKS · Track K8s Day 10 · Sat 2026-08-01 · Bundle Trio #2

CKS — Cluster Setup — the perimeter domain

The smallest CKS domain is the one that decides whether the cluster was ever yours to begin with.

Lesson Class: Cert-Prep (CKS Cluster Setup, 10%)
Track / Day: K8s (Deep K8s, CKA + CKS) — round-robin day 10, visit 4; CKS-emphasis (k8s_day_counter=3)
Cloud Referent: EKS — IMDSv2 hop-limit + NetworkPolicy egress ipBlock except 169.254.169.254
Word Count: ~2,350
Grounding: Poulton — Ch 16 Real-world security (pp. 234-235) · K8sUR 3rd ed — Ch 7 Serving TLS (p. 123) · Rice, Container Security — Ch 10 (p. 148)
Paired Ops: Kubernetes NetworkPolicy on EKS — Default-Deny and the Allow-List Discipline
Paired Dev: A Kubernetes Operator in Python with kopf — the Policy-Baseline Operator
Discipline: ROD v3 · aether-accent meta-card · interactive q-card drill · bundle shape (Maghrib fills quiz + lab-ref)
CKS Domain: Cluster Setup 10% Network Policy · kube-bench · Ingress TLS · Metadata · Binaries Performance-based · 2 hrs CKA-before-CKS sit order
Ten percent sounds small until you notice every Cluster Setup task is fast points if the moves are cold.

§ IFrame — Where Cluster Setup Sits in the Blueprint

The CKS blueprint weighs six domains: Cluster Setup 10%, Cluster Hardening 15%, System Hardening 15%, Minimize Microservice Vulnerabilities 20%, Supply Chain Security 20%, Monitoring/Logging/Runtime 20%. The 07-26 lesson worked the fourth (Pod Security Standards). Today is the first: the perimeter domain. Its bullets read as a checklist of the ground the cluster stands on: restrict cluster-level access with network policies; run CIS benchmark checks; set up ingress with TLS; protect node metadata and endpoints; verify platform binaries before deploying them.

Today's Ops lesson carries the first bullet at full depth: selector grammar, the isolation switch, the default-deny pair, the VPC CNI agent on EKS. This lesson takes the remaining four bullets, then drills the whole domain with six questions. Where the wall's grammar is needed, reach across the trio.

§ IINetwork Policies as the Perimeter — The Exam Moves

The exam wants speed and two verifications. Speed: write the default-deny pair for a named namespace, from memory, under a minute; the muscle is podSelector: {} plus both policyTypes and no rules. Verification one: prove the CNI enforces, because a policy on a non-enforcing plugin is a stored wish (Rice, ch. 10). Verification two: prove the wall with a probe pod, kubectl run probe --rm -it --image=busybox, then a wget with a two-second timeout against the target, expecting timeout after and success before.

One grammar point earns its repetition: within a from list, separate items OR; selectors within one item AND. The scrape rule admitting monitoring traffic is one item, one selector. Split a two-selector rule into two items and every pod in monitoring plus every matching pod anywhere is admitted. One dash, opposite perimeter.

§ IIIkube-bench and the CIS Benchmark — Auditing the Components

The CIS Kubernetes Benchmark is the line-by-line hardening standard for the control plane and nodes. kube-bench reads a cluster against it. Poulton files this under auditing and security monitoring: the benchmark run is the audit trail that says the ground was checked, and rerunning it is how you notice the ground shifted (The Kubernetes Book, ch. 16, pp. 234-235).

kube-bench run --targets master
kube-bench run --targets node

Output arrives as numbered checks in four states, PASS/FAIL/WARN/INFO, each FAIL carrying a remediation block naming the exact file and flag. The exam shape is always run-the-tool, read-one-FAIL, apply-remediation, re-run-to-PASS. Three FAILs worth having cold:

--anonymous-auth=false on the kubelet: anonymous access to the kubelet API is anonymous access to every container on the node. Edit /var/lib/kubelet/config.yaml (authentication.anonymous.enabled: false), restart. Then authorization.mode: Webhook, so the kubelet asks the API server's RBAC before honoring requests. And --read-only-port=0, because port 10255 answers pod specs to anyone who reaches the node.

On the control plane the classics are --anonymous-auth=false on the API server and etcd's TLS flags; those manifests live in /etc/kubernetes/manifests/ as static pods per the 07-23 architecture lesson. On EKS the control plane is AWS's side of the shared-responsibility line, so --targets master is not your audit; the node checks remain fully yours.

§ IVIngress TLS — The Front Door Speaks Encrypted or Not at All

The 07-29 lesson established that an Ingress without a controller routes nothing. The CKS bullet adds: an Ingress without TLS terminates nothing worth having. Two objects and one reference. First a Secret of type kubernetes.io/tls:

kubectl -n trading create secret tls trading-tls \
  --cert=trading.crt --key=trading.key

Then the Ingress names it:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: trading-ingress
  namespace: trading
spec:
  ingressClassName: nginx
  tls:
    - hosts: [trading.hedronite.io]
      secretName: trading-tls
  rules:
    - host: trading.hedronite.io
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: pricing-engine
                port:
                  number: 443

The rules that cost points: the Secret must live in the same namespace as the Ingress, because the TLS block carries a name, never a namespace; the hosts list must cover the rule's host or the controller serves its default certificate. K8sUR's Serving TLS section adds the operational truth that manual certificate Secrets rot, which is why cert-manager issues and renews them as a controller (K8sUR 3rd ed., ch. 7, p. 123).

§ VMetadata Protection and Binary Verification — The Two Quiet Bullets

The metadata endpoint. Every EC2 node behind EKS answers HTTP on 169.254.169.254, the instance metadata service, and what it serves includes the node's IAM role credentials. A pod on the flat network can curl that address and walk away holding the node's cloud identity. Two walls close it. First, IMDSv2 with session tokens and hop limit 1:

aws ec2 modify-instance-metadata-options --instance-id i-0abc123 \
  --http-tokens required --http-put-response-hop-limit 1

Second, the egress NetworkPolicy the Ops lesson armed, the legitimate in-cluster use of ipBlock:

egress:
  - to:
      - ipBlock:
          cidr: 0.0.0.0/0
          except: [169.254.169.254/32]

Layered under the deny floor, pods get whatever egress their allow rules grant, minus the one address that turns a pod compromise into a cloud-account compromise. GKE closes the same door under the name metadata concealment with Workload Identity as the successor.

Binary verification. Before a platform binary runs, its hash matches the release: sha512sum kubectl against the published checksum, same for kubelet and server binaries on self-managed nodes. Thirty seconds against a supply-chain class the 20% domain treats at length later.

§ VIDrill — Six Questions

Tap a card to reveal its resolution. Score cold first.

Q1 · The Pair That Isolates
A namespace has exactly one NetworkPolicy: podSelector: {}, policyTypes: [Ingress, Egress], no rule keys at all. What can its pods send and receive, and what single addition restores name resolution?
Resolution
Nothing in, nothing out: every pod selected, both directions, zero rules is total isolation — the default-deny pair in one object. DNS died with everything else, so add the kube-dns egress rule (kube-system namespaceSelector AND k8s-app: kube-dns podSelector, ports 53 UDP and TCP). Until then even permitted future flows fail at resolution before they fail at policy.
Q2 · One Dash, Two Perimeters
Rule A has one from item containing both namespaceSelector: {team: obs} and podSelector: {app: prom}. Rule B lists the same two selectors as two separate from items. State each rule's admitted set.
Resolution
Rule A admits only pods labeled app: prom in namespaces labeled team: obs: one item, selectors AND. Rule B admits every pod in any team: obs namespace, plus every app: prom pod in any namespace whatsoever: two items, OR. B is the accidental cluster-wide door the exam plants and production repeats.
Q3 · The kubelet FAIL
kube-bench reports FAIL: kubelet authorization mode is AlwaysAllow. Name the file, the exact change, the restart command, and the verification.
Resolution
File /var/lib/kubelet/config.yaml; set authorization.mode: Webhook (and confirm authentication.anonymous.enabled: false while in the file); systemctl restart kubelet; verify with kube-bench run --targets node flipping the check to PASS, or by curling the kubelet API unauthenticated and receiving 401/403.
Q4 · The Certificate That Never Serves
An Ingress in trading references secretName: trading-tls; the Secret sits in default. TLS clients get the controller's self-signed default cert. Why, and what is the fix?
Resolution
The tls.secretName reference is namespace-blind; the controller resolves it inside the Ingress's own namespace, finds nothing in trading, and falls back to its default certificate. Recreate the Secret in trading (or move it) and confirm the tls.hosts entry covers the rule's host exactly.
Q5 · The Metadata One-Liner
A pod runs curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ on an EKS node with IMDSv1 enabled and no egress policy. What does the attacker hold, and which two independent controls each would have stopped it?
Resolution
The attacker holds the node's IAM role credentials: temporary keys speaking with the node's full cloud permissions, typically enough to read images, write logs, and often far more. Control one: IMDSv2 with --http-tokens required and hop-limit 1, killing token retrieval from inside a pod netns. Control two: the egress ipBlock except-clause under a deny floor. Either alone stops the one-liner; CKS wants both installable.
Q6 · The Policy That Enforces Nothing
A team applies a perfect default-deny pair and the probe pod still connects to everything. The API server accepted the objects without complaint. Name the cause and the check.
Resolution
The CNI does not enforce NetworkPolicy: the API stores policy objects regardless of whether the plugin executes them (Rice's point, and why the Ops lesson checks enforcement before trusting YAML). On EKS with the VPC CNI, enableNetworkPolicy was never set true, so no eBPF agent translates policy into verdicts. Check the aws-node addon configuration (generally: identify the CNI and its policy support), enable, re-run the probe.

§ VIIClosing

Cluster Setup is the domain where the exam pays you for habits: the four-line deny pair, the kube-bench triple of run-fix-rerun, the two-object TLS wiring, the two walls in front of the metadata address, the checksum before the binary. Drill each until it is a hand movement rather than a decision.

Score yourself against the six questions cold, no scrollback. Anything answered slowly goes on tomorrow's whiteboard; the Maghrib quiz on this bundle will re-ask them in multiple-choice dress.

🫡 ⚖️ 📜
Leo.Syri — Praetor Consulate, Imperium Luminaura
Filed 2026-08-01 Fajr · Cert lesson · K8s deep-mastery track (day 10, visit 4; CKS-emphasis per k8s_day_counter=3)