KubeRusted
Spinning up your cluster…

CKS exam prep — Certified Kubernetes Security Specialist

Free CKS (Certified Kubernetes Security Specialist) practice: the 6 official domains, exam-style questions, a timed practice exam and more.

Play the CKS map → · Official CKS exam page

Cluster Setup (15%)

Network policies, CIS benchmarks, Ingress TLS, node metadata, verified binaries

Cluster Hardening (15%)

Least-privilege RBAC, careful ServiceAccounts, restricted API access, upgrades

System Hardening (10%)

Small host OS, least-privilege IAM, less network exposure, AppArmor and seccomp

Minimize Microservice Vulnerabilities (20%)

Pod Security Standards, Secrets, isolation and sandboxes, Pod-to-Pod encryption

Supply Chain Security (20%)

Small base images, SBOMs, allowed registries, signatures, static analysis

Monitoring, Logging and Runtime Security (20%)

Behavioral detection, attack phases, immutable containers, audit logs

Practice questions

A namespace needs a default-deny policy for both directions. Which policyTypes?

Answer: [Ingress, Egress] with no ingress or egress rules. Empty rule lists with both types deny everything for the selected Pods.

kube-bench reports that the API server profiling endpoint is enabled. Which flag fixes it?

Answer: --profiling=false. Profiling exposes debugging data; the CIS benchmark recommends turning it off.

How does kube-bench typically run against a cluster’s nodes?

Answer: As a Job (or binary) on each node, reading local config files. It inspects files and process flags on the node itself.

An Ingress must serve HTTPS for shop.example.com. Which is required?

Answer: A kubernetes.io/tls Secret referenced in spec.tls with the host listed. The controller terminates TLS with that certificate.

Which command verifies a downloaded kubectl against its published checksum file?

Answer: echo "$(cat kubectl.sha256) kubectl" | sha256sum --check. The release publishes .sha256 files next to each binary.

Why restrict Pod access to the kubelet’s port 10250 from inside the cluster?

Answer: The kubelet API can run commands in any Pod on that node. Combine kubelet authn/authz with NetworkPolicies or host firewalls.

How do you check what a ServiceAccount can do?

Answer: kubectl auth can-i --list --as=system:serviceaccount:<ns>:<name>. ServiceAccounts are users named system:serviceaccount:<namespace>:<name>.

Which ClusterRole should never be bound to application ServiceAccounts?

Answer: cluster-admin. cluster-admin grants every verb on every resource.

Why is the RBAC verb "*" on resource "*" dangerous even in a namespace?

Answer: It includes creating Pods, reading Secrets and modifying RBAC in that namespace. Grant explicit verbs on explicit resources.

Which RBAC permission lets a user run commands in containers?

Answer: create on pods/exec. Subresources like pods/exec, pods/attach and pods/portforward need explicit grants.

How do you stop the default ServiceAccount’s token from being mounted into Pods?

Answer: Set automountServiceAccountToken: false on the ServiceAccount (or each Pod). The default SA is recreated if deleted.

Which apiserver flag restricts which admission plugins run beyond the defaults?

Answer: --enable-admission-plugins. NodeRestriction is a common addition.

Upgrading control-plane nodes from 1.33 to 1.35 directly with kubeadm is…

Answer: Not supported — upgrade one minor version at a time. kubeadm supports skipping no minor versions: go 1.33 → 1.34 → 1.35, upgrading kubeadm first each time.

Which command shows listening TCP ports and the owning processes on a node?

Answer: ss -tlnp. Close or firewall anything the node does not need.

How do you list AppArmor profiles loaded on a node?

Answer: aa-status (or apparmor_status). Profiles in enforce or complain mode are listed.

Where does the kubelet look for Localhost seccomp profiles by default?

Answer: /var/lib/kubelet/seccomp. localhostProfile is a path relative to that directory.

Which is a good way to reduce a node’s attack surface?

Answer: Remove unused packages and services; Restrict SSH and use least-privilege accounts. Minimal host OSes ship only what is needed to run containers.

A namespace is labelled pod-security.kubernetes.io/enforce=restricted. A Pod without a seccompProfile is created. Result?

