What is the CKA Hands‑On Companion?
The companion is a curated collection of real‑world commands used in the freeCodeCamp CKA preparation course. It provides a practical, repeatable workflow for building, operating, and troubleshooting Kubernetes clusters, matching the tasks you will face on the Certified Kubernetes Administrator exam.
Why Set Up a Dedicated CKA Practice Environment?
- Replicates the exam’s single‑node or multi‑node kubeadm setup.
- Allows safe experimentation with networking, storage, and security features.
- Enables hands‑on practice of upgrade, backup, and restore procedures.
- Helps internalize the exact command syntax required for the exam.
How to Install the Prerequisites
- Install containerd – the container runtime used by kubeadm.
sudo apt-get update && sudo apt-get install -y containerd - Configure systemd cgroup driver for containerd.
sudo mkdir -p /etc/containerd && sudo containerd config default | sudo tee /etc/containerd/config.toml && sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml - Enable and start containerd.
sudo systemctl restart containerd && sudo systemctl enable containerd - Disable swap – required by kubeadm.
sudo swapoff -a && sudo sed -i '/ swap / s/^/#/' /etc/fstab
How to Add the Kubernetes apt Repository
- Install transport tools and add the signing key.
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg - Create keyring directory and import the key.
sudo mkdir -p -m 755 /etc/apt/keyrings && curl -fsSL | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg - Add the repository source.
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
How to Install and Hold Kubernetes Binaries
- Update the package index and install kubelet, kubeadm, and kubectl.
sudo apt-get update && sudo apt-get install -y kubelet kubeadm kubectl - Prevent automatic upgrades that could break the lab.
sudo apt-mark hold kubelet kubeadm kubectl
How to Bootstrap a Single‑Node Cluster
- Initialize the control‑plane with a pod network CIDR (Flannel example).
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 - Configure kubectl for the current user.
mkdir -p $HOME/.kube && sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config && sudo chown $(id -u):$(id -g) $HOME/.kube/config - Remove the control‑plane taint to allow scheduling pods on the master.
kubectl taint nodes --all node-role.kubernetes.io/control-plane- - Install a CNI plugin – Flannel is lightweight and works out‑of‑the‑box.
kubectl apply -f
How to Expand to a Multi‑Node Cluster
- On each worker node, repeat the prerequisite installation (containerd, swap, repo, binaries) but do NOT run
kubeadm init. - From the control‑plane, generate a join token.
kubeadm token create --print-join-command - Run the printed
kubeadm join …command on each worker. - Install a more feature‑rich CNI such as Calico for network policy support.
kubectl apply -f
How to Upgrade a Cluster
- Plan the upgrade on the control‑plane.
sudo kubeadm upgrade plan - Apply the upgrade to the control‑plane version (example v1.29.1).
sudo kubeadm upgrade apply v1.29.1 - On each worker, unhold the binaries, install the new version, then re‑hold.
sudo apt-mark unhold kubeadm kubelet && sudo apt-get update && sudo apt-get install -y kubeadm=1.29.1-1.1 kubelet=1.29.1-1.1 && sudo apt-mark hold kubeadm kubelet - Upgrade the node configuration and restart kubelet.
sudo kubeadm upgrade node && sudo systemctl daemon-reload && sudo systemctl restart kubelet
How to Backup and Restore etcd
- Backup using etcdctl (API v3).
sudo mkdir -p /var/lib/etcd-backup && sudo ETCDCTL_API=3 etcdctl snapshot save /var/lib/etcd-backup/snapshot.db \
--endpoints= \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key - Restore on the control‑plane.
sudo systemctl stop kubelet
sudo ETCDCTL_API=3 etcdctl snapshot restore /var/lib/etcd-backup/snapshot.db \
--data-dir /var/lib/etcd-restored
# Edit /etc/kubernetes/manifests/etcd.yaml to point to /var/lib/etcd‑restored
sudo systemctl start kubelet
How to Implement Role‑Based Access Control (RBAC)
- Create a namespace and service account.
kubectl create namespace rbac-test && kubectl create serviceaccount dev-user -n rbac-test - Define a Role that permits read‑only pod access.
# role.yaml … (apiVersion: rbac.authorization.k8s.io/v1, kind: Role, rules: [{apiGroups:[""], resources:["pods"], verbs:["get","list","watch"]}]) - Bind the Role to the ServiceAccount.
# rolebinding.yaml … (kind: RoleBinding, subjects: [{kind: ServiceAccount, name: dev-user, namespace: rbac-test}], roleRef: {kind: Role, name: pod‑reader}) - Apply manifests and verify permissions with
kubectl auth can-i.
How to Manage Applications with Helm and Kustomize
- Add a chart repository and install a chart with overrides.
helm repo add bitnami && helm repo update && helm install my‑nginx bitnami/nginx --set service.type=NodePort - Upgrade, rollback, or uninstall the release using
helm upgrade,helm rollback, andhelm uninstall. - Apply a Kustomize overlay (directory structure
my‑app/overlays/production) with:
kubectl apply -k my‑app/overlays/production
How to Work with Deployments, ConfigMaps, and Secrets
- Create a Deployment manifest (deployment.yaml) and apply it.
kubectl apply -f deployment.yaml - Trigger a rolling update by changing the container image.
kubectl set image deployment/nginx‑deployment nginx=nginx:1.25.0 - Inspect rollout status, history, and undo if needed.
kubectl rollout status deployment/nginx‑deployment && kubectl rollout history deployment/nginx‑deployment && kubectl rollout undo deployment/nginx‑deployment - Create a generic secret (base64 encoding handled automatically).
kubectl create secret generic db‑credentials --from-literal=username=admin --from-literal=password='s3cr3t'
How to Enable Horizontal Pod Autoscaling
- Install the Metrics Server (required for CPU metrics).
kubectl apply -f - Verify metrics collection.
kubectl top nodes && kubectl top pods -A - Create a deployment and expose it, then create an HPA targeting 50 % CPU.
kubectl create deployment php‑apache --image=k8s.gcr.io/hpa-example --requests="cpu=200m" && kubectl expose deployment php‑apache --port=80 && kubectl autoscale deployment php‑apache --cpu-percent=50 --min=1 --max=10 - Watch scaling behavior with
kubectl get hpa -w.
How to Configure Services and Ingress
- Expose a Deployment as a ClusterIP service (default).
kubectl expose deployment my‑app --port=80 --target-port=80 --name=my‑app‑service - Create a NodePort service for external access.
kubectl expose deployment my‑app --port=80 --target-port=80 --name=my‑app‑nodeport --type=NodePort - Install the NGINX Ingress Controller.
kubectl apply -f - Define an Ingress resource that routes traffic to the two sample apps and apply it.
kubectl apply -f ingress.yaml
How to Enforce Network Policies
- Deploy a web server and test connectivity from a default pod (expected to fail).
- Create a NetworkPolicy that allows traffic only from pods with label
access=true.
kubectl apply -f allow‑web‑access.yaml - Retest from a pod with the required label – connection should succeed.
How to Provision Persistent Storage
- Define a static PersistentVolume (hostPath for local testing) and a matching PersistentVolumeClaim.
kubectl apply -f pv.yaml && kubectl apply -f pvc.yaml - Verify binding with
kubectl get pv,pvc. - Deploy a pod that mounts the PVC.
kubectl apply -f pod‑storage.yaml - Use a StorageClass for dynamic provisioning – simply create a PVC without a pre‑created PV and observe the automatically created PV.
How to Troubleshoot Common Issues
- Check node health:
kubectl get nodesandsudo systemctl status kubeleton the node. - Inspect pod logs and events:
kubectl logs POD_NAMEandkubectl describe pod POD_NAME. - Review kubelet and control‑plane logs via
journalctl -u kubelet -f. - Validate network policies and service endpoints when connectivity fails.
- Monitor resource usage with the Metrics Server:
kubectl top nodesandkubectl top pods.