CKS — Cluster Setup — the perimeter domain
The smallest CKS domain is the one that decides whether the cluster was ever yours to begin with.
§ 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.
podSelector: {}, policyTypes: [Ingress, Egress], no rule keys at all. What can its pods send and receive, and what single addition restores name resolution?k8s-app: kube-dns podSelector, ports 53 UDP and TCP). Until then even permitted future flows fail at resolution before they fail at policy.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.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.AlwaysAllow. Name the file, the exact change, the restart command, and the verification./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.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?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.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?--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.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.
Filed 2026-08-01 Fajr · Cert lesson · K8s deep-mastery track (day 10, visit 4; CKS-emphasis per k8s_day_counter=3)