CKAD — Security Lab
Lab 1: Running as Non-Root
# Create a Pod running as user 1000
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: non-root-pod
spec:
securityContext:
runAsUser: 1000
runAsNonRoot: true
containers:
- name: app
image: busybox:1.36
command: ["/bin/sh", "-c", "id && whoami && sleep 3600"]
securityContext:
allowPrivilegeEscalation: false
EOF
kubectl logs non-root-pod
# Expected: uid=1000 gid=0(root)
# whoami: unknown uid 1000
Lab 2: ServiceAccount with Limited Permissions
# Create a ServiceAccount
kubectl create serviceaccount limited-sa
# Create a Role that can only list Pods
kubectl create role pod-lister --verb=list --resource=pods
# Bind the Role to the ServiceAccount
kubectl create rolebinding pod-lister-binding \
--role=pod-lister \
--serviceaccount=default:limited-sa
# Create a Pod with this ServiceAccount
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: sa-test
spec:
serviceAccountName: limited-sa
containers:
- name: kubectl
image: bitnami/kubectl:latest
command: ["/bin/sh", "-c", "sleep 3600"]
EOF
# Test from inside the Pod
kubectl exec sa-test -- kubectl get pods
# Expected: Lists pods successfully
kubectl exec sa-test -- kubectl get secrets
# Expected: Error — forbidden
Practice Questions
Q1: Create a Pod that runs as user ID 1000, group ID 2000, with a read-only root filesystem.
Show Answer
```yaml apiVersion: v1 kind: Pod metadata: name: secure-pod spec: securityContext: runAsUser: 1000 runAsGroup: 2000 containers: - name: app image: busybox:1.36 command: ["/bin/sh", "-c", "id && sleep 3600"] securityContext: readOnlyRootFilesystem: true volumeMounts: - name: tmp mountPath: /tmp volumes: - name: tmp emptyDir: {} ```Q2: What does allowPrivilegeEscalation: false do?
Show Answer
It prevents a process in the container from gaining more privileges than its parent process. This blocks exploits like `setuid` binaries that could allow a non-root process to gain root access. It is a security best practice and should be set to `false` on all production containers.Q3: Create a ServiceAccount named deploy-sa. Grant it permission to create and delete Deployments in the production namespace.
Show Answer
```bash kubectl create serviceaccount deploy-sa -n production kubectl create role deployment-manager \ --verb=create,delete,get,list \ --resource=deployments \ -n production kubectl create rolebinding deploy-sa-binding \ --role=deployment-manager \ --serviceaccount=production:deploy-sa \ -n production ``` Verify: ```bash kubectl auth can-i create deployments --as=system:serviceaccount:production:deploy-sa -n production # Expected: yes ```Q4: How do you prevent a Pod from mounting the ServiceAccount token?
Show Answer
Set `automountServiceAccountToken: false` at the Pod level or ServiceAccount level: ```yaml # Pod level spec: automountServiceAccountToken: false # Or ServiceAccount level apiVersion: v1 kind: ServiceAccount metadata: name: my-sa automountServiceAccountToken: false ``` This is a security best practice for Pods that do not need to access the Kubernetes API.Q5: A container needs to bind to port 80 but runs as non-root. Which capability do you add?