CKS study plan
CKS · Give each week a clear focus.
8 weeks · About 7 hours per week
Minimize Microservice Vulnerabilities
Label a namespace with pod-security.kubernetes.io/enforce=restricted and confirm a privileged test pod is rejected at admission
Apply a hardened securityContext to a Deployment (runAsNonRoot, allowPrivilegeEscalation=false, readOnlyRootFilesystem, drop ALL capabilities, seccompProfile RuntimeDefault) and verify each field survives the running pod
Mount a Secret as a volume instead of an env var, then enable encryption at rest for Secrets by supplying an EncryptionConfiguration to the API server
Attach a Localhost seccomp profile to a pod and demonstrate that a blocked syscall fails while the container still serves traffic
Your checkpoint
A committed manifest bundle for a 'secure-app' namespace (PSA labels + hardened Deployment + seccomp profile + encrypted Secret) applied to a practice cluster, with kubectl get pod -o yaml output pasted alongside each manifest proving the fields took effect
Supply Chain Security
Scan a container image with trivy and fail a shell script when HIGH or CRITICAL CVEs are present
Rewrite a Dockerfile as a multi-stage build that runs as a non-root UID and pins the base image by digest
Sign an image with cosign and write a verification step that rejects an unsigned image before deployment
Install an admission policy (OPA Gatekeeper constraint or ValidatingAdmissionPolicy) that denies images tagged :latest or pulled from unapproved registries
Run static analysis over your Kubernetes manifests with kubesec or checkov and remediate every HIGH finding
Your checkpoint
A single build-and-gate script that builds, scans, signs, verifies and deploys an image, plus its console transcript showing one compliant image admitted and one known-bad image blocked
Monitoring, Logging and Runtime Security
Write an audit policy capturing RequestResponse for Secrets and Metadata for everything else, wire it into the API server, and extract a single event from the audit log
Deploy Falco and author one custom rule that fires when a shell is spawned inside a container
Trigger the rule by exec-ing into a pod, then capture the alert with timestamps
Investigate the simulated intrusion using pod process listing and crictl, then isolate the workload by applying a quarantine NetworkPolicy
Configure readOnlyRootFilesystem and a non-privileged container and confirm an in-container write to / fails
Your checkpoint
A one-page incident runbook backed by real artifacts: the Falco alert output, the matching audit-log line, and the quarantine NetworkPolicy that cut off the pod
Cluster Setup
Implement a default-deny ingress and egress NetworkPolicy in a namespace, then add an allow-list and prove allowed traffic works while blocked traffic times out
Run kube-bench against the control plane and worker nodes and remediate at least three findings
Create an Ingress with TLS termination and verify the certificate is served correctly
Restrict anonymous access to the kubelet read-only port and confirm the metrics endpoint no longer answers unauthenticated requests
Your checkpoint
A kube-bench before/after comparison showing three remediations closed, plus a curl-based connectivity test matrix proving the default-deny plus allow-list NetworkPolicy behaves as designed
Cluster Hardening
Author least-privilege Role and ClusterRole objects and prove them with kubectl auth can-i --as for both an allowed and a forbidden verb
Disable automountServiceAccountToken on workloads and bind a dedicated minimal ServiceAccount to each Deployment
Harden API server flags (anonymous-auth=false, authorization-mode=Node,RBAC, explicit audit log path) and verify the running config
Set a short serviceAccountToken expiration on a test token and confirm the stale token is rejected
Your checkpoint
An RBAC matrix document mapping each workload to its ServiceAccount and verbs, accompanied by an auth can-i transcript showing forbidden actions correctly denied
System Hardening
Patch the KubeletConfiguration to set anonymous-auth=false, readOnlyPort=0 and protectKernelDefaults=true, then verify via the kubelet configz endpoint
Confirm the NodeRestriction admission plugin and Node authorizer are active and that a node cannot read unrelated Secrets
Load an AppArmor profile onto a pod and demonstrate that a write the profile forbids returns permission denied
Reduce the node attack surface by disabling or firewalling an unused host service and recording the before/after port scan
Your checkpoint
A hardened node evidence pack: live kubelet configz output, an AppArmor denial captured from the pod, and a port-scan diff showing the removed listener
Minimize Microservice Vulnerabilities & Supply Chain Security & Monitoring, Logging and Runtime Security
Re-run the weeks 1 through 3 labs under a 25-minute timer each without opening notes
Combine a signed-image gate, a restricted-PSA namespace and a Falco rule into one end-to-end deploy-and-detect pipeline
Locate and close the three weakest objectives from your own lab log
Write one-page command cheat sheets for PSA, NetworkPolicy, RBAC and Falco
Your checkpoint
Three timed exam-style tasks completed within 25 minutes each with a pass/fail log, plus the four committed cheat sheets
Cluster Setup & Cluster Hardening & System Hardening & Minimize Microservice Vulnerabilities & Supply Chain Security & Monitoring, Logging and Runtime Security
Complete two full-length timed mock exams covering all six domains
Remediate every objective missed in either mock by rebuilding it hands-on in a fresh cluster
Re-verify the deliverable artifacts from weeks 1 through 6 still apply cleanly on a rebuilt cluster
Finalize a 15-minute pre-exam review sheet limited to imperative kubectl and openssl commands
Your checkpoint
Two mock exam score reports at or above 75 percent with a written remediation note for every missed objective
Milestones
Week 4: Score at least 70 percent on a 20-question self-written quiz covering domains 4, 5 and 6, and pass the NetworkPolicy connectivity matrix with zero unintended allows
Week 6: All six deliverable artifacts exist in the repo and can be re-applied to a freshly built cluster without editing; the default-deny NetworkPolicy, restrictive PSA label and Falco alert are all demonstrably live at the same time
Week 8: Two timed mock exams completed at or above 75 percent, with every missed objective rebuilt hands-on and re-verified