CKA — Cluster Architecture Lab
Lab Overview
In this hands-on lab, you will explore the Kubernetes cluster architecture by inspecting control plane components, worker node components, static Pods, and DNS resolution.
Prerequisites: A working Kubernetes cluster (Minikube, kind, or kubeadm).
Task 1: Explore Control Plane Components
# List all Pods in kube-system namespace
kubectl get pods -n kube-system
# Expected output includes:
# coredns-*
# etcd-*
# kube-apiserver-*
# kube-controller-manager-*
# kube-proxy-*
# kube-scheduler-*
# Identify which node each control plane component runs on
kubectl get pods -n kube-system -o wide
# Describe the API server Pod
kubectl describe pod -n kube-system -l component=kube-apiserver
Task 2: Inspect Node Components
# List all nodes with their status
kubectl get nodes -o wide
# Describe a node to see its conditions, capacity, and allocatable resources
kubectl describe node <node-name>
# Check kubelet status (run on the node via SSH or if using single-node cluster)
systemctl status kubelet
# View kubelet configuration
cat /var/lib/kubelet/config.yaml
# Check container runtime
crictl info
Task 3: Inspect Static Pod Manifests
# List static Pod manifests
ls /etc/kubernetes/manifests/
# View the API server manifest
cat /etc/kubernetes/manifests/kube-apiserver.yaml | head -30
# Verify these match the running static Pods
kubectl get pods -n kube-system -l component=kube-apiserver -o yaml | grep -A1 "ownerReferences"
Task 4: Create a Static Pod
# Create a static Pod by placing a manifest in the static Pod directory
sudo tee /etc/kubernetes/manifests/lab-static.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: lab-static
labels:
app: lab-static
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
EOF
# Verify the static Pod was created
kubectl get pods -A | grep lab-static
# Expected: lab-static-<node-name> 1/1 Running
# Try to delete it via kubectl
kubectl delete pod lab-static-<node-name>
# It will be recreated immediately by kubelet
# Clean up: remove the manifest file
sudo rm /etc/kubernetes/manifests/lab-static.yaml
Task 5: Test DNS Resolution
# Create a test Service
kubectl create deployment web --image=nginx --replicas=2
kubectl expose deployment web --port=80
# Test DNS from a debug Pod
kubectl run dns-test --image=busybox:1.36 --rm -it --restart=Never -- nslookup web.default.svc.cluster.local
# Expected output:
# Server: 10.96.0.10
# Address: 10.96.0.10:53
# Name: web.default.svc.cluster.local
# Address: 10.96.x.x
# Test short name resolution (same namespace)
kubectl run dns-test2 --image=busybox:1.36 --rm -it --restart=Never -- nslookup web
# Clean up
kubectl delete deployment web
kubectl delete svc web
Task 6: Check Cluster Health
# API server health
kubectl get --raw /healthz
# Component status (deprecated but still works)
kubectl get componentstatuses
# Check all nodes are Ready
kubectl get nodes
# All should show STATUS: Ready
# Check for any failing Pods in kube-system
kubectl get pods -n kube-system
# All should be Running
Practice Questions
Q1: How many control plane components run as static Pods in a default kubeadm cluster? Name them.
Show Answer
Four control plane components run as static Pods:
- kube-apiserver
- etcd
- kube-scheduler
- kube-controller-manager
Their manifests are in /etc/kubernetes/manifests/.
Q2: Where does the kubelet look for static Pod manifests? How can you find this path?
Show Answer
The kubelet looks at the path configured by staticPodPath in its configuration:
cat /var/lib/kubelet/config.yaml | grep staticPodPath
# staticPodPath: /etc/kubernetes/manifests
The default path is /etc/kubernetes/manifests/.
Q3: A kube-apiserver static Pod is not starting. kubectl is not responding. How do you troubleshoot?
Show Answer
Since kubectl depends on the API server, you need to use node-level tools:
# 1. Check kubelet logs for errors
journalctl -u kubelet -f | grep -i error
# 2. Check the manifest for syntax errors
cat /etc/kubernetes/manifests/kube-apiserver.yaml
# 3. Check container runtime directly
crictl ps -a | grep kube-apiserver
crictl logs <container-id>
# 4. Check if the manifest file exists
ls -la /etc/kubernetes/manifests/kube-apiserver.yaml
Common causes: YAML syntax error, wrong certificate paths, port conflict, insufficient resources.
Q4: Write the command to test DNS resolution for a Service named db-svc in the production namespace.
Show Answer
kubectl run dns-test --image=busybox:1.36 --rm -it --restart=Never -- nslookup db-svc.production.svc.cluster.local
Or from within the same namespace:
kubectl run dns-test -n production --image=busybox:1.36 --rm -it --restart=Never -- nslookup db-svc
Q5: What is the difference between kube-proxy and kubelet? How does each run on a node?
Show Answer
| Aspect | kubelet | kube-proxy |
|---|---|---|
| Purpose | Ensures Pods are running on the node | Maintains network rules for Service connectivity |
| Runs as | systemd service | DaemonSet (Pod in kube-system) |
| Managed by | Operating system (systemd) | Kubernetes (DaemonSet controller) |
| Restart | systemctl restart kubelet |
kubectl rollout restart daemonset kube-proxy -n kube-system |
| Logs | journalctl -u kubelet |
kubectl logs -n kube-system -l k8s-app=kube-proxy |
Key difference: kubelet is the only component that runs as a system service. All other components run as Pods (kube-proxy as a DaemonSet, control plane as static Pods).