CKS — Exam Tips & Strategies

9 minute read

The 3-Pass Time Management Strategy

Time management is even more critical in CKS than CKA. CKS tasks often involve multiple steps (create profile → load → apply → verify) and security-specific tools.

Pass 1 — Quick Wins (First 10–15 Minutes)

  • Scan all questions and identify easy tasks you can solve in under 2 minutes
  • Complete every quick win first: set SecurityContext fields, apply a Seccomp RuntimeDefault profile, switch Secrets to mounted volumes
  • Skip anything involving Falco rule writing, complex NetworkPolicies, or multi-step audit configurations
  • Target: Complete 3–5 fast questions

Pass 2 — Medium Tasks (Next 60–70 Minutes)

  • Return to medium-complexity questions: create AppArmor profiles, write basic Falco rules, configure Pod Security Admission on namespaces
  • Allocate 5–8 minutes per task — if stuck after 8 minutes, flag and move on
  • Use documentation for YAML structure references (NetworkPolicy spec, audit policy levels)
  • Target: Complete 7–10 medium questions

Pass 3 — Hard Tasks (Remaining Time)

  • Tackle remaining complex questions: multi-step Gatekeeper policies, custom Seccomp profiles, elaborate Falco rule chains, multi-namespace NetworkPolicy scenarios
  • Even partial answers earn partial credit — always write something
  • Use the last 5 minutes to review flagged questions and verify context switches
  • Target: Attempt all remaining questions, even partially

Time Budget Summary

Pass Time Task Type Expected Questions
Pass 1 10–15 min Quick wins 3–5
Pass 2 60–70 min Medium tasks 7–10
Pass 3 25–35 min Hard tasks + review Remaining
Total 120 min   15–20

Average time per question: ~6–8 minutes. Some questions take 2 minutes, others take 15. The 3-pass approach ensures you capture all easy points first.

vi/vim Editor Shortcuts

You’ll use vi extensively in CKS — editing YAML manifests, Falco rules, AppArmor profiles, and audit policies. These shortcuts save significant time:

Essential Shortcuts

Shortcut Action
i Enter insert mode (type text)
Esc Exit insert mode
:wq Save and quit
:q! Quit without saving
dd Delete current line
5dd Delete 5 lines
yy Copy (yank) current line
5yy Copy 5 lines
p Paste below current line
P Paste above current line
u Undo last change
Ctrl+r Redo
/search Search forward for “search”
n Next search result
N Previous search result
:%s/old/new/g Replace all “old” with “new”
G Go to end of file
gg Go to beginning of file
:set number Show line numbers
:set paste Enable paste mode (preserves indentation)
:set nopaste Disable paste mode

CKS-Specific vi Tips

Task vi Workflow
Edit Falco rules Open /etc/falco/falco_rules.local.yaml, use /rule: to search for rules
Edit AppArmor profiles Open /etc/apparmor.d/<profile>, add deny/allow lines
Edit audit policy Navigate to /etc/kubernetes/audit-policy.yaml, add rules at correct indentation
Edit API server manifest Open /etc/kubernetes/manifests/kube-apiserver.yaml, careful with indentation
Paste YAML from docs :set paste first, then Ctrl+Shift+V, then :set nopaste

Always use :set paste before pasting multi-line content. Without it, vim auto-indents each line, destroying YAML structure.

First-Thing Setup

Run this at the start of your exam to optimize your shell:

# Set kubectl alias and exports
alias k=kubectl
export do="--dry-run=client -o yaml"
export now="--force --grace-period=0"

# Set vim defaults
echo 'set tabstop=2 shiftwidth=2 expandtab number' >> ~/.vimrc

YAML Best Practices for Security Resources

CKS tasks involve writing YAML for security-specific resources. Follow these patterns:

SecurityContext Template

apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: nginx:1.27
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
          - ALL

NetworkPolicy Template (Default Deny All)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: target-namespace
spec:
  podSelector: {}   # Selects ALL pods in namespace
  policyTypes:
  - Ingress
  - Egress

Audit Policy Template

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
  resources:
  - group: ""
    resources: ["secrets"]
- level: Metadata
  resources:
  - group: ""
    resources: ["configmaps"]
- level: None
  resources:
  - group: ""
    resources: ["events"]

Pod Security Admission Labels

