intermediateCKAD6-8 weeks prep6 min read
CKAD: Certified Kubernetes Application Developer — Study Guide
Study guide for the CKAD Certified Kubernetes Application Developer exam. Focuses on deploying, configuring, and troubleshooting applications in Kubernetes — for developers, not admins.
kubernetesckadk8sdeveloperintermediatecncflinux-foundationcontainers
Domains
8
Key concepts
13
Study time
6-8 weeks
Exam Overview
| Detail | Info |
|---|---|
| Exam code | CKAD |
| Duration | 2 hours |
| Format | Hands-on performance-based (real clusters) |
| Passing score | 66% |
| Cost | $395 USD (includes 1 free retake) |
| Validity | 3 years |
CKAD vs CKA
| CKAD | CKA | |
|---|---|---|
| Focus | Application deployment and configuration | Cluster administration |
| Audience | Developers | Platform/ops engineers |
| Overlap | Pods, Services, Networking | Cluster setup, etcd, RBAC |
| Harder topic | Multi-container patterns, Helm | kubeadm, troubleshooting |
Domain Weightings
| Domain | Weight |
|---|---|
| Application Design and Build | 20% |
| Application Deployment | 20% |
| Application Observability and Maintenance | 15% |
| Application Environment, Configuration, and Security | 25% |
| Services and Networking | 20% |
Domain 1: Application Design and Build (20%)
Multi-container pod patterns
# Sidecar pattern — logging agent alongside main app
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: log-vol
mountPath: /var/log/app
- name: log-shipper
image: fluentd:latest
volumeMounts:
- name: log-vol
mountPath: /var/log/app
volumes:
- name: log-vol
emptyDir: {}
# Init container — run setup before main app starts
spec:
initContainers:
- name: wait-for-db
image: busybox
command: ['sh', '-c', 'until nc -z db 5432; do sleep 2; done']
containers:
- name: app
image: myapp:1.0
Jobs and CronJobs
# One-off Job
kubectl create job pi --image=perl -- perl -Mbignum=bpi -wle 'print bpi(2000)'
# CronJob (run every minute)
kubectl create cronjob hello --image=busybox --schedule="*/1 * * * *" \
-- echo "Hello from CronJob"
Domain 2: Application Deployment (20%)
Deployment strategies
# Rolling update (default)
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
# Recreate (downtime)
strategy:
type: Recreate
# Blue-green deployment (manual)
kubectl set image deployment/app-blue app=myapp:1.0
kubectl set image deployment/app-green app=myapp:2.0
# Switch service selector from blue to green:
kubectl patch service app-svc -p '{"spec":{"selector":{"version":"green"}}}'
Helm fundamentals
# Add repo and install
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-release bitnami/nginx
# Override values
helm install my-release bitnami/nginx --set service.type=NodePort
# Upgrade
helm upgrade my-release bitnami/nginx --set image.tag=1.22
# Rollback
helm rollback my-release 1
# List releases
helm list -A
# Template rendering (debug)
helm template my-release bitnami/nginx --set service.type=NodePort
Domain 3: Observability and Maintenance (15%)
Probes
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
httpGet:
path: /started
port: 8080
failureThreshold: 30
periodSeconds: 10
# Allows 5 minutes (30*10s) for slow-starting containers
| Probe | Action on failure | Use for |
|---|---|---|
| liveness | Restart the container | Detect deadlocks |
| readiness | Remove from service endpoints | Not ready to handle traffic |
| startup | Restart if not started in time | Slow-start containers |
Debugging commands
kubectl logs <pod> [-c <container>] [--previous]
kubectl describe pod <pod>
kubectl exec -it <pod> -- /bin/sh
kubectl top pods -n <ns>
kubectl get events -n <ns> --sort-by='.lastTimestamp'
Domain 4: Configuration and Security (25%)
ConfigMaps
# Create
kubectl create configmap app-config \
--from-literal=DB_HOST=mydb \
--from-literal=DB_PORT=5432
# Use as environment variables
kubectl set env deployment/app --from=configmap/app-config
# Use as a volume (each key becomes a file)
volumes:
- name: config
configMap:
name: app-config
containers:
- volumeMounts:
- name: config
mountPath: /etc/config
Secrets
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password='S3cur3!'
# Use as env vars
kubectl set env deployment/app --from=secret/db-secret
Resource quotas and limits
# LimitRange — default limits for a namespace
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: dev
spec:
limits:
- default:
cpu: 500m
memory: 256Mi
defaultRequest:
cpu: 100m
memory: 128Mi
type: Container
# ResourceQuota — total namespace limit
apiVersion: v1
kind: ResourceQuota
metadata:
name: ns-quota
namespace: dev
spec:
hard:
requests.cpu: "4"
requests.memory: 4Gi
limits.cpu: "8"
limits.memory: 8Gi
pods: "20"
Security contexts
securityContext:
runAsUser: 1000 # don't run as root
runAsGroup: 3000
fsGroup: 2000
readOnlyRootFilesystem: true # immutable container FS
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
add: [NET_BIND_SERVICE]
ServiceAccount
# Create dedicated service account for pod (not default)
kubectl create serviceaccount app-sa
# Assign to pod
kubectl run myapp --image=nginx --serviceaccount=app-sa $do > pod.yaml
Domain 5: Services and Networking (20%)
Service selector matching
# Pods must have labels matching the service selector
kubectl label pod mypod app=frontend
# Service selects pods with app=frontend
kubectl expose pod mypod --port=80 --name=frontend-svc
Ingress with path routing
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /api(/|$)(.*)
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 8080
- path: /web(/|$)(.*)
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
NetworkPolicy (egress + ingress)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-isolation
spec:
podSelector:
matchLabels:
app: database
policyTypes: [Ingress, Egress]
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- port: 5432
egress:
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
Study Plan (6–8 Weeks)
| Weeks | Focus |
|---|---|
| 1 | Pods, Deployments, ReplicaSets, Services — kubectl speed drills |
| 2 | ConfigMaps, Secrets, resource limits, namespaces |
| 3 | Multi-container pods, init containers, Jobs, CronJobs |
| 4 | Probes, rolling updates, Helm basics |
| 5 | Security contexts, ServiceAccounts, NetworkPolicy |
| 6 | Ingress, PVC, persistent storage, Kustomize |
| 7–8 | Timed mock exams (killer.sh) + speed practice |
Key Resources
| Resource | Notes |
|---|---|
| killer.sh | Included with purchase; do it multiple times |
| KodeKloud CKAD | Best hands-on practice platform |
| Mumshad Mannambeth (Udemy) | Most popular CKAD course |
| CKAD exercises on GitHub | dgkanatsios/CKAD-exercises — free practice questions |
