CKAD Fact Sheet - Certified Kubernetes Application Developer¶
Exam Overview¶
Exam Code: CKAD Duration: 2 hours Format: Performance-based, hands-on terminal Passing Score: 66% Cost: $395 USD (includes one free retake) Delivery: PSI online proctoring Validity: 3 years Kubernetes Docs Access: Allowed during the exam
π Official CKAD Page - Linux Foundation CKAD certification page π CKAD Exam Curriculum - Official exam curriculum on GitHub π CNCF Certification FAQ - Frequently asked questions about the exam π Candidate Handbook - Exam policies and procedures π Exam Tips from CNCF - Official tips for the exam environment
Target Audience¶
The CKAD is designed for Kubernetes application developers who: - Build, configure, and deploy applications on Kubernetes - Understand core Kubernetes concepts and workload resources - Work with container images and multi-container Pods - Manage application configuration, storage, and networking - Implement observability and debugging strategies
This certification does not focus on cluster administration tasks (that is the CKA). The CKAD is specifically about deploying and managing applications on an existing Kubernetes cluster.
Exam Domain Breakdown¶
| Domain | Weight | Focus Areas |
|---|---|---|
| Application Design and Build | 20% | Pods, multi-container patterns, Jobs, CronJobs, volumes |
| Application Deployment | 20% | Deployments, rolling updates, Helm, Kustomize |
| Application Observability and Maintenance | 15% | Probes, logging, debugging, monitoring |
| Application Environment, Configuration and Security | 25% | ConfigMaps, Secrets, SecurityContexts, RBAC, quotas |
| Services and Networking | 20% | Services, Ingress, NetworkPolicies, DNS |
Domain 1: Application Design and Build (20%)¶
Pod Design and Multi-Container Patterns¶
- π Pods Overview - Core Pod concepts and lifecycle
- π Pod Lifecycle - Pod phases and container states
- π Init Containers - Containers that run before app containers
- π Sidecar Containers - Native sidecar container support
- π Container Lifecycle Hooks - PostStart and PreStop hooks
- π Container Environment Variables - Environment variable sources
Multi-Container Pod Patterns: - Sidecar: Extends the main container (e.g., log shipper, config reloader, proxy). Runs alongside the main container for the entire Pod lifecycle. - Init Container: Runs to completion before the main container starts. Used for setup tasks like waiting for a service, populating volumes, or running migrations. - Ambassador: Proxy container that handles outbound connections. The main container connects to localhost and the ambassador routes to the appropriate external service. - Adapter: Normalizes or transforms the main container's output (e.g., reformatting logs for a centralized system).
Container Images¶
- π Images Overview - Container image concepts
- π Image Pull Policy - Always, IfNotPresent, Never
- π Private Registry Authentication - Using imagePullSecrets
Key Concepts: - Image naming: registry/repository:tag (e.g., docker.io/library/nginx:1.25) - Default pull policy: IfNotPresent for tagged images, Always for :latest - Use specific image tags in production, never rely on :latest - ImagePullSecrets reference a Secret with registry credentials
Jobs and CronJobs¶
- π Jobs - Run-to-completion workloads
- π CronJobs - Scheduled Jobs
- π Automatic Cleanup for Finished Jobs - TTL controller
Job Configuration: - completions: Number of times the Job should complete successfully - parallelism: Number of Pods running concurrently - backoffLimit: Number of retries before marking the Job as failed - activeDeadlineSeconds: Maximum time a Job can run - restartPolicy: Must be Never or OnFailure (not Always)
CronJob Configuration: - schedule: Cron expression (e.g., "*/5 * * * *" for every 5 minutes) - concurrencyPolicy: Allow, Forbid, or Replace - startingDeadlineSeconds: Deadline for starting a Job if the schedule is missed - successfulJobsHistoryLimit: Number of successful Jobs to retain (default 3) - failedJobsHistoryLimit: Number of failed Jobs to retain (default 1)
Persistent and Ephemeral Volumes¶
- π Volumes - Volume types and usage
- π Persistent Volumes - PV and PVC lifecycle
- π Storage Classes - Dynamic provisioning
- π Ephemeral Volumes - Temporary storage
- π Projected Volumes - Combining multiple sources
Volume Types to Know: - emptyDir: Temporary directory, exists for the life of the Pod - hostPath: Mounts a file or directory from the node (use carefully) - persistentVolumeClaim: References a PVC for persistent storage - configMap / secret: Mount ConfigMap or Secret data as files - projected: Combines multiple volume sources into a single directory
PVC Access Modes: - ReadWriteOnce (RWO): Mounted as read-write by a single node - ReadOnlyMany (ROX): Mounted as read-only by many nodes - ReadWriteMany (RWX): Mounted as read-write by many nodes - ReadWriteOncePod (RWOP): Mounted as read-write by a single Pod
Domain 2: Application Deployment (20%)¶
Deployments and Rolling Updates¶
- π Deployments - Declarative application management
- π Rolling Update Strategy - Zero-downtime updates
- π Managing Resources - Deployment management patterns
- π Scaling a Deployment - Horizontal scaling
Rolling Update Parameters: - maxUnavailable: Max Pods that can be unavailable during update (default 25%) - maxSurge: Max Pods that can be created above desired count (default 25%) - minReadySeconds: Minimum seconds a Pod must be ready before considered available - revisionHistoryLimit: Number of old ReplicaSets to retain (default 10)
Rollback Commands:
kubectl rollout status deployment/myapp
kubectl rollout history deployment/myapp
kubectl rollout undo deployment/myapp
kubectl rollout undo deployment/myapp --to-revision=2
kubectl rollout pause deployment/myapp
kubectl rollout resume deployment/myapp
Deployment Strategies¶
- π Canary Deployments - Gradual traffic shifting
Blue-Green Deployment: 1. Deploy the new version as a separate Deployment with different labels 2. Verify the new version is healthy 3. Update the Service selector to point to the new version 4. Keep the old version running temporarily for quick rollback
Canary Deployment: 1. Create a small Deployment of the new version alongside the existing one 2. Both Deployments share the same label so the Service routes to both 3. Gradually scale up the canary and scale down the old version 4. Monitor for errors before completing the rollout
Helm Package Manager¶
- π Helm Documentation - Official Helm docs
- π Helm Quickstart - Getting started with Helm
- π Helm Charts - Chart structure and development
Essential Helm Commands:
# Add a chart repository
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# Search for charts
helm search repo nginx
helm search hub wordpress
# Install a chart
helm install my-release bitnami/nginx
helm install my-release bitnami/nginx --set replicaCount=3
helm install my-release bitnami/nginx -f values.yaml
# List releases
helm list
helm list -n my-namespace
# Upgrade a release
helm upgrade my-release bitnami/nginx --set replicaCount=5
# Rollback a release
helm rollback my-release 1
# Uninstall a release
helm uninstall my-release
# Show chart information
helm show values bitnami/nginx
helm show chart bitnami/nginx
Kustomize¶
- π Kustomize Documentation - Managing objects with Kustomize
- π Kustomize Feature List - Available features
Key Kustomize Features: - Generates ConfigMaps and Secrets from files or literals - Applies common labels, annotations, and namespace - Patches resources with strategic merge patches or JSON patches - Builds and applies with kubectl apply -k ./
# kustomization.yaml example
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
namespace: production
commonLabels:
app: myapp
env: production
configMapGenerator:
- name: app-config
literals:
- DB_HOST=db.production.svc
- LOG_LEVEL=info
Domain 3: Application Observability and Maintenance (15%)¶
Probes and Health Checks¶
- π Configure Liveness, Readiness and Startup Probes - Detailed probe configuration
- π Pod Lifecycle - Container Probes - Probe concepts
Probe Types: | Probe | Purpose | Failure Action | |-------|---------|---------------| | Liveness | Is the container running correctly? | Restart the container | | Readiness | Is the container ready to serve traffic? | Remove from Service endpoints | | Startup | Has the application finished starting? | Restart (disables liveness/readiness until success) |
Probe Mechanisms: - httpGet: HTTP GET request - success is 200-399 status code - tcpSocket: TCP connection attempt - success if connection established - exec: Execute a command - success if exit code is 0 - grpc: gRPC health check - success if status is SERVING
Probe Parameters: - initialDelaySeconds: Seconds before first probe (default 0) - periodSeconds: How often to perform the probe (default 10) - timeoutSeconds: Seconds after which probe times out (default 1) - successThreshold: Consecutive successes needed (default 1) - failureThreshold: Consecutive failures to trigger action (default 3)
Logging and Monitoring¶
- π Logging Architecture - Kubernetes logging concepts
- π Monitoring Resource Usage - Resource monitoring
- π Tools for Monitoring Resources - Metrics pipeline
Key Commands:
# View container logs
kubectl logs <pod-name>
kubectl logs <pod-name> -c <container-name> # specific container
kubectl logs <pod-name> --previous # previous instance
kubectl logs <pod-name> -f # stream logs
kubectl logs <pod-name> --tail=100 # last 100 lines
kubectl logs <pod-name> --since=1h # last hour
# Resource usage
kubectl top pods
kubectl top pods -n <namespace>
kubectl top nodes
kubectl top pod <pod-name> --containers
Debugging Applications¶
- π Debug Pods - Troubleshooting Pod issues
- π Debug Services - Troubleshooting Service issues
- π Debug Running Pods - Inspecting running containers
- π Get a Shell to a Running Container - Exec into containers
- π Troubleshooting - General troubleshooting guide
Debugging Workflow: 1. kubectl get pods - Check Pod status 2. kubectl describe pod <name> - Check events and conditions 3. kubectl logs <name> - Check application logs 4. kubectl exec -it <name> -- /bin/sh - Interactive shell 5. kubectl get events --sort-by=.metadata.creationTimestamp - Cluster events
API Deprecations¶
- π Kubernetes Deprecation Policy - API deprecation rules
- π Deprecated API Migration Guide - Migration paths
Key Points: - API versions progress: v1alpha1 -> v1beta1 -> v1 - Deprecated APIs are supported for at least the deprecation period before removal - Use kubectl convert or update manifests manually when APIs change - Check kubectl api-resources and kubectl api-versions for available APIs
Domain 4: Application Environment, Configuration and Security (25%)¶
ConfigMaps¶
- π ConfigMaps - ConfigMap concepts
- π Configure a Pod to Use a ConfigMap - Consuming ConfigMaps
Creation Methods:
kubectl create configmap my-config --from-literal=key1=value1 --from-literal=key2=value2
kubectl create configmap my-config --from-file=config.properties
kubectl create configmap my-config --from-env-file=config.env
Consumption Methods: - Environment variables: envFrom or individual env with configMapKeyRef - Volume mounts: Mount as files in a directory - Command arguments: Reference in container command/args
Secrets¶
- π Secrets - Secret concepts and types
- π Managing Secrets - Creating Secrets with kubectl
- π Using Secrets - Consuming Secrets in Pods
Secret Types: - Opaque: Generic key-value pairs (default) - kubernetes.io/dockerconfigjson: Docker registry credentials - kubernetes.io/tls: TLS certificate and key - kubernetes.io/basic-auth: Basic authentication credentials - kubernetes.io/service-account-token: ServiceAccount token
Creation:
kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=secret123
kubectl create secret docker-registry my-reg-secret --docker-server=registry.example.com --docker-username=user --docker-password=pass
kubectl create secret tls my-tls --cert=cert.pem --key=key.pem
SecurityContexts¶
- π Configure a Security Context for a Pod or Container - SecurityContext configuration
- π Pod Security Standards - Privileged, Baseline, Restricted
Common SecurityContext Settings:
securityContext:
runAsUser: 1000
runAsGroup: 3000
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
ServiceAccounts¶
- π Service Accounts - ServiceAccount concepts
- π Configure Service Accounts for Pods - Using ServiceAccounts
- π Managing Service Accounts - Administration
Key Points: - Every namespace has a default ServiceAccount - Pods use the default ServiceAccount unless specified otherwise - Assign specific ServiceAccounts for fine-grained access control - ServiceAccount tokens are automatically mounted (can be disabled with automountServiceAccountToken: false)
ResourceQuotas and LimitRanges¶
- π Resource Quotas - Namespace-level resource constraints
- π Limit Ranges - Default and max/min resource constraints
- π Manage Resources - Container resource management
ResourceQuota: Limits total resource consumption per namespace (CPU, memory, number of objects) LimitRange: Sets default, min, and max resource constraints per Pod/container in a namespace
Admission Controllers¶
- π Admission Controllers - What they are and how they work
- π Dynamic Admission Control - Webhooks
Key Admission Controllers: - NamespaceLifecycle: Prevents creation in non-existent namespaces - LimitRanger: Enforces LimitRange constraints - ResourceQuota: Enforces ResourceQuota constraints - ServiceAccount: Automates ServiceAccount assignment - PodSecurity: Enforces Pod Security Standards
Custom Resources and Operators¶
- π Custom Resources - Extending the Kubernetes API
- π Custom Resource Definitions - Creating CRDs
- π Operator Pattern - Automated application management
Domain 5: Services and Networking (20%)¶
Services¶
- π Service - Service concepts and types
- π Connecting Applications with Services - Practical Service usage
- π Use a Service to Access an Application in a Cluster - Service tutorial
Service Types: | Type | Description | Use Case | |------|-------------|----------| | ClusterIP | Internal cluster IP (default) | Internal communication between services | | NodePort | Exposes on each node's IP at a static port (30000-32767) | Development and testing | | LoadBalancer | Provisions external load balancer (cloud provider) | Production external access | | ExternalName | Maps to a DNS name (CNAME) | Referencing external services |
Imperative Creation:
kubectl expose deployment myapp --port=80 --target-port=8080 --type=ClusterIP
kubectl expose deployment myapp --port=80 --target-port=8080 --type=NodePort
kubectl expose pod mypod --port=80 --target-port=8080 --name=my-service
Ingress¶
- π Ingress - Ingress concepts and configuration
- π Ingress Controllers - Available controllers
- π Set up Ingress on Minikube - Practical Ingress tutorial
Ingress Features: - Host-based routing (route by domain name) - Path-based routing (route by URL path) - TLS termination - Default backend for unmatched requests - Requires an Ingress controller to be installed in the cluster
Example Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
tls:
- hosts:
- myapp.example.com
secretName: tls-secret
Network Policies¶
- π Network Policies - Traffic control between Pods
- π Declare Network Policy - Creating NetworkPolicies
Key Concepts: - By default, all Pods can communicate with all other Pods - A NetworkPolicy selects Pods using podSelector and defines allowed ingress and egress rules - Once a Pod is selected by any NetworkPolicy, all traffic not explicitly allowed is denied - Rules can select by: podSelector, namespaceSelector, ipBlock (CIDR) - Requires a CNI plugin that supports NetworkPolicies (Calico, Cilium, Weave Net)
Example - Allow only specific Pods:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
namespace: default
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
DNS for Services and Pods¶
- π DNS for Services and Pods - Kubernetes DNS
DNS Naming: - Services: <service-name>.<namespace>.svc.cluster.local - Pods: <pod-ip-dashed>.<namespace>.pod.cluster.local - Within the same namespace, use just the service name: my-service - Across namespaces, use: my-service.other-namespace
Exam Environment Tips¶
Tools Available in the Exam¶
kubectlwith bash/zsh autocompletionvimandnanofor text editingtmuxfor terminal multiplexingcurlandwgetfor HTTP requestsjqfor JSON processing- Access to kubernetes.io/docs, kubernetes.io/blog, and github.com/kubernetes
Time Management¶
- 2 hours for approximately 15-20 tasks
- Average 6-8 minutes per task
- Flag difficult tasks and come back to them
- Easy tasks first to bank points quickly
- Verify your work before moving on - points for partial completion are possible
Critical Shortcuts¶
# Set up aliases at the start of the exam
alias k=kubectl
export do="--dry-run=client -o yaml"
# Quick resource creation
k run pod1 --image=nginx $do > pod1.yaml
k create deploy d1 --image=nginx --replicas=3 $do > d1.yaml
# Context switching (exam uses multiple clusters)
kubectl config use-context <context-name>
kubectl config get-contexts
Common Pitfalls¶
- Forgetting to switch context between tasks
- Not checking the correct namespace
- YAML indentation errors
- Forgetting to verify the resource was created correctly
- Spending too long on a single question
- Not reading the full question before starting