Answer: Rejected. Restricted requires seccompProfile RuntimeDefault or Localhost.

Which Pod Security level blocks privileged Pods and hostPath but still allows running as root?

Answer: baseline. baseline blocks known escalations; restricted also requires non-root.

Which EncryptionConfiguration provider means "store as plaintext"?

Answer: identity. The first provider in the list is used for writes; identity last allows reading old plaintext.

In an EncryptionConfiguration, which provider encrypts new writes?

Answer: The first one in the providers list. Order matters: put the real provider first, identity after it during migration.

Which external approach avoids storing secret values in etcd at all?

Answer: A CSI secrets store driver or external secrets operator backed by a vault. Values are fetched from the external store at runtime.

Which RuntimeClass field names the runtime handler configured in containerd?

Answer: handler. handler: runsc maps to the gVisor runtime in the containerd config.

Which Istio resource makes mTLS strictly required in a namespace?

Answer: PeerAuthentication with mtls.mode: STRICT. STRICT rejects plaintext traffic to the selected workloads.

How does Cilium encrypt Pod traffic between nodes transparently?

Answer: WireGuard or IPsec transparent encryption. Enabled in Cilium’s configuration, no application changes.

Why separate tenants onto different nodes with taints and node affinity?

Answer: So a container escape on one tenant’s node cannot reach another tenant’s workloads. Node isolation strengthens multi-tenancy beyond namespaces.

Which Trivy command fails a CI job when HIGH or CRITICAL vulnerabilities are found?

Answer: trivy image --severity HIGH,CRITICAL --exit-code 1 <image>. --exit-code makes the scan return non-zero when findings match.

Which formats are common for SBOMs?

Answer: SPDX; CycloneDX. Both are widely supported by scanners and generators such as Syft and Trivy.

What does `cosign verify --key cosign.pub <image>` check?

Answer: That the image has a valid signature made with the matching private key. Signatures prove origin and integrity, not safety.

Why use image digests in Pod specs for production?

Answer: The exact image that was scanned and signed is the one that runs. A tag can be repointed after verification.

Which admission plugin delegates image allow/deny decisions to an external webhook backend?

Answer: ImagePolicyWebhook. It is configured with an admission configuration file pointing at the backend.

What does the AlwaysPullImages admission plugin protect against?

Answer: Pods reusing a private image already cached on a node without having pull credentials. It forces imagePullPolicy: Always so registry credentials are checked every time.

Which practice in a Dockerfile reduces what ends up in the final image?

Answer: A multi-stage build that copies only the built artifact into a minimal base. Build tools stay in the builder stage.

kubesec scores a Pod manifest. Which setting lowers the score?

Answer: privileged: true. kubesec rewards hardening settings and penalizes dangerous ones.

What does KubeLinter check?

Answer: Kubernetes YAML and Helm charts for misconfigurations and bad practices. It runs statically, e.g. in CI, before anything is deployed.

Which policy restricts Pods to images from registry.corp.example only, using Kyverno?

