Setting Up Your Kubernetes Lab Environment¶
Master the art of building Kubernetes clusters for CKA exam preparation. Learn kubeadm for production-grade setups, kind for rapid testing, and essential kubectl configuration for efficient cluster management.
Overview¶
A proper lab environment is critical for CKA exam success. The exam uses kubeadm-based clusters, making hands-on practice with real cluster setup essential. This guide covers four primary methods for building Kubernetes environments:
- kubeadm - Production-grade multi-node clusters (exam environment)
- kind - Fast container-based clusters for rapid iteration
- Minikube - Single-node local development with rich addons
- kubectl - Essential CLI tool configuration and management
CKA Exam Domain: Cluster Architecture, Installation & Configuration (25%)
Key Finding: While the CKA exam uses kubeadm clusters, kind offers the fastest iteration for practice exercises. A combination of both provides optimal preparation.
Lab Environment Decision Tree¶
Choosing the right lab setup depends on your immediate needs and learning phase.
flowchart TD
Start([Need Kubernetes Lab?]) --> Purpose{What's the purpose?}
Purpose -->|CKA Exam Prep| Exam{Practice<br/>or<br/>Full Simulation?}
Purpose -->|Local Development| Dev{Single or<br/>Multi-Node?}
Purpose -->|CI/CD Testing| CICD[Use kind<br/>Fast iteration]
Exam -->|Quick Practice| kind_exam[Use kind<br/>30-second clusters]
Exam -->|Full Simulation| kubeadm_exam[Use kubeadm<br/>Production-like setup]
Dev -->|Single Node<br/>+ Addons| Minikube[Use Minikube<br/>Rich ecosystem]
Dev -->|Multi-Node<br/>Testing| kind_dev[Use kind<br/>Config-based]
Dev -->|Production Sim| kubeadm_dev[Use kubeadm<br/>Real cluster]
CICD --> fast{Speed<br/>Important?}
fast -->|Yes| kind_fast[Use kind<br/>Container-based]
fast -->|No| minikube_ci[Use Minikube<br/>More features]
style kubeadm_exam fill:#ff9999
style kubeadm_dev fill:#ff9999
style Minikube fill:#99ccff
style kind_exam fill:#99ff99
style kind_dev fill:#99ff99
style kind_fast fill:#99ff99
style CICD fill:#99ff99
kubeadm: Production-Grade Cluster Setup¶
kubeadm is the official Kubernetes tool for bootstrapping production-grade clusters. This is the tool used in the CKA exam environment.
Prerequisites¶
System Requirements (Per Node): - Ubuntu 20.04/22.04/24.04 or equivalent Debian-based system - 2+ CPUs - 2GB+ RAM - Network connectivity between all nodes - Unique hostname, MAC address, and product_uuid per node - Swap disabled (critical requirement)
Complete Installation Process¶
Step 1: Disable Swap (CRITICAL)¶
Kubernetes scheduler relies on accurate resource allocation. Swap can cause unpredictable behavior.
# Temporary disable
sudo swapoff -a
# Permanent disable - comment out swap in /etc/fstab
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# Verify (swap line should show 0)
free -h
Exam Alert
The CKA exam expects swap to be disabled. Forgetting this step causes kubeadm init to fail.
Step 2: Install Container Runtime (containerd)¶
# Install containerd
sudo apt-get update
sudo apt-get install -y containerd
# Configure containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# Restart and enable containerd
sudo systemctl restart containerd
sudo systemctl enable containerd
# Verify containerd is running
systemctl status containerd
Step 3: Install kubeadm, kubelet, kubectl¶
# Update package index and install prerequisites
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
# Add Kubernetes GPG key (NEW REPOSITORY)
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key | \
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# Add Kubernetes repository
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /' | \
sudo tee /etc/apt/sources.list.d/kubernetes.list
# Install Kubernetes components
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
# Hold packages at current version (prevent auto-upgrade)
sudo apt-mark hold kubelet kubeadm kubectl
# Enable kubelet
sudo systemctl enable --now kubelet
Repository Change
The old repository https://apt.kubernetes.io is deprecated. Always use pkgs.k8s.io for new installations.
Step 4: Initialize Control Plane Node¶
# Basic initialization with pod network CIDR
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
# For HA setup with load balancer
sudo kubeadm init \
--control-plane-endpoint "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" \
--upload-certs \
--pod-network-cidr=10.244.0.0/16
Expected Output:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a Pod network to the cluster.
You can now join any number of machines by running the following on each node:
kubeadm join 192.168.0.200:6443 \
--token 9vr73a.a8uxyaju799qwdjv \
--discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d
Save the join command - you'll need it for worker nodes.
Step 5: Configure kubectl Access¶
# Configure kubectl for regular user
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# Verify cluster access
kubectl cluster-info
kubectl get nodes
Step 6: Install CNI Network Plugin (CRITICAL)¶
Without a CNI plugin, nodes remain in "NotReady" state and pods cannot communicate.
Option A: Calico (Recommended for CKA)
# Install Calico operator
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
# Apply custom resources
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml
# Verify installation (wait for all pods to be Running)
watch kubectl get pods -n calico-system
Option B: Flannel
Option C: Weave Net
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
After CNI installation, verify nodes are Ready:
Step 7: Join Worker Nodes¶
On each worker node (after completing Steps 1-3):
# Use the join command from Step 4 output
sudo kubeadm join 192.168.0.200:6443 \
--token 9vr73a.a8uxyaju799qwdjv \
--discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d
If token expired (tokens are valid for 24 hours):
kubeadm Cluster Architecture¶
graph TB
subgraph "Control Plane Node"
APIServer[API Server<br/>:6443]
Scheduler[Scheduler]
Controller[Controller Manager]
etcd[(etcd<br/>:2379-2380)]
KubeletCP[Kubelet<br/>:10250]
ProxyCP[kube-proxy]
end
subgraph "Worker Node 1"
KubeletW1[Kubelet<br/>:10250]
ProxyW1[kube-proxy]
Pod1[Pod]
Pod2[Pod]
CRI1[containerd]
end
subgraph "Worker Node 2"
KubeletW2[Kubelet<br/>:10250]
ProxyW2[kube-proxy]
Pod3[Pod]
Pod4[Pod]
CRI2[containerd]
end
subgraph "CNI Network Layer"
CNI[Calico/Flannel<br/>10.244.0.0/16]
end
APIServer --> Scheduler
APIServer --> Controller
APIServer --> etcd
APIServer -.->|watches| KubeletCP
APIServer -.->|watches| KubeletW1
APIServer -.->|watches| KubeletW2
KubeletW1 --> CRI1
KubeletW2 --> CRI2
CRI1 --> Pod1
CRI1 --> Pod2
CRI2 --> Pod3
CRI2 --> Pod4
CNI --> Pod1
CNI --> Pod2
CNI --> Pod3
CNI --> Pod4
style APIServer fill:#e1f5ff
style etcd fill:#ffe5e5
style CNI fill:#e8f5e8
Common kubeadm Issues and Solutions¶
Issue 1: "swap is enabled; production deployments should disable swap"¶
Cause: Swap not properly disabled
Solution:
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
sudo reboot
free -h # Verify swap shows 0
Issue 2: "container runtime network not ready: cni config uninitialized"¶
Cause: No CNI plugin installed
Solution:
# Check CNI config directory
ls /etc/cni/net.d/
# If empty, install CNI plugin (Calico/Flannel)
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml
# Verify CNI pods running
kubectl get pods -n calico-system
Issue 3: Port 6443 already in use¶
Cause: Previous kubeadm installation not cleaned up
Solution:
# Reset kubeadm completely
sudo kubeadm reset
# Clean up directories
sudo rm -rf /etc/cni/net.d
sudo rm -rf $HOME/.kube/config
# Try initialization again
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
Issue 4: Worker node join fails¶
Causes: Token expired, network connectivity, firewall rules
Solutions:
# Generate new join command
kubeadm token create --print-join-command
# Check connectivity from worker to control plane
ping <control-plane-ip>
nc -zv <control-plane-ip> 6443
# Required firewall ports:
# Control Plane: 6443, 2379-2380, 10250-10252
# Worker Nodes: 10250, 30000-32767
kubeadm Configuration File Approach¶
For repeatable setups, use configuration files:
# kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.0.200
bindPort: 6443
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
networking:
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/16
kubernetesVersion: v1.34.0
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
# Initialize with config file
sudo kubeadm init --config=kubeadm-config.yaml
# Generate default config template
kubeadm config print init-defaults > kubeadm-config.yaml
kind: Kubernetes in Docker¶
kind runs Kubernetes clusters using Docker containers as "nodes". Excellent for rapid iteration and CKA practice.
Installation¶
Linux/macOS:
# Using Homebrew (macOS)
brew install kind
# Direct binary download (Linux)
curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# Verify installation
kind version
Prerequisites: - Docker installed and running - kubectl installed - 4GB+ RAM allocated to Docker - 2+ CPUs for multi-node clusters
Basic Usage¶
# Create default single-node cluster
kind create cluster
# Create cluster with custom name
kind create cluster --name cka-practice
# List clusters
kind get clusters
# Delete cluster
kind delete cluster --name cka-practice
Multi-Node Cluster Configuration¶
2-Node Cluster (1 Control Plane + 1 Worker):
# kind-2node.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
3-Node Cluster with Port Mapping:
# kind-3node.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30080
hostPort: 8080
protocol: TCP
- role: worker
- role: worker
High Availability Control Plane (3 Control Plane + 3 Worker):
# kind-ha.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker
kind Cluster Lifecycle¶
sequenceDiagram
participant User
participant kind
participant Docker
participant kubectl
User->>kind: kind create cluster --config kind-3node.yaml
kind->>Docker: Pull kindest/node:v1.34.0 image
Docker-->>kind: Image ready
kind->>Docker: Create control-plane container
kind->>Docker: Create worker-1 container
kind->>Docker: Create worker-2 container
Docker-->>kind: 3 containers running
kind->>kind: Bootstrap Kubernetes in containers
kind->>kind: Configure CNI (kindnetd)
kind->>kind: Wait for cluster ready
kind->>kubectl: Update kubeconfig
kind-->>User: Cluster ready (30-60 seconds)
User->>kubectl: kubectl get nodes
kubectl-->>User: 3 nodes Ready
Note over User,kubectl: Practice CKA scenarios
User->>kind: kind delete cluster
kind->>Docker: Remove all containers
Docker-->>kind: Cleanup complete
kind-->>User: Cluster deleted
Load Docker Images into kind¶
For testing custom applications without pushing to registry:
# Build image locally
docker build -t my-app:1.0 .
# Load into kind cluster
kind load docker-image my-app:1.0 --name cka-lab
# Verify image available in cluster
docker exec -it cka-lab-control-plane crictl images | grep my-app
When to Use kind¶
Best For: - CKA rapid practice: Create/destroy clusters in seconds - Multi-node testing: Easy configuration for complex topologies - CI/CD pipelines: Fast, reproducible test environments - Integration testing: Test applications in real cluster - Quick experiments: Try configurations without VM overhead
Not Ideal For: - Learning basics: Minikube has better addon ecosystem - Production simulation: kubeadm provides real multi-machine setup - Resource-constrained systems: Requires Docker overhead
Minikube: Local Development Environment¶
Minikube creates single-node Kubernetes clusters on your local machine. Ideal for learning with rich addon support.
Installation¶
macOS:
Linux:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
minikube version
Driver Options¶
Docker Driver (Recommended):
# Start with Docker driver
minikube start --driver=docker
# Set as default
minikube config set driver docker
QEMU Driver (ARM/M1 Macs):
Resource Configuration¶
# Specify CPUs, memory, disk
minikube start \
--driver=docker \
--cpus=4 \
--memory=8192 \
--disk-size=40g \
--kubernetes-version=v1.34.0
Common Minikube Commands¶
# Start cluster
minikube start
# Stop cluster (preserves state)
minikube stop
# Delete cluster
minikube delete
# Check status
minikube status
# SSH into node
minikube ssh
# Open dashboard
minikube dashboard
# List addons
minikube addons list
# Enable addons
minikube addons enable ingress
minikube addons enable metrics-server
Minikube Addons for CKA Practice¶
# Metrics Server (for kubectl top)
minikube addons enable metrics-server
# Ingress Controller
minikube addons enable ingress
# Storage Provisioner (dynamic PVs)
minikube addons enable storage-provisioner
# Dashboard
minikube addons enable dashboard
kubectl Installation and Configuration¶
kubectl is the Kubernetes command-line tool. Mastery is essential for CKA exam success.
Installation¶
Linux:
# Download latest release
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
# Install
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# Verify
kubectl version --client
macOS:
Version Compatibility¶
kubectl version must be within ±1 minor version of cluster version.
# Check versions
kubectl version --short
# Example compatible versions:
# Cluster: v1.34.0
# kubectl: v1.33.x, v1.34.x, v1.35.x ✅
# kubectl: v1.32.x, v1.36.x ❌
Shell Completion Setup (CRITICAL for Exam Speed)¶
Bash (Linux):
# Install bash-completion package
sudo apt-get install bash-completion
# Add completion to current shell
source <(kubectl completion bash)
# Add to .bashrc for persistence
echo 'source <(kubectl completion bash)' >> ~/.bashrc
# Alias completion (essential for exam)
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -o default -F __start_kubectl k' >> ~/.bashrc
# Reload
source ~/.bashrc
Zsh:
# Add completion to .zshrc
echo 'source <(kubectl completion zsh)' >> ~/.zshrc
# Alias completion
echo 'alias k=kubectl' >> ~/.zshrc
echo 'complete -o default -F __start_kubectl k' >> ~/.zshrc
# Reload
source ~/.zshrc
Exam Tip
Practice using k instead of kubectl extensively. Tab completion saves critical minutes during the exam.
kubeconfig Management¶
kubeconfig files contain cluster connection details. Managing multiple clusters efficiently is essential for the exam.
kubeconfig File Structure¶
apiVersion: v1
kind: Config
current-context: my-cluster
clusters:
- cluster:
certificate-authority-data: <base64-encoded-ca>
server: https://192.168.1.100:6443
name: my-cluster
users:
- name: my-user
user:
client-certificate-data: <base64-encoded-cert>
client-key-data: <base64-encoded-key>
contexts:
- context:
cluster: my-cluster
user: my-user
namespace: default
name: my-cluster-context
Context Management Flow¶
graph TB
subgraph "kubeconfig File"
Clusters[Clusters<br/>- prod-cluster<br/>- dev-cluster<br/>- cka-cluster]
Users[Users<br/>- admin-user<br/>- dev-user<br/>- readonly-user]
Contexts[Contexts<br/>- prod-admin<br/>- dev-user<br/>- cka-practice]
CurrentContext[Current Context:<br/>cka-practice]
end
subgraph "Context: cka-practice"
CKACluster[Cluster: cka-cluster]
CKAUser[User: admin-user]
CKANamespace[Namespace: default]
end
subgraph "Actual Clusters"
ProdCluster[Production<br/>10.0.1.100:6443]
DevCluster[Development<br/>10.0.2.100:6443]
CKAClusterActual[CKA Lab<br/>10.0.3.100:6443]
end
Contexts --> CurrentContext
CurrentContext --> CKACluster
CurrentContext --> CKAUser
CurrentContext --> CKANamespace
CKACluster -.->|kubectl commands| CKAClusterActual
style CurrentContext fill:#ffff99
style CKAClusterActual fill:#99ff99
Essential Context Commands¶
# List all contexts
kubectl config get-contexts
# Show current context
kubectl config current-context
# Switch context
kubectl config use-context cka-practice
# Set default namespace for current context
kubectl config set-context --current --namespace=kube-system
# Create new context
kubectl config set-context dev-user \
--cluster=dev-cluster \
--namespace=development \
--user=dev-user
# Rename context
kubectl config rename-context old-name new-name
# Delete context
kubectl config delete-context old-context
Multiple Cluster Management¶
Strategy 1: Merged Configuration (Recommended for Exam):
# Merge multiple kubeconfig files
export KUBECONFIG=~/.kube/config:~/.kube/dev-config:~/.kube/prod-config
kubectl config view --flatten > ~/.kube/merged-config
# Set as default
export KUBECONFIG=~/.kube/merged-config
# Add to .bashrc for persistence
echo 'export KUBECONFIG=~/.kube/merged-config' >> ~/.bashrc
Strategy 2: Context-Specific Commands:
# Use specific context for single command
kubectl --context=prod-cluster get nodes
# Use specific kubeconfig for single command
kubectl --kubeconfig=~/.kube/prod-config get pods
# Override namespace for single command
kubectl -n kube-system get pods
Security Best Practices¶
# Protect kubeconfig files
chmod 600 ~/.kube/config
chmod 0400 ~/.kube/prod-config # Read-only for production
# Never commit kubeconfig to version control
echo '.kube/' >> ~/.gitignore
Common Exam Tasks¶
Scenario 1: Rapid Cluster Setup for Practice¶
Objective: Create disposable cluster for practice scenario
# Create kind cluster
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
# Verify cluster ready
kubectl get nodes
# Practice exam task
kubectl run nginx --image=nginx
kubectl expose pod nginx --port=80 --type=NodePort
# Clean up when done
kind delete cluster
Time: 30-60 seconds for cluster creation
Scenario 2: Multi-Cluster Context Switching¶
Objective: Practice switching between exam cluster contexts
# Assume exam provides contexts: cluster1-context, cluster2-context
# List available contexts
kubectl config get-contexts
# Switch to cluster1
kubectl config use-context cluster1-context
# Verify current context
kubectl config current-context
# Deploy to cluster1
kubectl run web --image=nginx
# Switch to cluster2
kubectl config use-context cluster2-context
# Deploy to cluster2
kubectl run database --image=postgres
Scenario 3: Troubleshoot CNI Issues¶
Objective: Fix cluster networking
# Check node status
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# node-1 NotReady control-plane 2m v1.34.0
# Check system pods
kubectl -n kube-system get pods
# Verify CNI config exists
kubectl exec -n kube-system <any-pod> -- ls /etc/cni/net.d/
# If empty, install CNI
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml
# Verify nodes transition to Ready
kubectl get nodes --watch
CNI Network Communication¶
Understanding how CNI plugins enable pod-to-pod communication is critical for troubleshooting.
sequenceDiagram
participant Pod1 as Pod 1<br/>10.244.1.5<br/>Node1
participant CNI1 as CNI Plugin<br/>Node1
participant CNI2 as CNI Plugin<br/>Node2
participant Pod2 as Pod 2<br/>10.244.2.8<br/>Node2
Note over Pod1,Pod2: Pod-to-Pod Communication Across Nodes
Pod1->>CNI1: Send packet to 10.244.2.8
CNI1->>CNI1: Check routing table<br/>Pod CIDR 10.244.0.0/16
CNI1->>CNI2: Forward via overlay network<br/>(VXLAN/BGP)
CNI2->>CNI2: Lookup destination pod<br/>10.244.2.8 on Node2
CNI2->>Pod2: Deliver packet
Pod2->>CNI2: Send response
CNI2->>CNI1: Return via overlay
CNI1->>Pod1: Deliver response
Note over CNI1,CNI2: CNI ensures IP reachability<br/>without NodePort/Service
Practice Exercises¶
Exercise 1: Complete kubeadm Cluster Setup (60 minutes)¶
Objective: Build production-like 3-node cluster
Tasks: 1. Prepare 3 VMs (1 control plane, 2 workers) 2. Disable swap on all nodes 3. Install container runtime 4. Install kubeadm, kubelet, kubectl 5. Initialize control plane with Calico pod CIDR 6. Install Calico CNI 7. Join worker nodes 8. Verify all nodes Ready 9. Deploy test workload
Success Criteria: - All 3 nodes show Ready status - CNI pods running in calico-system namespace - Test pod can communicate across nodes
Exercise 2: kind Multi-Node Lab (20 minutes)¶
Objective: Create multi-node cluster for rapid testing
Tasks: 1. Create kind config for 3-node cluster 2. Map NodePort 30000 to localhost:8080 3. Create cluster 4. Deploy nginx with NodePort 30000 5. Access from host browser 6. Test pod scheduling across workers 7. Delete and recreate cluster
Success Criteria: - Cluster creation completes in <60 seconds - Nginx accessible on localhost:8080 - Can repeat cycle 5 times in 10 minutes
Exercise 3: kubeconfig Context Mastery (30 minutes)¶
Objective: Manage multiple clusters efficiently
Tasks: 1. Create 3 different clusters (kubeadm, kind, minikube) 2. Export kubeconfig from each 3. Merge into single kubeconfig 4. Rename contexts meaningfully 5. Set default namespace per context 6. Practice rapid context switching 7. Deploy workload to specific context without switching
Success Criteria: - Switch contexts in <5 seconds - Deploy to specific cluster without errors - Verify deployment in correct cluster
Exercise 4: Shell Completion and Aliases (15 minutes)¶
Objective: Optimize kubectl workflow for exam speed
Tasks: 1. Install bash-completion 2. Configure kubectl completion 3. Test tab completion 4. Create aliases: k, kg, kd, kl 5. Configure alias completion 6. Time yourself: deploy nginx with and without aliases
Success Criteria: - Tab completion works for resources - Aliases reduce command length by 50%+ - Muscle memory for common patterns
Exercise 5: Troubleshooting Simulation (45 minutes)¶
Objective: Diagnose and fix common cluster issues
Tasks: 1. Initialize cluster WITHOUT CNI 2. Observe NotReady nodes 3. Check kubelet logs for errors 4. Identify CNI-related messages 5. Install CNI plugin 6. Verify nodes transition to Ready 7. Test pod communication 8. Break and fix: stop kubelet, observe effects 9. Break and fix: remove CNI config, restore
Success Criteria: - Can identify CNI issues from logs - Successfully install and verify CNI - Understand node status transitions - Troubleshooting workflow muscle memory
Lab Environment Comparison¶
graph TD
subgraph "Setup Method Comparison"
Feature[Feature]
kubeadm[kubeadm]
minikube[Minikube]
kind[kind]
end
Feature --> |Startup Time| Time
Time --> kubeadm_time[5-10 min<br/>Multi-machine]
Time --> minikube_time[2-5 min<br/>VM boot]
Time --> kind_time[30-60 sec<br/>Containers]
Feature --> |Resource Usage| Resources
Resources --> kubeadm_res[High<br/>Real VMs]
Resources --> minikube_res[Medium<br/>Single VM]
Resources --> kind_res[Low<br/>Docker only]
Feature --> |Multi-Node| MultiNode
MultiNode --> kubeadm_mn[Native<br/>Production-like]
MultiNode --> minikube_mn[Experimental<br/>Limited]
MultiNode --> kind_mn[Native<br/>Config-based]
Feature --> |CKA Relevance| CKA
CKA --> kubeadm_cka[Essential<br/>Exam environment]
CKA --> minikube_cka[Supplemental<br/>Learning]
CKA --> kind_cka[High<br/>Practice speed]
style kind_time fill:#99ff99
style kind_res fill:#99ff99
style kubeadm_mn fill:#ff9999
style kubeadm_cka fill:#ff9999
Quick Reference Commands¶
kubeadm Cluster Lifecycle¶
# Initialize control plane
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
# Configure kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# Install CNI (Calico)
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml
# Generate join command
kubeadm token create --print-join-command
# Reset cluster
sudo kubeadm reset
kind Quick Start¶
# Create cluster
kind create cluster --name cka-lab
# Create multi-node cluster
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
# Delete cluster
kind delete cluster --name cka-lab
Minikube Quick Start¶
# Start with resource spec
minikube start --driver=docker --cpus=4 --memory=8192
# Enable addons
minikube addons enable metrics-server
minikube addons enable ingress
# Access service
minikube service <service-name>
# Clean up
minikube delete
kubectl Context Management¶
# View contexts
kubectl config get-contexts
# Switch context
kubectl config use-context <context-name>
# Set namespace
kubectl config set-context --current --namespace=<namespace>
# Context-specific command
kubectl --context=<context> get pods
Troubleshooting Commands¶
# Check cluster health
kubectl get nodes -o wide
kubectl -n kube-system get pods
# View kubelet logs (on node)
sudo journalctl -u kubelet -f
# Check CNI config
ls -l /etc/cni/net.d/
# View events
kubectl get events --sort-by='.lastTimestamp'
# Check etcd health
sudo ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
endpoint health
Key Takeaways¶
✅ kubeadm is essential for CKA - The exam environment uses kubeadm clusters
✅ kind enables rapid iteration - 30-second cluster creation for practice
✅ kubectl proficiency is critical - Shell completion and aliases save exam minutes
✅ kubeconfig mastery matters - Context switching is a core exam skill
✅ CNI is non-negotiable - Clusters are non-functional without CNI plugins
✅ Swap must be disabled - Kubernetes does not support swap memory
✅ Version compatibility awareness - kubectl and cluster versions must align
✅ Hands-on practice wins - Deploy clusters repeatedly until muscle memory forms
✅ Troubleshooting is 30% of CKA - Practice breaking and fixing clusters
✅ Speed through preparation - Optimize workflow before exam day
Next Steps¶
After mastering lab setup, continue with:
Post 3: kubectl Essentials and Resource Management - Master the command-line tool for all Kubernetes operations
Related Posts: - Kubernetes Architecture Fundamentals - Understanding cluster components - Kubernetes CKA Mastery - Complete Learning Path - Full exam preparation series
External Resources: - kubeadm Official Documentation - kind Quick Start Guide - Minikube Documentation - kubectl Cheat Sheet - CKA Exam Curriculum