apiVersion: v1
kind: Namespace
metadata:
  name: secure-namespace
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

Common Exam Traps

These are mistakes that cost points in the CKS exam. Learn them before exam day:

Trap 1: Forgetting to Switch Context

Every question tells you which cluster to use. If you skip the kubectl config use-context command and work on the wrong cluster, you get zero points — even if your answer is technically correct.

Prevention: Make it a physical habit — read the context line, type the switch command, verify.

# ALWAYS start with this
kubectl config use-context <context-name>
# Verify
kubectl config current-context

Trap 2: Forgetting the Namespace

Many CKS tasks specify a namespace. If you create resources in the default namespace instead:

# WRONG — creates in default namespace
kubectl apply -f networkpolicy.yaml

# RIGHT — specify namespace
kubectl apply -f networkpolicy.yaml -n production

Or set the namespace in your context:

kubectl config set-context --current --namespace=production

Trap 3: NetworkPolicy Direction Confusion

Direction Meaning
Ingress Traffic coming INTO the selected Pods
Egress Traffic going OUT FROM the selected Pods

Common mistake: Creating an ingress rule when the question asks to restrict outbound traffic (egress), or vice versa.

Prevention: Always ask yourself: “From whose perspective? Which Pod is sending, which is receiving?”

Trap 4: Wrong Seccomp Profile Path

Seccomp Localhost profiles must be relative to the kubelet’s seccomp directory:

# WRONG — absolute path
seccompProfile:
  type: Localhost
  localhostProfile: /var/lib/kubelet/seccomp/profiles/my-profile.json

# RIGHT — relative to seccomp root
seccompProfile:
  type: Localhost
  localhostProfile: profiles/my-profile.json

The kubelet automatically prepends /var/lib/kubelet/seccomp/ to the path.

Trap 5: Not Loading AppArmor Profile Before Creating Pod

# WRONG order — Pod fails because profile doesn't exist on node
kubectl apply -f pod-with-apparmor.yaml
apparmor_parser -q /etc/apparmor.d/my-profile  # Too late!

# RIGHT order
apparmor_parser -q /etc/apparmor.d/my-profile   # Load first
kubectl apply -f pod-with-apparmor.yaml          # Then create Pod

If the profile isn’t loaded, the Pod stays in Blocked or Error state.

Trap 6: Editing Default Falco Rules

# WRONG — never edit this file (overwritten on upgrade)
vi /etc/falco/falco_rules.yaml

# RIGHT — put custom rules here
vi /etc/falco/falco_rules.local.yaml

Trap 7: Not Restarting Services After Config Changes

After editing Falco config, API server manifests, or kubelet config, you must restart the relevant service:

# After editing Falco rules
systemctl restart falco

# After editing kubelet config
systemctl restart kubelet

# After editing API server static Pod manifest
# (automatic restart — but verify it comes back)
crictl ps | grep kube-apiserver

For static Pods (API server, etcd, scheduler, controller-manager): Editing the manifest in /etc/kubernetes/manifests/ triggers automatic restart. But if the YAML is invalid, the Pod won’t come back — always validate before saving.

Trap 8: Forgetting to Verify

After applying any security configuration, verify it works:

# Verify NetworkPolicy blocks traffic
kubectl exec test-pod -- wget -qO- --timeout=2 http://target-service

# Verify AppArmor profile is enforced
kubectl get pod secure-pod -o jsonpath='{.metadata.annotations}'

# Verify Seccomp is applied
kubectl get pod secure-pod -o jsonpath='{.spec.securityContext.seccompProfile}'

# Verify Falco detects events
kubectl exec test-pod -- cat /etc/shadow
journalctl -u falco | tail -5

Exam Day Checklist

1 Hour Before

  • Close all unnecessary applications
  • Clear your desk completely
  • Test webcam and microphone
  • Have your ID ready
  • Water in a clear container (if needed)
  • Use the bathroom
  • Disable all notifications (system, phone, messaging)

5 Minutes Before

  • Log into the PSI exam portal
  • Complete proctor check-in (ID, room scan)
  • Verify browser is Google Chrome / Chromium
  • Deep breath — you’ve prepared for this

First 60 Seconds of Exam

# Set up your environment immediately
alias k=kubectl
export do="--dry-run=client -o yaml"
export now="--force --grace-period=0"