Answer: A validate rule with an image pattern registry.corp.example/*. Admission policies can match on image references.

Where do Falco rules set the alert text that names the Pod and container?

Answer: The rule’s output field. condition decides when to fire; output formats the alert with fields like %container.name.

Which Falco rule priority is higher: WARNING or CRITICAL?

Answer: CRITICAL. Priorities follow syslog severities: EMERGENCY … DEBUG.

An audit policy has a first rule level: None for get on pods, and a later rule level: Metadata for all. What is logged for a pod get?

Answer: Nothing. Audit rules are evaluated in order; the first match wins.

Which kube-apiserver flags are needed to write audit logs to a file?

Answer: --audit-policy-file; --audit-log-path. Add --audit-log-maxage/maxbackup/maxsize to rotate them; mount the paths into the static Pod.

How do you find which containers in a namespace can write to their root filesystem?

Answer: Check securityContext.readOnlyRootFilesystem for each container. Containers without readOnlyRootFilesystem: true are mutable.

A container must be immutable but needs to write temporary files. What do you do?

Answer: readOnlyRootFilesystem: true plus an emptyDir mounted at /tmp. Only the specific writable paths are allowed.

In the attack lifecycle, what comes right after initial access?

Answer: Execution. MITRE ATT&CK orders tactics from reconnaissance and initial access to impact.

A suspicious binary appeared in a running container. What should incident response do first?

Answer: Isolate the Pod (e.g. NetworkPolicy) and preserve evidence before deleting it. Contain first, then investigate; deleting destroys evidence.

Which signal reveals a kubectl exec into a production Pod after the fact?

Answer: An audit log entry for create on pods/exec. Audit logs record the user, Pod and time.

kube-bench reports that the kubelet allows anonymous requests. What do you change?

Answer: Set authentication.anonymous.enabled: false in the kubelet config and restart kubelet. kube-bench maps each failing CIS check to its remediation; the kubelet reads authentication settings from its config file.

Pods must not reach the cloud metadata service at 169.254.169.254. What do you create?

Answer: An egress NetworkPolicy allowing 0.0.0.0/0 except 169.254.169.254/32. ipBlock with except carves the metadata IP out of allowed egress. RBAC only governs the Kubernetes API, not network traffic.

How do you confirm a downloaded kubelet binary is the official one?

Answer: Compare its sha256sum (or sha512sum) with the checksum published for that release. A version string is trivial to fake; a checksum (or signature) from the release proves the bits are unchanged.

Which kube-apiserver settings close the most obvious doors?

Answer: --anonymous-auth=false; --authorization-mode=Node,RBAC. Disable anonymous access and authorize through Node + RBAC. AlwaysAllow and AlwaysAdmit disable the checks entirely.

A Pod never talks to the Kubernetes API. What is the hardening step for its token?

Answer: Set automountServiceAccountToken: false (on the Pod or its ServiceAccount). A token that is not mounted cannot be stolen from the Pod. Deleting the default ServiceAccount just gets it recreated.

Apply the container runtime’s default syscall filter to a Pod. Which field?

Answer: securityContext.seccompProfile.type: RuntimeDefault. RuntimeDefault is the runtime’s curated seccomp profile; Unconfined turns filtering off.

You wrote an AppArmor profile "k8s-deny-write". What else is needed before Pods can use it?

Answer: Load it on every node that may run the Pod (apparmor_parser) and reference it as a Localhost profile. AppArmor profiles live in the node kernel. Kubernetes only references them; a Pod with an unloaded profile fails to start.

Make every new Pod in namespace "payments" meet the restricted Pod Security Standard. How?

Answer: kubectl label ns payments pod-security.kubernetes.io/enforce=restricted. Pod Security Admission reads namespace labels. PodSecurityPolicy was removed in v1.25.

After enabling an EncryptionConfiguration, existing Secrets are still plaintext in etcd. Why, and what fixes it?

Answer: Only writes get encrypted — rewrite them: kubectl get secrets -A -o json | kubectl replace -f -. The API server encrypts on write, so existing objects stay as they were until they are written again.

Untrusted workloads should run under gVisor. Which object connects a Pod to that runtime?

Answer: A RuntimeClass with handler runsc, referenced by spec.runtimeClassName. RuntimeClass maps a name to a CRI handler configured on the node.

Which practices shrink an image’s attack surface?

Answer: A multi-stage build that copies only the binary into a distroless image; Running as a non-root USER. Fewer packages means fewer CVEs and fewer tools for an attacker; non-root limits what a compromise can do.

Only images from registry.corp.example and signed by your key may run. Where is this enforced?

Answer: At admission: an ImagePolicyWebhook or a policy engine (Kyverno/Gatekeeper) verifying registry and signature. Admission control sees every Pod before it is stored, so it can reject untrusted images.

Which tool alerts when someone opens a shell inside a running container?

Answer: Falco. Falco watches syscalls at runtime. kube-bench checks configuration, Trivy and kubesec scan artifacts before deploy.

You must record the full request and response of every change to Secrets. Which audit level?

Answer: RequestResponse for resources: secrets. Metadata logs only who/what/when; RequestResponse includes the bodies. Mind the log’s sensitivity.

Which setting stops an attacker from dropping new binaries into a container’s filesystem?

Answer: readOnlyRootFilesystem: true. A read-only root filesystem keeps the container immutable; provide emptyDir mounts only where writes are needed.