Overview
Cluster Setup is about the first security controls an administrator puts in place. You write NetworkPolicies that deny traffic by default and then allow only what a namespace needs, run kube-bench to compare the API server, etcd, kubelet and controller manager against the CIS Kubernetes Benchmark, and fix failed checks in static Pod manifests or the kubelet configuration file. You terminate TLS at an Ingress using a kubernetes.io/tls Secret, block Pods from reaching the cloud metadata address 169.254.169.254, lock down the kubelet API, and compare kubeadm, kubelet and kubectl binaries against the sha512 files published on dl.k8s.io.
Every competency is tested as a live task on a host you reach over ssh. The CKS assumes you already hold the CKA, so the exam does not explain where manifests live or how to restart the kubelet. A broken edit to kube-apiserver.yaml can take down the API for the rest of the task.
How it's tested
Setup tasks give a target state and a host. You might be told to make kube-bench report PASS for three named checks, to create a policy that blocks egress to the metadata service in one namespace, or to verify which of several binaries has been tampered with. Grading checks files and objects, not your explanation.
-
Benchmark remediation
kube-bench output lists failed checks with remediation text; you edit kube-apiserver.yaml, etcd.yaml or /var/lib/kubelet/config.yaml, wait for the restart and rerun the check.
-
Policy from a traffic description
A sentence describes allowed and denied flows between namespaces, Pods and CIDRs, and you translate it into podSelector, namespaceSelector, ipBlock and port rules.
-
Integrity check
Several binaries or a release version are named, and you compute sha512sum values and compare them with the official checksum files to find the mismatch.
A task says Pods in namespace apps must reach anything except 169.254.169.254. A policy with an egress rule allowing ipBlock cidr 0.0.0.0/0 with except 169.254.169.254/32 meets that, because once a Pod is selected for egress, only listed destinations are allowed. Adding a second policy that allows all egress would undo the block, since NetworkPolicies combine as a union of allowances.
Competencies 5
Official competencies from the CNCF / The Linux Foundation outline, in outline order.
1.1 Use Network security policies to restrict cluster level accessDefault-deny and allow-list NetworkPolicies for Pod traffic.
- What it means
- NetworkPolicy objects select Pods by label and define which ingress and egress connections they accept. A Pod that no policy selects accepts all traffic. Once a policy selects it for a direction, only the flows some policy allows are permitted.
- What to understand
- An empty podSelector selects every Pod in the namespace, so a policy with podSelector {} and policyTypes Ingress and Egress but no rules is a default deny. Rules within a from or to list are ORed; a namespaceSelector and podSelector inside one list item are ANDed. Egress deny also blocks DNS, so allow UDP and TCP port 53 to kube-dns when names must resolve. Enforcement depends on the CNI plugin, such as Calico or Cilium.
- How it shows up
- Expect to write a default-deny policy for a namespace, then a narrow allow rule between two labelled tiers.
- Common confusion
- Splitting namespaceSelector and podSelector into two list items, which allows either match instead of both.
1.2 Use CIS benchmark to review the security configuration of Kubernetes components (etcd, kubelet, kubedns, kubeapi)Running kube-bench and fixing the failed checks it reports.
- What it means
- The CIS Kubernetes Benchmark is a published checklist of secure settings for control plane and worker components. kube-bench, from Aqua Security, runs those checks against a node and prints PASS, FAIL or WARN with remediation advice.
- What to understand
- Run kube-bench run --targets master or node on the relevant host, then apply the remediation text. Typical fixes are --profiling=false on the scheduler and controller manager, --authorization-mode not containing AlwaysAllow, kubelet anonymous authentication disabled, and etcd --client-cert-auth=true. Control plane changes go in /etc/kubernetes/manifests and apply automatically; kubelet changes go in /var/lib/kubelet/config.yaml and need systemctl restart kubelet.
- How it shows up
- A task lists specific check numbers to fix and may ask you to leave other findings alone.
- Common confusion
- Editing the kubelet systemd drop-in when the setting lives in the KubeletConfiguration file, or forgetting to restart the kubelet.
1.3 Properly set up Ingress with TLSTerminating HTTPS at an Ingress with a TLS Secret.
- What it means
- An Ingress can serve HTTPS when its spec.tls section names one or more hosts and a Secret of type kubernetes.io/tls holding the certificate and private key. The Ingress controller presents that certificate to clients.
- What to understand
- Create the Secret with kubectl create secret tls name --cert=file --key=file in the same namespace as the Ingress, because cross-namespace references are not supported. The hosts under tls should match the rule hosts. Set ingressClassName so the right controller claims the object. Controllers can redirect HTTP to HTTPS; ingress-nginx does this by default once TLS is configured. Test with curl -kv --resolve host:443:IP https://host.
- How it shows up
- You may be handed a certificate and key and asked to secure an existing Ingress for one hostname.
- Common confusion
- Putting the Secret in the controller's namespace instead of the Ingress namespace.
1.4 Protect node metadata and endpointsBlocking metadata access and securing kubelet ports.
- What it means
- Cloud nodes expose an instance metadata service at 169.254.169.254 that can return credentials, and the kubelet serves an API on port 10250. Both are targets for a compromised Pod. Protecting them means restricting network paths and requiring authentication.
- What to understand
- Use egress NetworkPolicies with ipBlock except entries to keep Pods away from the metadata address, unless a labelled workload truly needs it. On the kubelet, set authentication.anonymous.enabled false, authorization.mode Webhook and readOnlyPort 0 in the KubeletConfiguration so unauthenticated callers cannot list Pods or exec into containers. Host firewalls should keep 10250, 2379 and 2380 off public networks.
- How it shows up
- A task may ask for a policy allowing all egress except metadata for every Pod in a namespace.
- Common confusion
- Assuming the NodeRestriction admission plugin protects the kubelet port; it limits what kubelets may change through the API.
1.5 Verify platform binaries before deployingComparing Kubernetes binaries with official checksums.
- What it means
- Before installing or trusting kubeadm, kubelet, kubectl or server binaries, you confirm they match what the Kubernetes release team published. A mismatch means the file was corrupted or tampered with.
- What to understand
- Each binary on dl.k8s.io has a matching .sha256 or .sha512 file. Compute the local hash with sha512sum, then compare, or pipe the published value into sha512sum --check. Release tarballs are also listed with hashes in the CHANGELOG. For binaries inside a container image, copy them out and hash the copy. Confirm the version first with kubelet --version so you compare against the correct release.
- How it shows up
- A task supplies several binaries and asks you to delete the ones whose hashes do not match the release.
- Common confusion
- Comparing a sha256 output against a sha512 published value, which can never match.
High-yield concepts
The terms, rules and formulas this domain turns into questions most often.
-
Default-deny NetworkPolicy
A policy that selects all Pods in a namespace and lists no allow rules for the chosen directions.
- Remember
- podSelector {} plus policyTypes [Ingress, Egress] with empty rule lists blocks both directions.
- Tested as
- Most network tasks start from a default deny and then add one narrow allowance.
- Trap
- Omitting policyTypes Egress, so only inbound traffic is denied.
-
Union semantics of policies
Multiple policies selecting a Pod combine, and any one of them can allow a flow.
- Remember
- There is no deny rule; the only way to block is to be selected and not allowed.
- Tested as
- Explains why an existing permissive policy can defeat the one you write.
- Trap
- Expecting a later or more specific policy to override an earlier one.
-
ipBlock except
An ipBlock rule allows a CIDR while carving out ranges listed under except.
- Remember
- 0.0.0.0/0 with except 169.254.169.254/32 allows the internet but not metadata.
- Tested as
- The standard pattern for metadata protection tasks.
- Trap
- Using ipBlock to match Pod IPs, which change and are better selected by labels.
-
kube-bench
An open source tool that runs CIS Kubernetes Benchmark checks on a node.
- Remember
- Targets include master, node and etcd; each finding prints a remediation hint.
- Tested as
- Benchmark tasks name check IDs from its output.
- Trap
- Fixing every warning instead of the checks the task names.
-
Static Pod manifests
YAML files in /etc/kubernetes/manifests that the kubelet runs as control plane Pods.
- Remember
- Saving an edit restarts the component; a syntax error stops it.
- Tested as
- API server and etcd hardening is done by editing these files.
- Trap
- Running kubectl edit on the mirror Pod, which does not change the manifest.
-
KubeletConfiguration
The file, usually /var/lib/kubelet/config.yaml, that sets kubelet authentication, authorization and ports.
- Remember
- anonymous.enabled false, authorization.mode Webhook, readOnlyPort 0, then restart kubelet.
- Tested as
- Kubelet benchmark fixes and endpoint protection both land here.
- Trap
- Adding a flag in the systemd drop-in that conflicts with the file.
-
kubernetes.io/tls Secret
A Secret holding tls.crt and tls.key, referenced by an Ingress tls block.
- Remember
- It must live in the same namespace as the Ingress.
- Tested as
- Every Ingress TLS task needs one.
- Trap
- Creating a generic Secret with different key names.
-
Release checksums
Hash files published next to every Kubernetes binary on dl.k8s.io.
- Remember
- Match the algorithm: sha512sum against .sha512, sha256sum against .sha256.
- Tested as
- Binary verification tasks are pure hash comparisons.
- Trap
- Trusting a binary because its --version output looks right.
Side by side
Concepts candidates mix up, compared on the point that decides the answer.
NetworkPolicy selectors
| Concept | Meaning | Key difference | Common trap |
|---|---|---|---|
| podSelector | Matches Pods by label in the policy's namespace | Never reaches into other namespaces on its own | Assuming it matches same-labelled Pods everywhere |
| namespaceSelector | Matches all Pods in namespaces with given labels | Selects namespaces, not individual Pods | Forgetting namespaces carry kubernetes.io/metadata.name automatically |
| namespaceSelector + podSelector in one item | Matches labelled Pods inside labelled namespaces | Both conditions must be true | Adding a dash before podSelector, which turns AND into OR |
| ipBlock | Matches IP ranges, with optional except ranges | Intended for traffic outside the cluster | Using it for Pod-to-Pod rules |
Where a hardening setting lives
| Concept | Meaning | Key difference | Common trap |
|---|---|---|---|
| kube-apiserver flags | Arguments in /etc/kubernetes/manifests/kube-apiserver.yaml | Applied when the kubelet recreates the static Pod | Checking kubectl get pods too early and seeing the old Pod |
| Kubelet settings | Fields in /var/lib/kubelet/config.yaml | Need systemctl restart kubelet | Editing a different node from the one the task names |
| etcd settings | Arguments in /etc/kubernetes/manifests/etcd.yaml | Wrong certificate flags break the API server too | Changing ports without updating the API server's --etcd-servers |
Exam traps
Each trap is an answer that looks right. Learn the clue that should change your mind.
-
Policy that allows too much
- What candidates pick
- Two separate list items for namespaceSelector and podSelector.
- Why it looks right
- The YAML looks tidy and each line reads like part of the requirement.
- Why it's wrong
- Separate list items are ORed, so every Pod in the namespace and every matching Pod anywhere gets access.
Clue to watch for Wording such as 'only Pods labelled X in namespace Y'.
-
Fixing the wrong file
- What candidates pick
- Adding a kubelet flag to the systemd unit file.
- Why it looks right
- Older tutorials show kubelet flags in the unit file.
- Why it's wrong
- kubeadm clusters read most kubelet security settings from the KubeletConfiguration, and conflicting flags cause confusion or failure.
Clue to watch for A benchmark remediation that names a config file field such as readOnlyPort.
-
Metadata still reachable
- What candidates pick
- Writing an ingress policy to protect metadata.
- Why it looks right
- Ingress feels like the protective direction.
- Why it's wrong
- The metadata service is reached by outbound connections from the Pod, so egress rules are needed.
Clue to watch for The words 'Pods must not access' plus an IP address.
-
Losing the API server
- What candidates pick
- Editing kube-apiserver.yaml directly with no backup.
- Why it looks right
- It is the fastest way to apply the flag.
- Why it's wrong
- A typo leaves no running API server, and without a copy you must find the error by reading kubelet logs.
Clue to watch for Any task that changes control plane flags; copy the manifest outside the manifests directory first.
-
Benchmark scope creep
- What candidates pick
- Remediating every FAIL that kube-bench reports.
- Why it looks right
- More fixes look more secure.
- Why it's wrong
- Unrequested changes cost time and can break components the grader checks in later tasks.
Clue to watch for A task that lists exact check numbers.
Answer framework
Apply this order to any setup task so baseline controls land correctly without breaking the control plane.
- Connect to the named host, then back up any manifest or kubelet config file you will touch to a directory outside /etc/kubernetes/manifests.
- Translate the requirement into exact objects or settings: selectors, ports and CIDRs for policies, or check IDs and fields for benchmark fixes.
- Apply the change with the smallest edit possible, keeping namespaces, Secret names and hostnames exactly as the task spells them.
- Wait for static Pods or the kubelet to restart and confirm with crictl ps, kubectl get pods -n kube-system or systemctl status kubelet.
- Prove the outcome by rerunning the kube-bench check, curling the Ingress, testing traffic from a temporary Pod or rerunning sha512sum.
Practice question
Want more like this? The CKS practice test has questions for every domain.
Checklist
0 of 10
Tick each one you can do without notes. Your ticks stay in this browser.
Study strategy
Begin with NetworkPolicies on a lab cluster that runs an enforcing CNI such as Calico or Cilium. Build a default deny, then add allowances one at a time and test each with a short-lived busybox Pod using wget or nc. This trains the selector logic, which is where most policy points are lost.
Next, install kube-bench on a kubeadm control plane and a worker. Fix five or six common findings, including profiling, anonymous auth and the kubelet read-only port, and always back up the file before editing. Practise reading kubelet logs with journalctl -u kubelet so a broken manifest becomes a two-minute recovery rather than a lost task.
Finish with the quick competencies: create a TLS Secret and Ingress, and verify binaries with sha512sum against files downloaded from dl.k8s.io. Then time yourself completing a setup task in under seven minutes, including verification. Repeat any task type that runs over, because setup work should bank time for the heavier domains later in the exam.
FAQ
How much of the CKS exam is Cluster Setup?
Cluster Setup carries 15% of the score according to the CNCF curriculum and the Linux Foundation exam page. Expect two or three tasks drawn from its five competencies.
Will the exam cluster enforce NetworkPolicies?
Exam clusters are built so that policy tasks can be graded, which means an enforcing CNI is installed. In your own lab, check that the CNI enforces policies, because some simple plugins ignore them.
Is kube-bench installed in the exam environment?
Benchmark tasks provide a way to run the checks, typically a kube-bench binary or job on the host. Know the run syntax and how to read the output instead of relying on a specific install method.
Do I need to generate certificates for Ingress TLS?
Usually a certificate and key are provided. Knowing an openssl req -x509 one-liner is still useful in case a task asks you to create a self-signed pair.
Which documentation can I open for this domain?
The kubernetes.io documentation covers NetworkPolicy, Ingress TLS and kubelet configuration. The Linux Foundation also allows the ingress-nginx configuration guide and any Quick Reference links in a task.
How do I know a static Pod restarted after my edit?
Watch crictl ps on the node for a new container ID, or check the Pod age in kube-system. If nothing appears after a minute, read journalctl -u kubelet for the parse error.
Other DevOps & Containers certifications
Where the same subject shows up in other exams. Cards marked "Same subject" open the matching domain.
Test your Domain 1 knowledge
Try timed setup tasks covering NetworkPolicies, CIS benchmark fixes, Ingress TLS and binary verification before moving to hardening.