# Quick scan of all questions (note easy ones)
# Switch to the first question's context
kubectl config use-context <context-name>

Key Bookmarks to Prepare

Prepare browser bookmarks for these specific pages before exam day:

Bookmark URL Path Why
NetworkPolicy spec kubernetes.io/docs → NetworkPolicy Copy YAML structure for ingress/egress rules
Pod SecurityContext kubernetes.io/docs → Security Context Reference all security fields
Audit Policy kubernetes.io/docs → Auditing Audit levels and policy YAML
Pod Security Standards kubernetes.io/docs → Pod Security Standards Three levels reference
PSA labels kubernetes.io/docs → Pod Security Admission Namespace label syntax
Encryption at rest kubernetes.io/docs → Encrypting Secret Data EncryptionConfiguration YAML
Falco rules falco.org/docs → Rules Rule syntax and macros
AppArmor with K8s kubernetes.io/docs → AppArmor Profile annotation/securityContext syntax
Trivy CLI aquasecurity.github.io/trivy → CLI Command-line flags and options
Seccomp kubernetes.io/docs → Seccomp Profile types and Pod spec syntax

Pro tip: Organize bookmarks in a “CKS Exam” folder in your browser. During the exam, you’ll need to find specific YAML snippets quickly — 10 seconds of bookmark navigation vs 2 minutes of searching the docs.


Practice Questions

Q1: You have 120 minutes for 18 CKS questions. Using the 3-pass strategy, how would you allocate time?

Show Answer
Pass Time Target
Pass 1 (Quick wins) 10–15 min 3–5 easy questions (<2 min each)
Pass 2 (Medium tasks) 60–70 min 7–10 medium questions (5–8 min each)
Pass 3 (Hard tasks) 25–35 min Remaining 3–5 hard questions + review

Average ~6.7 min per question. Quick wins in Pass 1 build confidence and secure easy points before tackling complex tasks.


Q2: What is the correct order of operations when applying an AppArmor profile to a Pod?

Show Answer
  1. Write the AppArmor profile (e.g., /etc/apparmor.d/my-profile)
  2. Load the profile on the target node: apparmor_parser -q /etc/apparmor.d/my-profile
  3. Verify the profile is loaded: aa-status | grep my-profile
  4. Create the Pod with the AppArmor reference in the spec
  5. Verify the Pod is running and the profile is enforced

Loading the profile before creating the Pod is critical. If the profile isn’t loaded, the Pod will fail to start.


Q3: Why should you run :set paste in vim before pasting YAML from the browser?

Show Answer

Without :set paste, vim auto-indents each pasted line based on the previous line’s indentation. For multi-line YAML, this causes cascading indentation errors — each line gets indented further than the last, destroying the YAML structure.

:set paste disables auto-indentation temporarily, preserving the exact formatting of the pasted content. After pasting, run :set nopaste to re-enable normal vim behavior.


Q4: A question asks you to “restrict egress traffic from Pods in namespace backend to only allow DNS and connections to namespace database.” Which NetworkPolicy direction do you configure?

Show Answer

Egress. The question says “restrict egress traffic from Pods” — this means controlling traffic leaving the backend Pods.

You would create a NetworkPolicy with:

  • podSelector: {} (selects all Pods in backend)
  • policyTypes: [Egress]
  • egress rules allowing:
    • DNS: port 53 (TCP and UDP) to kube-dns
    • Database: namespaceSelector matching database namespace

A common trap is confusing this with ingress. Egress = traffic from the selected Pods. Ingress = traffic to the selected Pods.


Q5: After editing /etc/kubernetes/manifests/kube-apiserver.yaml, what should you do next?

Show Answer

Wait for the static Pod to restart automatically and verify it comes back. The kubelet monitors /etc/kubernetes/manifests/ and automatically restarts static Pods when their manifests change.

Verification steps:

# Watch for the API server to come back
crictl ps | grep kube-apiserver

# Or check with kubectl (may take 30-60 seconds)
kubectl get pods -n kube-system | grep apiserver

# If it doesn't come back, check the YAML for errors
cat /etc/kubernetes/manifests/kube-apiserver.yaml | python3 -c "import yaml,sys; yaml.safe_load(sys.stdin)"

If the YAML is invalid, the API server won’t start and kubectl will stop working. Always validate YAML before saving.


Next: Test your knowledge with Practice Questions →

Updated: