You have reached the end of the technical journey. Across eleven modules you have built, broken, fixed, secured and scaled the Rutas Norte platform: from that first stand-alone Pod to a production cluster with Ingress, TLS, network policies, persistent storage, full observability and canary deployments governed by GitOps. That knowledge is exactly what the CKA (Certified Kubernetes Administrator) certification measures. The only thing standing between you and the certificate is the format: a hands-on exam, in a terminal, against the clock, with a timer that does not forgive hesitation.
This lesson turns the course you have just completed into a study plan for the CKA. You will see what it certifies precisely, what the exam looks like from the inside, which domains it covers and with what weight, and —most importantly— a table mapping every official curriculum objective to the lesson in this course where you studied it. From there you get a six-week plan and a battery of eight exam-style tasks solved with the exact command and its target time.
Essential notice. The specific exam details (price, exact duration, number of attempts included, pass mark and domain weighting) change over time. Everything you read here is indicative and reflects the moment this lesson was written. Before you enrol, always check the current official curriculum on the Linux Foundation / CNCF website (
training.linuxfoundation.organdcncf.io/certification/cka). The certification programme reviews its objectives with each Kubernetes release.
Contents
- What the CKA certifies and who it is for
- The exam format from the inside
- The curriculum domains and their indicative weights
- Full map: every CKA objective and its lesson in this course
- CKA-specific skills worth practising separately
- A six-week study plan
- Official resources and the practice simulator
- Eight CKA-style tasks solved against the clock
- What the CKA certifies and who it is for
The CKA certifies that you know how to administer and operate a Kubernetes cluster. It is not a certification about container theory or about application development: it is the certification of the profile that keeps the cluster alive.
1.1 The profile it measures
In an organisation like Rutas Norte, the person holding a CKA is the one responsible for:
| Responsibility | Example at Rutas Norte |
|---|---|
| Installing and maintaining the cluster | Building the cluster with kubeadm, joining new nodes, upgrading from 1.30 to 1.31 |
| Managing the control plane | Diagnosing a kube-apiserver that will not start, taking an etcd backup |
| Operating nodes | Draining node-3 to swap the disk, managing taints and cordons |
| Configuring access | Creating the Role that lets the support team read logs in rutas-norte-pro |
| Providing networking and storage | Publishing web-store through Ingress, provisioning the PVC for bookings-postgres |
| Troubleshooting | notifications-worker is in CrashLoopBackOff and you have to work out why |
1.2 Its place among the three certifications
- CKA: administering the cluster. Nodes, control plane, etcd, RBAC, networking, storage and diagnosis.
- CKAD: developing on the cluster; application manifests and speed with
kubectl(lesson12-02). - CKS: securing the cluster; hardening, policies and detection (lesson
12-03). Requires a valid CKA.
The CKA is the natural entry point if your work is platform, SRE or infrastructure.
1.3 Prerequisites and what is NOT covered
There are no formal prerequisites: anyone can enrol. The real requirements are practical: being comfortable with the Linux command line (systemctl, journalctl, file permissions, vim), understanding containers, and having worked on a real cluster —the mileage this course has given you.
It is also worth knowing what does not come up. There are no multiple-choice questions: everything is hands-on. Helm, Kustomize and Argo CD are not covered in depth, nor are the managed providers (EKS/AKS/GKE), nor Prometheus or Grafana as products —kubectl top and the metrics-server are—, nor application development. The exam focuses on pure Kubernetes.
- The exam format from the inside
This is the section most people underestimate. Knowing Kubernetes and passing the CKA are different things, and the difference lives right here.
2.1 Exam characteristics
| Aspect | Indicative description |
|---|---|
| Type | 100 % hands-on, no theory questions |
| Environment | Browser-based terminal, remotely proctored |
| Duration | Around two hours |
| Number of tasks | Roughly between 15 and 20 |
| Pass mark | Around 66 % |
| Attempts | Enrolment usually includes a free second attempt |
| Validity | Around two years (see lesson 12-04) |
| Documentation allowed | Yes, the official documentation and nothing else |
Again: all these figures are indicative. Verify the current curriculum and conditions on the official website before paying for your enrolment.
2.2 Multiple clusters and context switching
This is trap number one in the exam, and the one that gives away the most points to the careless.
The exam does not give you one cluster: it gives you several, each with a different context name. Every task starts by telling you which context to work in, with a command you can copy and paste:
If you solve the task perfectly on the wrong cluster, your score is zero. There are no partial marks for good intentions.
Commands you need at your fingertips, automatically:
# List every available context
kubectl config get-contexts
# See which one I am in RIGHT NOW
kubectl config current-context
# Switch context
kubectl config use-context <name>
# Set a default namespace on the current context
kubectl config set-context --current --namespace=rutas-norte-proMandatory habit: the first command of every task is the use-context you were given. No exceptions, not even when "it is the same one as before".
2.3 Per-task scoring and partial marks
Each task carries a weight in points shown in the statement (for example, "Task weight: 7 %"). They all add up to 100.
What matters:
- Partial marks exist. If a task asks you to create a Deployment with 3 replicas, expose it with a Service and add a probe, and you only do the first two things, you take part of the points. Never leave a task blank.
- Grading is automatic and based on the final state of the cluster. Nobody looks at how you did it. If the object exists with the requested configuration, it scores; it makes no difference whether you created it with
kubectl create, from a YAML file or by editing it by hand. - That means the imperative route is just as valid as the declarative one, and far quicker.
2.4 The allowed documentation: the decisive weapon
During the exam you may open one additional browser tab to consult:
https://kubernetes.io/docs/(including the API reference and the blog)- The documentation of the official subprojects linked from there (for example
kubernetes.io/docs/reference/kubectl/)
You may not use general search engines, forums, your own notes, other websites or AI tools. It is proctored.
This changes your study strategy completely: you do not need to memorise YAML. You need to know where each example lives and adapt it in seconds. A PersistentVolume manifest, a NetworkPolicy or an Ingress with TLS are long to type and easy to copy.
Pages worth having mentally located (covered in more detail in lesson 12-04):
| I need... | Search on kubernetes.io |
|---|---|
| PV / PVC manifest | "persistent volumes" |
| Sample NetworkPolicy | "network policies" |
| Ingress with path rules | "ingress" |
| etcd backup | "operating etcd clusters for kubernetes" |
| Upgrading the cluster | "upgrading kubeadm clusters" |
| RBAC (Role/RoleBinding) | "using rbac authorization" |
| Static pods | "static pods" |
| Probes | "configure liveness readiness startup probes" |
2.5 The working environment
- The terminal lives in a browser. Copy and paste works, but with its own shortcuts (usually
Ctrl+Shift+C/Ctrl+Shift+Von Linux). Practise it. - The available editor is
vim(andnano). If you cannot handlevimwith at least basic fluency, give it a couple of hours before the exam. - You have
sudoaccess to the nodes oversshwhen a task requires it (to fix the kubelet, for instance). - There is a notepad in the exam interface for jotting things down; use it to keep your list of pending tasks.
- The curriculum domains and their indicative weights
The official CKA curriculum is organised into five domains. This is the split published at the time of writing this lesson; verify it on the official website, because the programme is reviewed periodically.
| Domain | Indicative weight | What it covers |
|---|---|---|
| Cluster architecture, installation and configuration | ~25 % | Building the cluster, RBAC, upgrading it, etcd, high availability, Helm/Kustomize package managers at a basic level |
| Workloads and scheduling | ~15 % | Deployments, scaling, rollouts, ConfigMaps and Secrets, pod scheduling, autoscaling |
| Services and networking | ~20 % | Services, DNS, Ingress, CNI, NetworkPolicies |
| Storage | ~10 % | StorageClasses, PV, PVC, access modes, volumes in pods |
| Troubleshooting | ~30 % | Diagnosing applications, the cluster, nodes, networking, logs and monitoring |
Look closely at that split: troubleshooting is the heaviest domain, almost a third of the exam. It is not a topic you study by reading: you train it by breaking things and fixing them. It is exactly what you did in module 7 (07-06) and module 11 (11-06).
3.1 How weight translates into time
With two hours and ~17 tasks, the average is around 7 minutes per task, but the real distribution is very uneven:
2-4 % tasks → target 3-4 minutes (create a Secret, scale a Deployment)
5-7 % tasks → target 6-8 minutes (Ingress with TLS, NetworkPolicy, PV+PVC+Pod)
8-10 % tasks → target 10-12 minutes (etcd backup/restore, node upgrade,
broken control plane)Leave the final 10 minutes unallocated, for review. It is the best possible use of those minutes.
- Full map: every CKA objective and its lesson in this course
This is the section that turns the course into a study plan. Every curriculum objective is linked to the lesson where you worked on it. Revising for the CKA is, literally, rereading these lessons and redoing their exercises on a real cluster.
4.1 Cluster architecture, installation and configuration (~25 %)
| Official objective | Course lesson |
|---|---|
| Manage role-based access control (RBAC) | 08-01-role-based-access-control |
| Prepare the infrastructure to install a cluster | 10-02-kubeadm, 01-04-setting-up-a-kubernetes-cluster |
| Create and manage clusters with kubeadm | 10-02-kubeadm |
| Manage the cluster lifecycle (upgrades) | 10-02-kubeadm |
| Implement and configure a highly available infrastructure | 10-02-kubeadm, 09-05-high-availability-and-pdb |
| Use Helm and Kustomize to install components | 10-03-helm, 10-04-kustomize |
| Understand the extension interfaces (CNI, CSI, CRI, ...) | 04-01-cluster-networking, 05-04-storage-classes, 01-02-kubernetes-architecture |
| CRDs, operators and aggregated API components | 06-06-custom-resource-definitions, 06-07-operators-and-the-controller-pattern |
| ServiceAccounts and API access | 03-06-serviceaccounts-and-api-access |
4.2 Workloads and scheduling (~15 %)
| Official objective | Course lesson |
|---|---|
| Understand deployments and perform rollouts and rollbacks | 02-03-deployments, 02-04-updates-rollbacks-and-strategies |
| Use ConfigMaps and Secrets to configure applications | 03-01-configmaps, 03-02-secrets, 03-03-environment-variables |
| Configure application scaling | 09-01-horizontal-pod-autoscaling, 02-03-deployments |
| Understand the primitives used to build robust workloads | 02-01-pods, 02-02-replicasets, 06-01-statefulsets, 06-02-daemonsets |
| Configure Pods and containers: resources and limits | 03-04-resource-quotas-and-limits, 03-05-limitranges-and-qos-classes |
| Scheduling: affinity, taints, tolerations, nodeSelector | 06-05-scheduling-affinity-taints-and-tolerations |
| Jobs and CronJobs | 06-03-jobs-and-cronjobs |
| Labels and selectors | 02-07-labels-selectors-and-annotations |
4.3 Services and networking (~20 %)
| Official objective | Course lesson |
|---|---|
| Understand connectivity between pods | 04-01-cluster-networking |
| Service types and endpoints | 04-02-service-types |
| Use the cluster DNS | 04-03-internal-dns-and-service-discovery |
| Configure and use Ingress and IngressClass | 04-04-ingress-controllers |
| Configure TLS on Ingress | 04-05-tls-and-certificates-with-cert-manager |
| Use NetworkPolicies | 04-06-network-policies, 08-04-network-security |
| Choose and install a CNI plugin | 04-01-cluster-networking |
| Gateway API (basic awareness) | 04-04-ingress-controllers |
4.4 Storage (~10 %)
| Official objective | Course lesson |
|---|---|
| Implement StorageClasses and dynamic provisioning | 05-04-storage-classes, 05-05-dynamic-provisioning-expansion-and-snapshots |
| Configure volumes: types, access modes, reclaim policy | 05-01-volumes, 05-02-persistent-volumes |
| Manage PersistentVolumeClaims | 05-03-persistent-volume-claims |
| Use storage in workloads | 05-01-volumes, 06-01-statefulsets |
| Backup and restore | 05-06-backup-and-restore |
4.5 Troubleshooting (~30 %)
| Official objective | Course lesson |
|---|---|
| Debug applications (pods, containers, events) | 07-06-debugging-and-cluster-events |
| Monitor applications and cluster components | 07-02-metrics-server-and-kubectl-top, 07-03-monitoring-with-prometheus |
| Manage container logs | 07-05-centralized-logging-with-efk, 07-06-debugging-and-cluster-events |
| Diagnose cluster and node failures | 07-06-debugging-and-cluster-events, 11-06-production-operations |
| Troubleshoot networking and service problems | 04-03-internal-dns-and-service-discovery, 04-06-network-policies |
| Health checks and probes | 07-01-health-checks-and-probes |
| Incidents and runbooks | 11-06-production-operations |
- CKA-specific skills worth practising separately
The course has given you the knowledge, but there are seven procedures that are almost certain to appear in the exam and that you need memorised like a choreography. Go over them until they come out without thinking.
5.1 Building a cluster with kubeadm and joining nodes
On the control node:
# Initialise the control plane
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
# Install the CNI (the task statement gives you the exact manifest)
kubectl apply -f https://raw.githubusercontent.com/.../calico.yamlOn the worker node:
If the token has expired (it lasts 24 h), regenerate it from the control node:
Check: kubectl get nodes -o wide must show every node as Ready.
5.2 Upgrading the cluster version
The canonical procedure (always: control plane first, then the workers, one at a time).
# --- On the control node ---
# 1. Allow the new version in the repository (adjust the minor in the repo URL)
sudo apt-get update
sudo apt-cache madison kubeadm # see available versions
# 2. Upgrade kubeadm
sudo apt-mark unhold kubeadm
sudo apt-get install -y kubeadm=1.31.1-1.1
sudo apt-mark hold kubeadm
# 3. Review the plan and apply it
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.31.1
# 4. Drain the node, upgrade kubelet and kubectl, and return it to service
kubectl drain control-node --ignore-daemonsets
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.31.1-1.1 kubectl=1.31.1-1.1
sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubectl uncordon control-node# --- On each worker node ---
sudo apt-get install -y kubeadm=1.31.1-1.1
sudo kubeadm upgrade node # careful: "node", not "apply"!
kubectl drain node-1 --ignore-daemonsets
sudo apt-get install -y kubelet=1.31.1-1.1 kubectl=1.31.1-1.1
sudo systemctl daemon-reload && sudo systemctl restart kubelet
kubectl uncordon node-1Classic traps: forgetting --ignore-daemonsets on the drain (it always fails, because there are CNI and kube-proxy DaemonSets); using upgrade apply on a worker; forgetting the final uncordon.
5.3 etcd backup and restore
This is the task worth the most points and the one most people get wrong. Memorise it.
Backup:
ETCDCTL_API=3 etcdctl snapshot save /opt/backup-etcd.db \
--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.keyVerify the backup:
Restore:
# 1. Restore into a NEW directory
sudo ETCDCTL_API=3 etcdctl snapshot restore /opt/backup-etcd.db \
--data-dir=/var/lib/etcd-restored
# 2. Point the etcd static pod at the new directory
sudo vim /etc/kubernetes/manifests/etcd.yaml
# Under volumes: change hostPath.path from /var/lib/etcd to /var/lib/etcd-restored
# 3. The kubelet recreates the pod on its own. Wait and check.
sudo systemctl restart kubelet
kubectl get pods -n kube-systemThe bits people forget:
- The
etcdcertificates live in/etc/kubernetes/pki/etcd/, not in/etc/kubernetes/pki/. - If the task statement gives you different certificate paths, use theirs.
- You must restore into a new directory, not over the existing one.
- What you change is the
hostPathvolume, not just the container's--data-dirargument. Change both if the manifest has them out of sync.
5.4 Certificate management
sudo kubeadm certs check-expiration # expiry of every certificate
sudo kubeadm certs renew all # renew them all
sudo kubeadm certs renew apiserver # renew just oneAfter renewing you have to restart the control plane static pods —by temporarily moving the manifests out of /etc/kubernetes/manifests/ or restarting the kubelet— and regenerate ~/.kube/config if the admin certificate has changed.
You may also be asked to approve a CSR for a new user:
kubectl get csr
kubectl certificate approve support-rutas-norte
kubectl get csr support-rutas-norte -o jsonpath='{.status.certificate}' | base64 -d > support.crtThe CertificateSigningRequest manifest (group certificates.k8s.io/v1, with the request field in base64, signerName: kubernetes.io/kube-apiserver-client and usages: ["client auth"]) is copied from the documentation by searching for "certificate signing requests": it is quicker and safer than typing it out.
5.5 Draining nodes and node maintenance
# Mark as unschedulable (existing pods stay put)
kubectl cordon node-2
# Empty the node (DaemonSets cannot be evicted: you have to ignore them)
kubectl drain node-2 --ignore-daemonsets --delete-emptydir-data
# Return it to service
kubectl uncordon node-2| Flag | When you need it |
|---|---|
--ignore-daemonsets |
Almost always: there are networking and logging DaemonSets |
--delete-emptydir-data |
If any pod uses emptyDir (the logging sidecar, for example) |
--force |
If there are "orphan" pods with no controller (a stand-alone Pod) |
--grace-period=0 |
Only if the task statement demands immediacy |
5.6 Diagnosing a broken control plane
This is the star scenario of the troubleshooting domain. The mental sequence is always the same:
# 1. Is the API answering?
kubectl get nodes
# If it says "connection refused" → the apiserver is not up.
# 2. Is the kubelet alive? (on the control node, over ssh)
sudo systemctl status kubelet
sudo journalctl -u kubelet -n 50 --no-pager
# 3. Which control plane containers are running?
sudo crictl ps -a
sudo crictl logs <container-id>
# 4. Are the static pod manifests correct?
ls -l /etc/kubernetes/manifests/
sudo cat /etc/kubernetes/manifests/kube-apiserver.yamlTypical causes they will plant on you, and their symptoms:
| Injected cause | Symptom | Fix |
|---|---|---|
Syntax error in kube-apiserver.yaml |
The API does not answer, crictl ps shows no apiserver |
Correct the YAML; the kubelet recreates it on its own |
| Wrong path in a manifest volume | The container starts and dies | Correct the hostPath |
--etcd-servers with the wrong port |
apiserver in a loop, connection errors in the logs | Correct the argument |
staticPodPath changed in /var/lib/kubelet/config.yaml |
No static pod starts at all | Restore staticPodPath: /etc/kubernetes/manifests and restart the kubelet |
| kubelet stopped or disabled | Node NotReady |
sudo systemctl enable --now kubelet |
Wrong permissions on /etc/kubernetes/pki/* |
apiserver cannot read its keys | Correct chmod/chown (keys 600, root:root) |
kubelet kubeconfig pointing to the wrong place |
Node NotReady, authentication errors in the logs |
Correct /etc/kubernetes/kubelet.conf |
Golden rule: static pods are not managed with kubectl. They are managed by editing files in /etc/kubernetes/manifests/, and the kubelet reacts within seconds.
5.7 RBAC
It shows up in practically every exam. These four commands solve 90 % of the cases:
# Role scoped to a namespace
kubectl create role bookings-reader \
--verb=get,list,watch --resource=pods,pods/log \
-n rutas-norte-pro
# Bind it to a ServiceAccount
kubectl create rolebinding bookings-reader-binding \
--role=bookings-reader \
--serviceaccount=rutas-norte-pro:support \
-n rutas-norte-pro
# ClusterRole and ClusterRoleBinding (cluster scope)
kubectl create clusterrole nodes-reader --verb=get,list --resource=nodes
kubectl create clusterrolebinding nodes-reader-binding \
--clusterrole=nodes-reader --serviceaccount=rutas-norte-pro:supportAnd the check you must always leave done:
kubectl auth can-i list pods \
--as=system:serviceaccount:rutas-norte-pro:support \
-n rutas-norte-pro
# yes
- A six-week study plan
This plan assumes between 8 and 10 hours a week and that you have already done the course. The rule that governs it: for every hour of reading, two hours of keyboard.
| Week | Focus | Lessons to revise | Measurable goal by the end |
|---|---|---|---|
| 1 | Fundamentals and speed with kubectl | 01-05, 01-06, 02-01 to 02-07 |
Create a 3-replica Deployment, expose it, scale it and verify it in under 2 minutes |
| 2 | Workloads, configuration and scheduling | 03-01 to 03-05, 06-01 to 06-03, 06-05, 09-01 |
Consume a ConfigMap and a Secret in all four possible ways without opening the documentation |
| 3 | Networking | 04-01 to 04-06 |
Write from memory a default-deny NetworkPolicy and an Ingress with TLS |
| 4 | Storage and cluster administration | 05-01 to 05-06, 10-02, 08-01 |
Build a kubeadm cluster from scratch on two VMs and upgrade it one full minor version |
| 5 | etcd, certificates and troubleshooting | 07-01, 07-02, 07-06 and sections 5.3 to 5.7 of this lesson |
etcd backup and restore with no documentation; fix the seven failures in the table in section 5.6 |
| 6 | Mock exams | Lesson 12-05 and the official simulator |
Two full timed mock exams, marked, with targeted revision of the weak domains |
How to use it. Week 6 is not for learning anything new: it is for measuring, correcting and resting. Leave the last day to prepare the physical exam environment (see 12-04) and do not touch new topics in the final 48 hours.
- Official resources and the practice simulator
7.1 The ones that matter
| Resource | What for |
|---|---|
| Official CKA page (Linux Foundation) | Current curriculum, price, conditions, retake policy |
Curriculum in the cncf/curriculum GitHub repository |
The PDF with the exact objectives per domain |
kubernetes.io/docs |
The only documentation allowed in the exam: get familiar with its search |
| Candidate Handbook | Environment requirements, identification, proctoring rules |
| Practice simulator included with enrolment | An environment practically identical to the exam |
7.2 The included simulator
Enrolment usually includes access to an exam simulator (typically two sessions of around 36 hours each, in an environment equivalent to the real one). Tips on using it:
- Do not burn it early. Use it once you already feel reasonably prepared, in week 6.
- Its difficulty is usually higher than the real exam. If you score 60 % there, you are in good shape.
- What is valuable is not the score but the solutions: read them all, including the tasks you got right, because there is almost always a quicker way.
7.3 Your own practice environment
You do not need to pay for anything. With kind you get a cluster with one control node and two workers in under a minute (revisit 10-01):
kind create cluster --name cka --config kind-cka.yaml # 1 control-plane + 2 workers
kubectl get nodesThat said, to practise kubeadm, etcd and the broken control plane you need real machines (VMs with Multipass, Vagrant or similar): kind runs the control plane inside containers and faithfully reproduces neither systemctl nor the host's static pods.
- Eight CKA-style tasks solved against the clock
Practise these eight as if they were the exam: timer running, only kubernetes.io open. The scenarios are from Rutas Norte.
Task 1 — Create a Deployment and expose it (weight ~4 %, target: 4 min)
Context:
kubectl config use-context rutas-norte-devIn the
rutas-norte-devnamespace, create a Deployment calledweb-storewith the imagenginx:1.27-alpineand 3 replicas. Expose it with aClusterIPService calledweb-store-svcon port 80.
kubectl config use-context rutas-norte-dev
kubectl create deployment web-store \
--image=nginx:1.27-alpine --replicas=3 -n rutas-norte-dev
kubectl expose deployment web-store \
--name=web-store-svc --port=80 --target-port=80 -n rutas-norte-devCheck:
NAME READY UP-TO-DATE AVAILABLE
deployment.apps/web-store 3/3 3 3
NAME TYPE CLUSTER-IP PORT(S)
service/web-store-svc ClusterIP 10.96.140.22 80/TCP
NAME ENDPOINTS
endpoints/web-store-svc 10.244.1.5:80,10.244.2.7:80,10.244.2.8:80The trap: if endpoints comes back empty, the selector does not match. kubectl expose inherits it correctly; writing it by hand is where it breaks.
Task 2 — etcd backup and restore (weight ~8 %, target: 10 min)
Context:
kubectl config use-context rutas-norte-proTake an etcd backup into
/opt/etcd-rutas-norte.db. Then restore the previous backup/opt/previous-snapshot.dbinto the directory/var/lib/etcd-restore. The certificates are in/etc/kubernetes/pki/etcd/.
# Backup
sudo ETCDCTL_API=3 etcdctl snapshot save /opt/etcd-rutas-norte.db \
--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
# Backup verification
sudo ETCDCTL_API=3 etcdctl --write-out=table snapshot status /opt/etcd-rutas-norte.db
# Restore
sudo ETCDCTL_API=3 etcdctl snapshot restore /opt/previous-snapshot.db \
--data-dir=/var/lib/etcd-restore
# Repoint the static pod
sudo vim /etc/kubernetes/manifests/etcd.yamlIn the manifest, the volume ends up like this:
volumes:
- hostPath:
path: /var/lib/etcd-restore # previously: /var/lib/etcd
type: DirectoryOrCreate
name: etcd-dataCheck:
The trap: snapshot save does not need sudo if your user can read the certificates, but restore writes into /var/lib, so it does. And you must change the volume's hostPath, not just the container's --data-dir.
Task 3 — Drain a node for maintenance (weight ~4 %, target: 3 min)
Context:
kubectl config use-context rutas-norte-proNode
node-2is due for maintenance. Empty it of workloads without removing the DaemonSets, and make sure no new pods are scheduled onto it.
Check:
NAME STATUS ROLES VERSION
node-1 Ready <none> v1.30.4
node-2 Ready,SchedulingDisabled <none> v1.30.4kubectl get pods -A -o wide --field-selector spec.nodeName=node-2
# Only DaemonSet pods should remain (CNI, kube-proxy)The trap: drain already does a cordon. If it fails because of a stand-alone pod with no controller, add --force.
Task 4 — RBAC for the support team (weight ~6 %, target: 6 min)
Context:
kubectl config use-context rutas-norte-proCreate the ServiceAccount
supportinrutas-norte-pro. Grant it permission to view pods and read their logs in that namespace, and nothing else. Verify the result.
kubectl create serviceaccount support -n rutas-norte-pro
kubectl create role support-read \
--verb=get,list,watch \
--resource=pods,pods/log \
-n rutas-norte-pro
kubectl create rolebinding support-read-binding \
--role=support-read \
--serviceaccount=rutas-norte-pro:support \
-n rutas-norte-proCheck:
kubectl auth can-i get pods --as=system:serviceaccount:rutas-norte-pro:support -n rutas-norte-pro
# yes
kubectl auth can-i delete pods --as=system:serviceaccount:rutas-norte-pro:support -n rutas-norte-pro
# no
kubectl auth can-i get pods --as=system:serviceaccount:rutas-norte-pro:support -n rutas-norte-dev
# noThe trap: pods/log is a separate subresource. Without it, kubectl logs fails even though you can list pods.
Task 5 — PV, PVC and a Pod that uses it (weight ~7 %, target: 8 min)
Context:
kubectl config use-context rutas-norte-preCreate a PersistentVolume
pv-reportsof 2Gi, modeReadWriteOnce,hostPathat/mnt/reports, withstorageClassName: manual. Create a 1Gi PVCpvc-reportsthat consumes it, and a Podoccupancy-reportswith imagebusybox:1.36that mounts it at/dataand runssleep 3600.
# reports.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-reports
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /mnt/reports
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-reports
namespace: rutas-norte-pre
spec:
accessModes:
- ReadWriteOnce
storageClassName: manual
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: occupancy-reports
namespace: rutas-norte-pre
spec:
containers:
- name: reports
image: busybox:1.36
command: ["sleep", "3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: pvc-reportsCheck:
NAME CAPACITY ACCESS MODES STATUS CLAIM
persistentvolume/pv-reports 2Gi RWO Bound rutas-norte-pre/pvc-reports
NAME STATUS VOLUME CAPACITY
persistentvolumeclaim/pvc-reports Bound pv-reports 2GiThe trap: if storageClassName does not match exactly between PV and PVC, the PVC stays Pending forever. And the PV is cluster-scoped: it takes no namespace.
Task 6 — NotReady node (weight ~8 %, target: 8 min)
Context:
kubectl config use-context rutas-norte-proNode
node-3shows up asNotReady. Investigate and bring it back toReadywithout reinstalling anything.
kubectl get nodes
kubectl describe node node-3 | tail -20
# Get onto the node
ssh node-3
sudo systemctl status kubelet
sudo journalctl -u kubelet -n 40 --no-pagerTypical diagnostic output:
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/lib/systemd/system/kubelet.service; disabled)
Active: inactive (dead)The trap: enable as well as start. If you only do start, the grader may reboot the node and you will fail again. If the kubelet starts but dies, look at journalctl: it is usually a wrong path in /var/lib/kubelet/config.yaml or an invalid kubeconfig.
Task 7 — Isolation NetworkPolicy (weight ~7 %, target: 7 min)
Context:
kubectl config use-context rutas-norte-proIn
rutas-norte-pro,bookings-postgresmust only accept inbound traffic on port 5432 from pods labelledapp=bookings-apiin the same namespace. Everything else, denied.
# np-postgres.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: postgres-api-only
namespace: rutas-norte-pro
spec:
podSelector:
matchLabels:
app: bookings-postgres
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: bookings-api
ports:
- protocol: TCP
port: 5432Check:
# Should work
kubectl run test-ok --rm -it --image=busybox:1.36 \
--labels=app=bookings-api -n rutas-norte-pro --restart=Never \
-- nc -zv bookings-postgres 5432
# Should fail (timeout)
kubectl run test-ko --rm -it --image=busybox:1.36 \
--labels=app=intruder -n rutas-norte-pro --restart=Never \
-- nc -zv -w 3 bookings-postgres 5432The trap: declaring policyTypes: [Ingress] is what makes the policy deny everything not explicitly allowed. If you omit it and there are no egress rules, the behaviour is not what you expect. And the CNI must support NetworkPolicies (Calico does; the default CNI in kind does not).
Task 8 — Upgrade a worker node (weight ~9 %, target: 12 min)
Context:
kubectl config use-context rutas-norte-proUpgrade the worker node
node-1from version 1.30.4 to 1.31.1. The control plane is already on 1.31.1.
# From the control node
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
# On node-1 over ssh
ssh node-1
sudo apt-get update
sudo apt-mark unhold kubeadm
sudo apt-get install -y kubeadm=1.31.1-1.1
sudo apt-mark hold kubeadm
sudo kubeadm upgrade node
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.31.1-1.1 kubectl=1.31.1-1.1
sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reload
sudo systemctl restart kubelet
exit
# Back on the control node
kubectl uncordon node-1Check:
The trap: on workers it is kubeadm upgrade node, never upgrade apply. And if the package repository is pinned to minor 1.30, you first have to change the pkgs.k8s.io repository URL to v1.31, or apt will not see the new version.
Common Mistakes and Tips
Mistakes that cost points in the exam
| Mistake | Consequence | Prevention |
|---|---|---|
Not running the task's use-context |
Zero points on a perfect task | First command of every task, always |
Forgetting the requested -n <namespace> |
The object is created in default and does not score |
Use kubectl config set-context --current --namespace=X |
| Writing YAML from scratch | Time drains away and you introduce indentation errors | Use --dry-run=client -o yaml or copy from the documentation |
| Grinding away at a hard task | You leave 4 easy tasks undone | Time limit per task; flag it and move on |
| Not verifying what you did | You think you scored and you did not | One closing kubectl get/describe per task |
| Leaving a task blank | You lose the partial marks | Always do the part you know |
Using apt-get upgrade instead of installing the exact version |
You break the cluster | apt-get install -y kubelet=<version> |
Restoring etcd over /var/lib/etcd |
The restore fails or corrupts data | Restore into a new directory |
drain without --ignore-daemonsets |
The command fails and you lose minutes | Always include it |
Preparation tips
- Practise on a real cluster, do not just read. You pass the CKA with your hands.
- Time yourself from day one. Knowing how to do something in 15 minutes is useless if the target is 6.
- Master
kubectl explain.kubectl explain pod.spec.containers.livenessProbe --recursivesaves you opening the browser. - Hold the documentation in your head as a map. Do not memorise YAML: memorise which page it is on.
- Learn to read events.
kubectl describe podandkubectl get events --sort-by=.lastTimestampsolve half the troubleshooting domain. - Get comfortable with
sudo. Many administration tasks happen on the node, not inkubectl. - Simulate the exam environment. Same browser, same terminal, same keyboard. It reduces friction on the day.
Exercises
Exercise 1 — Build your own study map
Take the current official CKA curriculum (download it from the cncf/curriculum repository) and, for each objective, note three things in a table of your own: the lesson in this course that covers it, your confidence level from 1 to 5, and whether you could solve it without documentation. Sort the table by ascending confidence: that order is your revision plan.
Exercise 2 — Timed administration block
On a three-node cluster built with kubeadm (or VMs), solve the following in 30 straight minutes with no breaks:
- Back up etcd into
/opt/backup.dband verify it withsnapshot status. - Drain
node-1, upgrade its kubelet to the next patch version, and return it to service. - Create the ServiceAccount
auditorwith read-only permissions onpodsandservicesacross all namespaces, and prove it withauth can-i.
Exercise 3 — Break and fix the control plane
Deliberately cause these three failures, one at a time, and fix each one while timing yourself:
- Change the
--secure-portin/etc/kubernetes/manifests/kube-apiserver.yamlto6444. - Rename
/etc/kubernetes/pki/etcd/server.keytoserver.key.bak. - Change
staticPodPathin/var/lib/kubelet/config.yamlto/etc/kubernetes/pod-manifests.
Target: diagnose and fix each one in under 6 minutes.
Solutions
Solution to Exercise 1
There is no single solution, but your table should look something like this (extract); the deciding criterion is the last column:
| Objective | Lesson | Confidence | Without docs? |
|---|---|---|---|
| etcd backup/restore | 05-06 + section 5.3 |
2 | No |
| Create a Deployment and scale it | 02-03 |
5 | Yes |
| Default-deny NetworkPolicy | 04-06 |
3 | No |
| Upgrade the cluster | 10-02 |
2 | No |
| Diagnose a pod in CrashLoop | 07-06 |
4 | Yes |
Anything with confidence ≤ 3 and "No" in the last column goes into weeks 4 and 5 of the plan. The usual trap is scoring yourself high on things you understand but have never executed: if you have not done it with your hands this week, confidence is 3 at most.
Solution to Exercise 2
etcd block (target 8 min):
sudo ETCDCTL_API=3 etcdctl snapshot save /opt/backup.db \
--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
sudo ETCDCTL_API=3 etcdctl --write-out=table snapshot status /opt/backup.db+----------+----------+------------+------------+
| HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| 8f2e91ac | 41207 | 1382 | 5.9 MB |
+----------+----------+------------+------------+Node block (target 15 min):
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
ssh node-1 '
sudo apt-get update &&
sudo apt-mark unhold kubelet kubectl &&
sudo apt-get install -y kubelet=1.30.5-1.1 kubectl=1.30.5-1.1 &&
sudo apt-mark hold kubelet kubectl &&
sudo systemctl daemon-reload && sudo systemctl restart kubelet'
kubectl uncordon node-1
kubectl get nodesFor a patch-only change (1.30.4 → 1.30.5) upgrading the kubelet is enough; a minor version change would also require sudo kubeadm upgrade node.
RBAC block (target 7 min): because it says "all namespaces", it requires ClusterRole + ClusterRoleBinding:
kubectl create serviceaccount auditor -n rutas-norte-pro
kubectl create clusterrole auditor-read --verb=get,list,watch --resource=pods,services
kubectl create clusterrolebinding auditor-read-binding \
--clusterrole=auditor-read --serviceaccount=rutas-norte-pro:auditor
kubectl auth can-i list services --as=system:serviceaccount:rutas-norte-pro:auditor -A # yes
kubectl auth can-i create pods --as=system:serviceaccount:rutas-norte-pro:auditor -A # noThe classic mistake is using Role+RoleBinding: that would only cover one namespace. The second mistake is a ClusterRole with a RoleBinding, which restricts the permissions to one specific namespace —useful in other cases, but not what was asked.
Solution to Exercise 3
| Injected failure | Symptom | Fix |
|---|---|---|
--secure-port=6444 on the apiserver |
kubectl answers The connection to the server ... was refused; the container starts and dies |
Put 6443 back and adjust the port in livenessProbe and readinessProbe too: the manifest repeats it in three places and changing only one leaves the pod in a loop |
etcd's server.key renamed |
The API does not answer; the etcd logs show no such file or directory |
Restore the name and leave it as chmod 600, root:root. With wrong permissions the symptom is identical, and the fix is just the chmod/chown |
staticPodPath changed |
Every control plane pod disappears at once; that simultaneity gives it away compared with an isolated failure | Restore staticPodPath: /etc/kubernetes/manifests in /var/lib/kubelet/config.yaml and restart the kubelet |
The diagnostic sequence is always the same, and it is worth putting on autopilot:
kubectl get nodes # is the API answering?
sudo systemctl status kubelet # is the kubelet alive?
sudo journalctl -u kubelet -n 40 --no-pager
sudo crictl ps -a # which control plane containers are there?
sudo crictl logs <container-id>
ls -l /etc/kubernetes/manifests/The key difference this exercise burns in: the manifests in /etc/kubernetes/manifests/ are reread by the kubelet on its own, within seconds; /var/lib/kubelet/config.yaml does require sudo systemctl restart kubelet to take effect.
Conclusion
The CKA does not measure whether you know Kubernetes in the abstract: it measures whether you can operate a cluster with your hands and in a hurry. After eleven modules building Rutas Norte, you already have the knowledge; what this lesson has given you is the translation of that knowledge into the language of the exam.
The points to take away:
- The CKA certifies the administration profile: nodes, control plane, etcd, networking, storage, RBAC and, above all, diagnosis (the heaviest domain, around 30 %).
- The exam is hands-on, timed and spread over several clusters.
use-contextis the first command of every task, without exception. - There are partial marks: never leave a task empty.
- You may consult the official documentation and nothing else. Study where everything is; do not memorise YAML.
- The table in section 4 turns this course into your study plan: every official objective has its lesson.
- Seven procedures must be on autopilot: kubeadm, upgrade, etcd, certificates, drain, broken control plane and RBAC.
- Always check the current official curriculum on the Linux Foundation / CNCF website before enrolling: weights, duration and conditions change.
In the next lesson we change profile. If the CKA is the certification for whoever keeps the cluster running, the CKAD is the one for whoever builds on top of it: less etcd and more application manifests, less administration and far more speed with kubectl. We will look at how they differ, which domains they cover and how to train the skill that decides that exam: doing many correct things in very little time.
Kubernetes Course
Module 1: Introduction to Kubernetes
- What Is Kubernetes?
- Kubernetes Architecture
- Key Concepts and Terminology
- Setting Up a Kubernetes Cluster
- The Kubernetes CLI: kubectl
- Objects, YAML Manifests and the Declarative Model
- The Course Project: the Rutas Norte Platform
Module 2: Core Kubernetes Components
- Pods
- ReplicaSets
- Deployments
- Updates, Rollbacks and Deployment Strategies
- Services
- Namespaces
- Labels, Selectors and Annotations
Module 3: Configuration and Secret Management
- ConfigMaps
- Secrets
- Environment Variables
- Resource Quotas and Limits
- LimitRanges and Quality of Service (QoS) Classes
- ServiceAccounts and API Access from Pods
Module 4: Networking in Kubernetes
- Cluster Networking
- Service Types
- Internal DNS and Service Discovery
- Ingress Controllers
- TLS and Certificate Management with cert-manager
- Network Policies
Module 5: Storage in Kubernetes
- Volumes
- Persistent Volumes
- Persistent Volume Claims
- Storage Classes
- Dynamic Provisioning, Expansion and Snapshots
- Backup and Restore of Persistent Data
Module 6: Advanced Kubernetes Concepts
- StatefulSets
- DaemonSets
- Jobs and CronJobs
- Init Containers, Sidecars and Multi-Container Patterns
- Scheduling: Affinity, Taints and Tolerations
- Custom Resource Definitions (CRDs)
- Operators and the Controller Pattern
Module 7: Monitoring and Logging
- Health Checks and Probes
- Metrics Server and kubectl top
- Monitoring with Prometheus
- Visualization and Alerting with Grafana and Alertmanager
- Centralized Logging with Elasticsearch, Fluentd and Kibana (EFK)
- Application Debugging and Cluster Events
Module 8: Kubernetes Security
- Role-Based Access Control (RBAC)
- Security Contexts and Container Hardening
- Pod Security Policies and Pod Security Standards
- Network Security
- Image Security
- Auditing, Scanning and Vulnerability Management
Module 9: Scaling and Performance
- Horizontal Pod Autoscaling
- Vertical Pod Autoscaling
- Cluster Autoscaling
- Event-Driven and Custom-Metric Scaling with KEDA
- High Availability: PodDisruptionBudgets and Topology
- Performance Tuning
Module 10: Kubernetes Ecosystem and Tooling
- Minikube and Local Environments with kind
- Kubeadm
- Helm
- Kustomize
- GitOps with Argo CD and Flux
- Managed Kubernetes: EKS, AKS and GKE
Module 11: Case Studies and Real-World Applications
- Deploying a Web Application
- Running Stateful Applications
- CI/CD with Kubernetes
- Deployment Strategies: Blue-Green and Canary
- Multi-Cluster Management
- Production Operations: Incidents, Runbooks and Costs
