Module 0.2: Security Lab Setup
Complexity:
[MEDIUM]- Multiple tools to installTime to Complete: 45-60 minutes
Prerequisites: Working Kubernetes cluster (from CKA), kubectl configured
What You’ll Be Able to Do
Section titled “What You’ll Be Able to Do”After completing this module, you will be able to:
- Deploy a security-focused Kubernetes lab with Trivy, Falco, and kube-bench installed
- Configure cluster components for security testing and vulnerability scanning
- Diagnose common lab setup issues with security tool installations
- Create reproducible lab environments for practicing CKS exam scenarios
Why This Module Matters
Section titled “Why This Module Matters”CKS requires hands-on practice with security tools. You can’t learn Trivy from documentation alone—you need to scan images, see vulnerabilities, and practice remediation. Same with Falco: writing rules requires a running instance generating alerts.
This module builds your security lab: a cluster equipped with all tools you’ll encounter on the exam.
Lab Architecture
Section titled “Lab Architecture”┌─────────────────────────────────────────────────────────────┐│ CKS SECURITY LAB │├─────────────────────────────────────────────────────────────┤│ ││ ┌─────────────────────────────────────────────────────┐ ││ │ Kubernetes Cluster │ ││ │ │ ││ │ Security Tools Deployed: │ ││ │ ┌─────────┐ ┌─────────┐ ┌───────────┐ │ ││ │ │ Falco │ │ Trivy │ │ kube-bench│ │ ││ │ │(runtime)│ │(scanner)│ │(CIS audit)│ │ ││ │ └─────────┘ └─────────┘ └───────────┘ │ ││ │ │ ││ │ Security Features Enabled: │ ││ │ ┌─────────┐ ┌─────────┐ ┌───────────┐ │ ││ │ │AppArmor │ │ seccomp │ │ Audit │ │ ││ │ │profiles │ │profiles │ │ Logging │ │ ││ │ └─────────┘ └─────────┘ └───────────┘ │ ││ │ │ ││ │ Vulnerable Apps (for practice): │ ││ │ ┌─────────────────────────────────────────┐ │ ││ │ │ Intentionally insecure deployments │ │ ││ │ │ for scanning and hardening practice │ │ ││ │ └─────────────────────────────────────────┘ │ ││ │ │ ││ └─────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────┘Stop and think: Why do you think audit logging is not enabled by default in Kubernetes? What trade-off is being made, and why is enabling it essential for CKS?
Option 1: Kind Cluster (Recommended for Learning)
Section titled “Option 1: Kind Cluster (Recommended for Learning)”For most CKS study, a kind cluster with security tools works well:
# Create kind cluster with audit logging enabledcat <<EOF > kind-cks.yamlkind: ClusterapiVersion: kind.x-k8s.io/v1alpha4nodes:- role: control-plane kubeadmConfigPatches: - | kind: ClusterConfiguration apiServer: extraArgs: audit-policy-file: /etc/kubernetes/audit-policy.yaml audit-log-path: /var/log/kubernetes/audit.log audit-log-maxage: "30" audit-log-maxbackup: "3" audit-log-maxsize: "100" extraVolumes: - name: audit-policy hostPath: /etc/kubernetes/audit-policy.yaml mountPath: /etc/kubernetes/audit-policy.yaml readOnly: true pathType: File - name: audit-logs hostPath: /var/log/kubernetes mountPath: /var/log/kubernetes pathType: DirectoryOrCreate extraMounts: - hostPath: ./audit-policy.yaml containerPath: /etc/kubernetes/audit-policy.yaml readOnly: true - hostPath: ./audit-logs containerPath: /var/log/kubernetes- role: worker- role: workerEOF
# Create the audit log directory on the hostmkdir -p audit-logs
# Create basic audit policycat <<EOF > audit-policy.yamlapiVersion: audit.k8s.io/v1kind: Policyrules:- level: Metadata resources: - group: "" resources: ["secrets", "configmaps"]- level: Request resources: - group: "" resources: ["pods"]- level: None users: ["system:kube-proxy"] verbs: ["watch"] resources: - group: "" resources: ["endpoints", "services"]- level: Metadata omitStages: - RequestReceivedEOF
# Create the clusterkind create cluster --name cks-lab --config kind-cks.yamlOption 2: Kubeadm Cluster (Closer to Exam)
Section titled “Option 2: Kubeadm Cluster (Closer to Exam)”If you have a kubeadm cluster from CKA practice, add security configurations:
# Enable audit logging on existing cluster# Edit /etc/kubernetes/manifests/kube-apiserver.yaml on control plane
# Add these flags to the API server:# --audit-policy-file=/etc/kubernetes/audit-policy.yaml# --audit-log-path=/var/log/kubernetes/audit.log# --audit-log-maxage=30# --audit-log-maxbackup=3# --audit-log-maxsize=100
# Create the audit policy filesudo mkdir -p /etc/kubernetessudo tee /etc/kubernetes/audit-policy.yaml <<EOFapiVersion: audit.k8s.io/v1kind: Policyrules:- level: Metadata resources: - group: "" resources: ["secrets", "configmaps"]- level: RequestResponse resources: - group: "" resources: ["pods"] verbs: ["create", "delete"]- level: Metadata omitStages: - RequestReceivedEOF
# Create log directorysudo mkdir -p /var/log/kubernetesInstall Security Tools
Section titled “Install Security Tools”1. Trivy (Image Scanner)
Section titled “1. Trivy (Image Scanner)”# Install Trivy CLI# On Ubuntu/Debiansudo apt-get install wget apt-transport-https gnupg lsb-release -ywget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/trivy.listsudo apt-get updatesudo apt-get install trivy -y
# On macOSbrew install trivy
# Verify installationtrivy --version
# Test scantrivy image nginx:latest2. Falco (Runtime Security)
Section titled “2. Falco (Runtime Security)”# Install Falco using Helmhelm repo add falcosecurity https://falcosecurity.github.io/chartshelm repo update
# Install Falco with modern eBPF driverhelm install falco falcosecurity/falco \ --namespace falco \ --create-namespace \ --set driver.kind=modern_ebpf \ --set falcosidekick.enabled=true \ --set falcosidekick.webui.enabled=true
# For kind clusters, use kernel module driver instead# helm install falco falcosecurity/falco \# --namespace falco \# --create-namespace \# --set driver.kind=kmod
# Verify Falco is runningkubectl get pods -n falco
# Check Falco logskubectl logs -n falco -l app.kubernetes.io/name=falco3. kube-bench (CIS Benchmark)
Section titled “3. kube-bench (CIS Benchmark)”# Run kube-bench as a jobkubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
# Wait for completionkubectl wait --for=condition=complete job/kube-bench --timeout=120s
# View resultskubectl logs job/kube-bench
# For detailed output, run interactively on control plane node# Download and run kube-bench directlycurl -L https://github.com/aquasecurity/kube-bench/releases/download/v0.7.0/kube-bench_0.7.0_linux_amd64.tar.gz -o kube-bench.tar.gztar -xvf kube-bench.tar.gz./kube-bench run --targets=master4. kubesec (Static Analysis)
Section titled “4. kubesec (Static Analysis)”# Install kubesec# Binary installationwget https://github.com/controlplaneio/kubesec/releases/download/v2.14.0/kubesec_linux_amd64.tar.gztar -xvf kubesec_linux_amd64.tar.gzsudo mv kubesec /usr/local/bin/
# Or use Docker# docker run -i kubesec/kubesec scan /dev/stdin < deployment.yaml
# Test kubeseccat <<EOF | kubesec scan /dev/stdinapiVersion: v1kind: Podmetadata: name: testspec: containers: - name: test image: nginx securityContext: runAsUser: 0EOFVerify AppArmor Support
Section titled “Verify AppArmor Support”# Check if AppArmor is enabled (on nodes)cat /sys/module/apparmor/parameters/enabled# Should output: Y
# List loaded profilessudo aa-status
# Check if container runtime supports AppArmor# For containerd, it's enabled by defaultPause and predict: You install Falco on a kind cluster using the modern_ebpf driver, but the cluster node’s kernel doesn’t support eBPF CO-RE. What symptoms would you see and how would you fix it?
Verify Seccomp Support
Section titled “Verify Seccomp Support”# Check kernel seccomp supportgrep CONFIG_SECCOMP /boot/config-$(uname -r)# Should see: CONFIG_SECCOMP=y
# Kubernetes default seccomp profile locationls /var/lib/kubelet/seccomp/
# Create a test seccomp profile directorysudo mkdir -p /var/lib/kubelet/seccomp/profilesPause and predict: You’re about to deploy intentionally insecure containers. In a real cluster, what would prevent these from being created? Think about which CKS topics (Pod Security Admission, image scanning, RBAC) would block each one.
Deploy Vulnerable Apps (Practice Targets)
Section titled “Deploy Vulnerable Apps (Practice Targets)”Create intentionally insecure deployments for practice:
# Create namespace for practicekubectl create namespace insecure-apps
# Deploy vulnerable app 1: Privileged containercat <<EOF | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: privileged-pod namespace: insecure-appsspec: containers: - name: nginx image: nginx:1.25 securityContext: privileged: trueEOF
# Deploy vulnerable app 2: Root usercat <<EOF | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: root-pod namespace: insecure-appsspec: containers: - name: nginx image: nginx:1.25 securityContext: runAsUser: 0EOF
# Deploy vulnerable app 3: No resource limitscat <<EOF | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: unlimited-pod namespace: insecure-appsspec: containers: - name: nginx image: nginx:1.25 # No resources specified = unlimitedEOF
# Deploy vulnerable app 4: Vulnerable imagecat <<EOF | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: vulnerable-image namespace: insecure-appsspec: containers: - name: app image: vulnerables/web-dvwa # Known vulnerable imageEOFLab Validation Script
Section titled “Lab Validation Script”Run this to verify your lab is ready:
#!/bin/bashecho "=== CKS Lab Validation ==="echo ""
# Check clusterecho "1. Cluster Status:"kubectl cluster-info | head -2echo ""
# Check Trivyecho "2. Trivy:"if command -v trivy &> /dev/null; then trivy --versionelse echo " NOT INSTALLED"fiecho ""
# Check Falcoecho "3. Falco:"kubectl get pods -n falco -l app.kubernetes.io/name=falco --no-headers 2>/dev/null | head -1 || echo " NOT RUNNING"echo ""
# Check kube-benchecho "4. kube-bench:"if command -v kube-bench &> /dev/null; then echo " Installed"else echo " Available as Job"fiecho ""
# Check AppArmorecho "5. AppArmor:"if [ -f /sys/module/apparmor/parameters/enabled ]; then cat /sys/module/apparmor/parameters/enabledelse echo " Check on cluster nodes"fiecho ""
# Check Audit Loggingecho "6. Audit Logging:"kubectl get pods -n kube-system kube-apiserver-* -o yaml 2>/dev/null | grep -q "audit-log-path" && echo " Enabled" || echo " Check API server config"echo ""
echo "=== Validation Complete ==="Did You Know?
Section titled “Did You Know?”-
Falco can detect cryptomining in real-time by monitoring for suspicious CPU patterns and network connections to mining pools.
-
Trivy scans more than images—it can scan filesystems, git repositories, and Kubernetes manifests for misconfigurations.
-
The CIS Kubernetes Benchmark has over 200 checks. kube-bench automates all of them.
-
AppArmor and SELinux are alternatives—most Kubernetes environments use AppArmor (Ubuntu default) or SELinux (RHEL/CentOS default). CKS focuses on AppArmor.
Common Mistakes
Section titled “Common Mistakes”| Mistake | Why It Hurts | Solution |
|---|---|---|
| No audit logging enabled | Can’t practice audit-related tasks | Configure API server with audit policy |
| Falco not running | Can’t practice runtime detection | Install via Helm, check driver |
| Only scanning images once | Need workflow practice | Integrate into routine |
| Skipping vulnerable app setup | No targets to practice hardening | Deploy intentionally insecure apps |
| Not checking node-level tools | AppArmor/seccomp are node features | SSH to nodes, verify support |
-
You run
trivy image nginx:latestand get over 140 vulnerabilities. Your manager panics and says to switch to Alpine-based images immediately. Is this the right response, and what would you actually do?Answer
Switching to Alpine may reduce the vulnerability count since Alpine has fewer packages, but it is not a complete or guaranteed solution. The right approach is to filter by severity using `trivy image --severity HIGH,CRITICAL nginx:latest` and focus on fixing CRITICAL and HIGH vulnerabilities first. You should also check if patched versions of the specific vulnerable packages exist before swapping the entire base image. Furthermore, consider adopting distroless or truly minimal base images if the application supports it. Trivy scans images, filesystems, git repos, and Kubernetes manifests, so you must use all these capabilities to build a comprehensive security posture rather than just reacting to raw vulnerability counts. -
During CKS lab setup, you create a custom seccomp profile and place it in
/etc/seccomp/profiles/on the node. When you reference it in a pod spec, the pod fails to start with a create error. What went wrong?Answer
Kubernetes expects custom seccomp profiles to be located in `/var/lib/kubelet/seccomp/` on the node where the pod is scheduled to run, rather than the standard OS path `/etc/seccomp/profiles/`. The kubelet constructs the profile path relative to its own configured seccomp directory. Because the profile was placed in the wrong directory, the container runtime could not find the file and refused to start the container. Moving the JSON profile to the correct path, specifically `/var/lib/kubelet/seccomp/profiles/`, and updating the pod spec to reference `localhost/profiles/your-profile.json` will resolve the issue. -
Your security team notices an alert and asks why you are deploying a container image called
vulnerables/web-dvwainto the cluster. Explain the security rationale for intentionally deploying vulnerable applications.Answer
Intentionally vulnerable applications serve as highly realistic practice targets in an isolated lab environment. They allow you to practice scanning with Trivy to find real CVEs and configuring Falco to detect actual runtime exploitation attempts. These applications also give you a baseline to practice hardening techniques using security contexts, Pod Security Admission, and NetworkPolicies. Without these realistic, flawed targets, you cannot adequately simulate the remediation workflows that the CKS exam tests. The critical mitigating factor is that these deployments are strictly confined to a dedicated, isolated lab namespace and never allowed in a production cluster. -
You install Falco via Helm with
driver.kind=modern_ebpfon your lab cluster, but the Falco pods are stuck in CrashLoopBackOff. The logs mention “kernel version not supported.” How do you diagnose and fix this?Answer
The modern eBPF driver requires a Linux kernel version that supports eBPF CO-RE (Compile Once - Run Everywhere), which is typically found in kernels 5.8 or newer. If your cluster node's kernel is older or lacks these specific features, Falco cannot successfully load its modern eBPF probe, resulting in the crash. To fix this, you must switch Falco to an alternative driver that is compatible with your environment. You can use the kernel module driver by running `helm upgrade falco falcosecurity/falco --set driver.kind=kmod -n falco`, which requires kernel headers, or fall back to the classic eBPF driver. For environments like kind clusters, the kernel module driver is frequently the most reliable choice.
Hands-On Exercise
Section titled “Hands-On Exercise”Task: Validate your security lab setup.
# 1. Verify cluster is runningkubectl get nodes
# 2. Install Trivy and scan an imagetrivy image nginx:latest | head -50
# 3. Check Falco is running (if installed)kubectl get pods -n falco
# 4. Run kube-benchkubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yamlkubectl wait --for=condition=complete job/kube-bench --timeout=120skubectl logs job/kube-bench | head -100
# 5. Create a test pod and scan itkubectl run test-pod --image=nginx:1.25trivy image nginx:1.25
# 6. Cleanupkubectl delete pod test-podkubectl delete job kube-benchSuccess criteria: Trivy scans images, kube-bench reports results, cluster is accessible.
Summary
Section titled “Summary”Your CKS lab needs:
Tools installed:
- Trivy (image scanning)
- Falco (runtime detection)
- kube-bench (CIS benchmarks)
- kubesec (static analysis)
Cluster features enabled:
- Audit logging
- AppArmor support (node-level)
- Seccomp support (node-level)
Practice targets:
- Intentionally vulnerable deployments
- Known-vulnerable images
This lab environment lets you practice every CKS exam domain hands-on.
Next Module
Section titled “Next Module”Module 0.3: Security Tool Mastery - Deep dive into Trivy, Falco, and kube-bench usage.