Practice Questions -- Domain 3: Minimize Microservice Vulnerabilities
Highest Weight Domain (20%)
This domain has the highest weight on the CKS exam. These 25 questions cover all major topics: SecurityContexts, Secrets, OPA/Gatekeeper, RuntimeClass, Admission Controllers, mTLS, and Container Hardening. Practice until you can solve each in under 5 minutes.
How to Use These Questions
- Set up a practice cluster (kubeadm, kind, or minikube)
- Time yourself -- aim for 4-5 minutes per question
- Do NOT look at the solutions until you have attempted each question
- Focus on questions you find difficult -- those are the ones you will learn the most from
Question 1 -- SecurityContext: Non-Root Enforcement
Difficulty: Easy
A pod named legacy-app is running in the production namespace with the following specification. It currently runs as root.
Modify the pod to:
- Run as user ID
1000and group ID1000 - Enforce non-root execution
- Prevent privilege escalation
- Drop all Linux capabilities
The pod uses the image nginx:1.25 with a single container named app.
Question 2 -- SecurityContext: Read-Only Filesystem
Difficulty: Medium
Create a pod named secure-nginx in the default namespace that:
- Uses the
nginx:1.25image - Has a read-only root filesystem
- Still functions correctly (nginx needs to write to
/var/cache/nginx,/var/run, and/tmp) - Runs as user
101(nginx user) - Uses a seccomp profile of type
RuntimeDefault
Question 3 -- SecurityContext: Pod vs Container Precedence
Difficulty: Easy
Create a pod named multi-user-pod in the default namespace with the following requirements:
- Pod-level:
runAsUser: 1000,runAsGroup: 3000,fsGroup: 2000 - Container
writer(imagebusybox:1.36, commandsh -c "id > /data/user.txt && sleep 3600"): should run as user2000(override pod-level) - Container
reader(imagebusybox:1.36, commandsh -c "sleep 3600"): should inherit pod-level user - Both containers share a volume mounted at
/data
After creation, verify the user IDs and file ownership in /data.
Question 4 -- Secrets: Encryption at Rest
Difficulty: Hard
Secrets in the cluster are currently stored unencrypted in etcd. Configure encryption at rest for secrets:
- Generate a 32-byte encryption key
- Create an
EncryptionConfigurationusing theaescbcprovider at/etc/kubernetes/enc/encryption-config.yaml - Configure the API server to use the encryption configuration
- Verify that the API server restarts successfully
- Create a test secret named
encrypted-secretin thedefaultnamespace with keypasswordand valueSuperSecret123 - Verify the secret is encrypted in etcd
Question 5 -- Secrets: Environment Variables to Volume Mounts
Difficulty: Medium
A pod named insecure-app in the security namespace currently exposes secrets through environment variables:
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: passwordThe secret db-credentials exists with keys username and password.
Refactor the pod to:
- Mount the secret as a volume at
/etc/secretsinstead of using environment variables - Set volume mount to read-only
- Set file permissions to
0400 - Remove the environment variable references
Question 6 -- Secrets: Verify etcd Encryption
Difficulty: Medium
A colleague claims that encryption at rest has been configured for secrets in the cluster. Verify this claim:
- Check if the API server has the
--encryption-provider-configflag set - Inspect the EncryptionConfiguration file to identify the encryption provider
- Create a test secret named
enc-testwith valueverify-me - Read the secret directly from etcd and confirm it is encrypted
- Confirm you can still read the secret normally through kubectl
Question 7 -- OPA/Gatekeeper: Require Labels
Difficulty: Hard
Gatekeeper is installed in the cluster. Create a policy that:
- Creates a
ConstraintTemplatenamedk8srequiredlabelsthat requires specified labels on resources - Creates a
Constraintnamedrequire-team-labelthat enforces all Pods in theproductionnamespace must have ateamlabel - The enforcement action should be
deny - Exclude the
kube-systemnamespace
Test by attempting to create a pod without the team label in the production namespace.
Question 8 -- OPA/Gatekeeper: Deny Privileged Containers
Difficulty: Hard
Create an OPA/Gatekeeper policy that:
- Creates a
ConstraintTemplatenamedk8sdenyprivilegedthat denies pods with privileged containers - The Rego policy should check both regular containers and init containers
- Creates a
Constraintnamedno-privileged-podsthat applies to all pods - Excludes the
kube-systemandgatekeeper-systemnamespaces
Verify by attempting to create a privileged pod.
Question 9 -- OPA/Gatekeeper: Enforce Image Registry
Difficulty: Hard
Create an OPA/Gatekeeper policy that:
- Creates a
ConstraintTemplatenamedk8sallowedreposwith a parameter for a list of allowed repository prefixes - Creates a
Constraintnamedrestrict-image-reposthat only allows images from:docker.io/library/gcr.io/my-company/
- Apply to all pods in the
productionnamespace - Use
dryrunenforcement action first, then change todenyafter verifying
Question 10 -- OPA/Gatekeeper: Audit Mode
Difficulty: Medium
An existing Gatekeeper Constraint named require-resource-limits is currently in deny mode and is blocking deployments. The development team needs time to add resource limits to their pods.
- Change the enforcement action from
denytodryrun(audit mode) - Verify the constraint is now in audit mode
- Check the audit results to see which existing pods violate the policy
- Document the namespace and pod names of violating resources
Question 11 -- RuntimeClass: gVisor Configuration
Difficulty: Medium
Configure container sandboxing with gVisor:
- Create a
RuntimeClassnamedgvisorwith handlerrunsc - Create a pod named
sandboxed-appin thedefaultnamespace that:- Uses the
nginx:1.25image - Uses the
gvisorRuntimeClass - Has a container named
web
- Uses the
Question 12 -- RuntimeClass: Multiple Runtimes
Difficulty: Medium
Create two RuntimeClass resources and assign pods to them:
- RuntimeClass
gvisorwith handlerrunsc - RuntimeClass
katawith handlerkata-runtimeand a pod overhead ofmemory: 160Miandcpu: 250m - Create a pod named
gvisor-podusing thegvisorRuntimeClass with imagebusybox:1.36runningsleep 3600 - Create a pod named
kata-podusing thekataRuntimeClass with imagebusybox:1.36runningsleep 3600
Question 13 -- Admission Controllers: Enable ImagePolicyWebhook
Difficulty: Hard
Configure the ImagePolicyWebhook admission controller:
- The webhook service endpoint is at
https://image-bouncer.default.svc:1323/image_policy - The required certificates are at:
- CA:
/etc/kubernetes/admission/ca.crt - Client cert:
/etc/kubernetes/admission/api-server-client.crt - Client key:
/etc/kubernetes/admission/api-server-client.key
- CA:
- Create the admission configuration at
/etc/kubernetes/admission/admission-config.yaml - Create the kubeconfig at
/etc/kubernetes/admission/kubeconfig.yaml - Enable the
ImagePolicyWebhookadmission controller - Set
defaultAllowtofalse(deny images if webhook is unreachable) - Ensure the API server restarts successfully
Question 14 -- Admission Controllers: ValidatingWebhookConfiguration
Difficulty: Medium
A validating webhook service pod-validator is running in the webhook-system namespace on port 443 with path /validate.
Create a ValidatingWebhookConfiguration named pod-security-webhook that:
- Intercepts
CREATEandUPDATEoperations on Pods - Uses the in-cluster service as the webhook endpoint
- Has a failure policy of
Fail(fail closed) - Excludes the
kube-systemnamespace - Sets a timeout of 10 seconds
- The CA bundle is available at
/etc/kubernetes/webhook/ca.crt
Question 15 -- Admission Controllers: Troubleshooting
Difficulty: Medium
Pods cannot be created in the production namespace. The error message indicates an admission webhook is denying requests. Investigate and fix the issue:
- Identify which webhook configuration is causing the rejection
- Check if the webhook service is healthy
- The webhook service pod in
webhook-systemnamespace has crashed. Determine the most appropriate immediate fix to restore pod creation ability - Apply the fix while maintaining security
Question 16 -- Container Hardening: Non-Root with Read-Only FS
Difficulty: Medium
Harden the following pod specification. Apply ALL of these security measures:
- Run as non-root user (UID 10001)
- Read-only root filesystem
- Drop all capabilities
- Prevent privilege escalation
- Set resource limits (128Mi memory, 250m CPU)
- Use RuntimeDefault seccomp profile
- Do not mount the service account token
- Provide writable
/tmpdirectory
The pod uses image python:3.12-slim with container name api and command ["python", "-m", "http.server", "8080"].
Question 17 -- Container Hardening: Identify and Fix Vulnerabilities
Difficulty: Medium
Examine the pod vulnerable-app in the audit namespace. Identify and fix all security issues:
apiVersion: v1
kind: Pod
metadata:
name: vulnerable-app
namespace: audit
spec:
containers:
- name: app
image: ubuntu:latest
command: ["sh", "-c", "apt-get update && apt-get install -y curl && sleep 3600"]
securityContext:
privileged: true
env:
- name: DB_PASSWORD
value: "plaintext-password-123"
ports:
- containerPort: 8080List all vulnerabilities and create a hardened version.
Question 18 -- Combined: SecurityContext + Secrets
Difficulty: Medium
Create a pod named secure-db-client in the production namespace that:
- Uses image
postgres:16-alpine - Container name
db-client - Mounts the existing secret
pg-credentials(keys:PGUSER,PGPASSWORD) as a volume at/etc/db-secretswith permissions0400 - Runs as user
70(postgres user), group70 - Has a read-only root filesystem
- Provides writable
/tmpand/var/run/postgresqldirectories - Drops all capabilities, prevents privilege escalation
- Command:
["sleep", "3600"]
Question 19 -- Combined: RuntimeClass + SecurityContext
Difficulty: Hard
Create a high-security pod that combines sandboxing with security contexts:
- Ensure a RuntimeClass named
gvisorwith handlerrunscexists - Create a pod named
high-security-podin therestrictednamespace that:- Uses the
gvisorRuntimeClass - Image:
gcr.io/distroless/static:nonroot - Container name:
app, command:["/bin/sleep", "3600"] - Runs as user 65532, group 65532
- Read-only root filesystem
- Drops all capabilities
- No privilege escalation
- RuntimeDefault seccomp profile
- No service account token mount
- Memory limit: 64Mi, CPU limit: 100m
- Uses the
Question 20 -- Combined: Gatekeeper + SecurityContext
Difficulty: Hard
Create a Gatekeeper policy and demonstrate compliance:
- Create a
ConstraintTemplatenamedk8srequirereadonlyfsthat denies pods where containers do not havereadOnlyRootFilesystem: true - Create a
Constraintnamedrequire-readonly-fsthat applies to pods in theproductionnamespace - Demonstrate a pod that is rejected by the policy
- Create a compliant pod named
compliant-appthat passes the policy with imagenginx:1.25
Question 21 -- Secrets: Key Rotation
Difficulty: Hard
The cluster currently uses encryption at rest with an aescbc key named key1. Perform a key rotation:
- Generate a new 32-byte encryption key
- Update the EncryptionConfiguration to use the new key (
key2) as the primary encryption key while keepingkey1for decryption of old secrets - Restart the API server
- Re-encrypt all existing secrets with the new key
- Verify that newly created secrets use the new key
Question 22 -- Admission Controllers: Mutating vs Validating Order
Difficulty: Easy
Answer the following questions about admission controller ordering:
- A MutatingWebhookConfiguration adds a label
validated: trueto all pods. A ValidatingWebhookConfiguration rejects pods without the labelvalidated: true. Will a pod creation request succeed? Explain the order of operations. - What is the
reinvocationPolicyfield in MutatingWebhookConfiguration, and when would you set it toIfNeeded? - What happens when
failurePolicy: Failis set and the webhook service is down?
Create the MutatingWebhookConfiguration and ValidatingWebhookConfiguration YAML files (no need to deploy the actual webhook services).
Question 23 -- mTLS: PeerAuthentication
Difficulty: Medium
Istio is installed in the cluster. Configure mTLS:
- Create a mesh-wide
PeerAuthenticationpolicy in theistio-systemnamespace that sets mTLS mode toSTRICT - Create a namespace-level
PeerAuthenticationfor thelegacynamespace that sets mTLS mode toPERMISSIVE(to allow non-mesh services to communicate) - Create an
AuthorizationPolicyin theproductionnamespace namedallow-frontend-onlythat:- Applies to pods with label
app: api-server - Only allows traffic from the
frontendservice account in theproductionnamespace - Only allows GET and POST methods on paths starting with
/api/
- Applies to pods with label
Question 24 -- Combined: Full Pod Hardening
Difficulty: Hard
You are given a Deployment named web-app in the production namespace. Apply the maximum security hardening:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: nginx:latest
ports:
- containerPort: 80Apply ALL of the following:
- Pin the image to a specific tag (not
latest) - Non-root user (UID 101 for nginx)
- Read-only root filesystem with necessary writable volumes
- Drop all capabilities, add only
NET_BIND_SERVICE - Prevent privilege escalation
- Resource limits (256Mi memory, 500m CPU)
- RuntimeDefault seccomp profile
- Do not automount service account token
- Add
fsGroup: 101
Question 25 -- Combined: Multi-Layer Security
Difficulty: Hard
Implement a comprehensive multi-layer security configuration:
Secret encryption: Verify encryption at rest is configured. If not, set it up using
secretboxprovider.OPA Policy: Create a Gatekeeper policy (
ConstraintTemplate+Constraint) that ensures all pods inproductionnamespace:- Must have
runAsNonRoot: trueat pod level OR container level
- Must have
RuntimeClass: Create a RuntimeClass
gvisorwith handlerrunscSecure Pod: Create a pod named
fortressinproductionnamespace that:- Uses the
gvisorRuntimeClass - Mounts a secret named
app-secret(create it with keyapi-key, valuesk-12345) at/etc/secrets - Has all security hardening applied (non-root, read-only FS, drop caps, no escalation)
- Passes the OPA policy you created
- Uses the
This question tests your ability to combine all Domain 3 concepts into a cohesive security architecture.