CKA (Certified Kubernetes Administrator) Study Guide
Part 1: Core Components & Scheduling
1. ETCD
Default Port: 2379
Version Differences
ETCD v2 Commands:
etcdctl set key1 value1
etcdctl get key1
ETCD v3 Commands:
export ETCDCTL_API=3
etcdctl put key1 value1
etcdctl get key1
Accessing ETCD in Kubernetes
kubectl exec etcd-controlplane -n kube-system -- sh -c \
"ETCDCTL_API=3 etcdctl get / --prefix --keys-only --limit=10 \
--cacert /etc/kubernetes/pki/etcd/ca.crt \
--cert /etc/kubernetes/pki/etcd/server.crt \
--key /etc/kubernetes/pki/etcd/server.key"
2. Pods & Deployments
Imperative vs. Declarative Commands
Generate YAML without Creating Resource:
kubectl run nginx --image=nginx --dry-run=client -o yaml
Create Deployment:
kubectl create deployment nginx --image=nginx
Generate Deployment YAML:
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml
Scale Deployment:
kubectl scale deployment nginx --replicas=4
Edit Running ReplicaSet:
kubectl edit replicaset <rs-name>
ReplicaSet vs. ReplicationController
Key Difference: ReplicaSet supports selector matching (matchLabels
), while ReplicationController does not.
3. Services
ClusterIP Service
kubectl expose pod redis --port=6379 --name redis-service --dry-run=client -o yaml
NodePort Service
kubectl expose pod nginx --type=NodePort --port=80 --name=nginx-service --dry-run=client -o yaml
Imperative Service Creation
kubectl create service nodeport nginx --tcp=80:80 --node-port=30080 --dry-run=client -o yaml
4. Scheduling & Affinity
Manual Scheduling
Method 1: Use nodeName
in Pod definition
spec:
nodeName: node01
containers:
- name: nginx
image: nginx
Method 2: Use pod-binding-definition.yaml
Labels & Selectors
Get Pods with Multiple Selectors:
kubectl get pods --selector env=dev,bu=finance
Taints & Tolerations
Taint a Node:
kubectl taint nodes node1 key=value:NoSchedule
Pod Tolerations Example:
tolerations:
- key: "spray"
value: "mortein"
effect: "NoSchedule"
operator: "Equal"
Node Affinity
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: color
operator: In
values:
- blue
Affinity Types:
-
requiredDuringSchedulingIgnoredDuringExecution
- Hard requirement -
preferredDuringSchedulingIgnoredDuringExecution
- Soft requirement
5. Resource Management
Requests & Limits
Pod Definition Example:
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "1Gi"
LimitRange (CPU & Memory Constraints)
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-limit-range
spec:
limits:
- default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "256Mi"
max:
cpu: "1"
memory: "1Gi"
min:
cpu: "100m"
memory: "128Mi"
type: Container
Resource Quotas
Restrict Namespace Resource Usage:
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu-quota
namespace: dev
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
pods: "10"
6. DaemonSets & Static Pods
DaemonSet Example
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: kube-system
spec:
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
containers:
- name: fluentd
image: fluentd
Use Case: Deploy one pod per node (monitoring agents, log collectors, etc.)
Static Pods
Location: /etc/kubernetes/manifests/
Example (busybox.yaml):
apiVersion: v1
kind: Pod
metadata:
name: static-busybox
spec:
containers:
- name: busybox
image: busybox
command: ["sleep", "1000"]
Key Characteristics:
- Managed directly by kubelet on a specific node
- Not managed by kube-apiserver
- Mirror pods appear in kubectl output
- Control plane components often run as static pods
7. Custom Schedulers
Deploy Custom Scheduler
apiVersion: v1
kind: Pod
metadata:
name: my-scheduler
namespace: kube-system
spec:
containers:
- command:
- /usr/local/bin/kube-scheduler
- --config=/etc/kubernetes/my-scheduler-config.yaml
image: k8s.gcr.io/kube-scheduler:v1.22.0
name: kube-second-scheduler
Use Custom Scheduler in Pod
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
schedulerName: my-scheduler
containers:
- name: nginx
image: nginx
8. Admission Controllers & Webhooks
Check Enabled Admission Controllers
kubectl exec kube-apiserver-controlplane -n kube-system -- \
kube-apiserver -h | grep enable-admission-plugins
Mutating Webhook Example
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: demo-webhook
webhooks:
- name: webhook-server.webhook-demo.svc
clientConfig:
service:
name: webhook-server
namespace: webhook-demo
path: "/mutate"
caBundle: <base64-encoded-ca-cert>
rules:
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
Common Admission Controllers:
-
NamespaceLifecycle
- Prevents operations in terminating namespaces -
LimitRanger
- Enforces LimitRange constraints -
ResourceQuota
- Enforces resource quotas -
PodSecurityPolicy
- Controls pod security settings -
DefaultStorageClass
- Sets default storage class
Part 2: Operations & Advanced Topics
1. Monitoring & Metrics
Metrics Server
In-memory monitoring solution for CPU/Memory metrics.
Deploy Metrics Server:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Commands:
kubectl top nodes # Show node resource usage
kubectl top pods # Show pod resource usage
kubectl top pods -n kube-system --sort-by=memory
kubectl top pods -n kube-system --sort-by=cpu
Logging
# View logs
kubectl logs <pod-name>
# Stream logs (multi-container pods)
kubectl logs -f <pod-name> -c <container>
# View previous container logs
kubectl logs <pod-name> --previous
# Tail last N lines
kubectl logs <pod-name> --tail=50
2. Deployment Strategies
Strategy Types
RollingUpdate (Default):
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25% # Extra pods allowed during update
maxUnavailable: 25% # Max unavailable pods during update
Recreate:
spec:
strategy:
type: Recreate
Image Updates
# Update image
kubectl set image deployment/myapp nginx=nginx:1.25
# Manual edit
kubectl edit deployment/myapp
# Rollback to previous version
kubectl rollout undo deployment/myapp
# Check rollout status
kubectl rollout status deployment/myapp
# View rollout history
kubectl rollout history deployment/myapp
3. Container Configuration
Command vs Args
containers:
- name: ubuntu
image: ubuntu
command: ["sleep"] # Overrides ENTRYPOINT
args: ["5000"] # Overrides CMD
Equivalents:
-
command
= DockerfileENTRYPOINT
-
args
= DockerfileCMD
4. ConfigMaps & Secrets
ConfigMaps
Imperative Creation:
# From literals
kubectl create configmap app-config \
--from-literal=APP_COLOR=blue \
--from-literal=APP_MODE=prod
# From file
kubectl create configmap app-config \
--from-file=config.properties
Declarative Usage:
# As environment variable
env:
- name: APP_COLOR
valueFrom:
configMapKeyRef:
name: app-config
key: APP_COLOR
# As volume
volumes:
- name: config-volume
configMap:
name: app-config
Secrets
Create Secret:
kubectl create secret generic db-secret \
--from-literal=DB_HOST=mysql \
--from-literal=DB_PASSWORD=admin123
Base64 Encoding:
echo -n "secret" | base64 # Encode: c2VjcmV0
echo "c2VjcmV0" | base64 -d # Decode: secret
Mounting Secrets:
# As environment variables
envFrom:
- secretRef:
name: db-secret
# As volume
volumes:
- name: secret-volume
secret:
secretName: db-secret
5. Multi-Container Pods
Sidecar Pattern
containers:
- name: app
image: nginx
volumeMounts:
- name: log-volume
mountPath: /var/log/nginx
- name: log-collector
image: fluentd
volumeMounts:
- name: log-volume
mountPath: /var/log/nginx
volumes:
- name: log-volume
emptyDir: {}
Init Containers
initContainers:
- name: init-db
image: busybox
command: ['sh', '-c', 'until nslookup db-service; do echo waiting for db; sleep 2; done']
containers:
- name: app
image: nginx
Key Characteristics:
- Run before app containers
- Run sequentially (one at a time)
- Must complete successfully before app containers start
6. Autoscaling
Horizontal Pod Autoscaler (HPA)
Imperative:
kubectl autoscale deployment/myapp --cpu-percent=50 --min=2 --max=5
Declarative:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
Vertical Pod Autoscaler (VPA)
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: myapp-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: myapp
updatePolicy:
updateMode: "Auto" # Options: Off, Initial, Recreate, Auto
Key Differences
Feature | HPA | VPA |
---|---|---|
Scales | Pod count (horizontal) | Resource requests/limits (vertical) |
Triggers | CPU/Memory metrics | Resource utilization over time |
Use Case | Handle variable load | Optimize resource allocation |
Requires Restart | No | Yes (for most modes) |
7. Cluster Maintenance
Node Operations
Drain Node (Safe maintenance):
kubectl drain node01 --ignore-daemonsets --delete-emptydir-data
Cordon Node (Mark unschedulable):
kubectl cordon node01
Uncordon Node (Allow scheduling):
kubectl uncordon node01
Upgrade Workflow
1. Upgrade Control Plane:
# Update kubeadm
apt-get update
apt-get install kubeadm=1.28.0-00
# Check upgrade plan
kubeadm upgrade plan
# Apply upgrade
kubeadm upgrade apply v1.28.0
# Upgrade kubelet and kubectl
apt-get install kubelet=1.28.0-00 kubectl=1.28.0-00
systemctl daemon-reload
systemctl restart kubelet
2. Upgrade Worker Nodes:
# On worker node
kubeadm upgrade node
# Upgrade kubelet
apt-get install kubelet=1.28.0-00
systemctl daemon-reload
systemctl restart kubelet
Upgrade Process:
- Drain the node
- Upgrade kubeadm
- Run
kubeadm upgrade
- Upgrade kubelet and kubectl
- Restart kubelet
- Uncordon the node
Quick Reference
Essential Commands
# Cluster Information
kubectl cluster-info
kubectl get nodes
kubectl get componentstatuses
# Resource Management
kubectl get all -A
kubectl get pods -o wide
kubectl describe pod <pod-name>
kubectl delete pod <pod-name> --grace-period=0 --force
# Configuration
kubectl apply -f <file.yaml>
kubectl delete -f <file.yaml>
kubectl edit <resource> <name>
# Debugging
kubectl logs <pod-name>
kubectl exec -it <pod-name> -- /bin/bash
kubectl port-forward <pod-name> 8080:80
# Performance
kubectl top nodes
kubectl top pods
YAML Templates
Basic Pod:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
Basic Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: nginx
image: nginx:1.21
Key Takeaways
Part 1
- ETCD v3 is the current standard
- ReplicaSets are preferred over ReplicationControllers due to selector flexibility
- Taints/Tolerations restrict nodes, Node Affinity attracts pods
- Static Pods are managed by kubelet directly, not the API server
- Custom Schedulers allow advanced scheduling logic
- Admission Webhooks enforce policies at resource creation time
Part 2
-
Metrics Server is required for
kubectl top
and HPA functionality - RollingUpdate is the default deployment strategy (25% surge/unavailable)
- ConfigMaps/Secrets can be mounted as environment variables or volumes
- HPA scales pods horizontally based on metrics
- VPA adjusts resource requests/limits vertically
- Always drain nodes before maintenance, uncordon afterward
Exam Tips
-
Use imperative commands with
--dry-run=client -o yaml
to generate YAML templates quickly -
Practice kubectl shortcuts:
po
(pods),svc
(services),deploy
(deployments),ns
(namespaces) - Bookmark Kubernetes documentation - you can reference it during the exam
- Master YAML indentation - use 2 spaces, never tabs
- Know the exam environment - Practice with vim/nano and tmux
- Time management - Flag difficult questions and return later
- Verify your changes - Always check resources after creating/modifying them
Document Version: 1.0
Last Updated: October 2025
Mohamed Nasser Mohamed
https://www.linkedin.com/in/mohamednasser8/
Top comments (0)