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.org and cncf.io/certification/cka). The certification programme reviews its objectives with each Kubernetes release.

Contents

  1. What the CKA certifies and who it is for
  2. The exam format from the inside
  3. The curriculum domains and their indicative weights
  4. Full map: every CKA objective and its lesson in this course
  5. CKA-specific skills worth practising separately
  6. A six-week study plan
  7. Official resources and the practice simulator
  8. Eight CKA-style tasks solved against the clock

  1. 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 (lesson 12-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.


  1. 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:

kubectl config use-context rutas-norte-pro

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-pro

Mandatory 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+V on Linux). Practise it.
  • The available editor is vim (and nano). If you cannot handle vim with at least basic fluency, give it a couple of hours before the exam.
  • You have sudo access to the nodes over ssh when 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.

  1. 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.


  1. 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

  1. 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.yaml

On the worker node:

sudo kubeadm join 10.0.0.10:6443 --token <token> \
  --discovery-token-ca-cert-hash sha256:<hash>

If the token has expired (it lasts 24 h), regenerate it from the control node:

kubeadm token create --print-join-command

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-1

Classic 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.key

Verify the backup:

ETCDCTL_API=3 etcdctl --write-out=table snapshot status /opt/backup-etcd.db

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-system

The bits people forget:

  • The etcd certificates 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 hostPath volume, not just the container's --data-dir argument. 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 one

After 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.crt

The 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.yaml

Typical 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:support

And 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

  1. 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.


  1. 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 nodes

That 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.


  1. 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-dev

In the rutas-norte-dev namespace, create a Deployment called web-store with the image nginx:1.27-alpine and 3 replicas. Expose it with a ClusterIP Service called web-store-svc on 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-dev

Check:

kubectl get deploy,svc,endpoints -n rutas-norte-dev -l app=web-store
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:80

The 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-pro

Take an etcd backup into /opt/etcd-rutas-norte.db. Then restore the previous backup /opt/previous-snapshot.db into 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.yaml

In the manifest, the volume ends up like this:

  volumes:
  - hostPath:
      path: /var/lib/etcd-restore   # previously: /var/lib/etcd
      type: DirectoryOrCreate
    name: etcd-data

Check:

sudo crictl ps | grep etcd
kubectl get nodes

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-pro

Node node-2 is due for maintenance. Empty it of workloads without removing the DaemonSets, and make sure no new pods are scheduled onto it.

kubectl drain node-2 --ignore-daemonsets --delete-emptydir-data

Check:

kubectl get nodes
NAME     STATUS                     ROLES    VERSION
node-1   Ready                      <none>   v1.30.4
node-2   Ready,SchedulingDisabled   <none>   v1.30.4
kubectl 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-pro

Create the ServiceAccount support in rutas-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-pro

Check:

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
# no

The 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-pre

Create a PersistentVolume pv-reports of 2Gi, mode ReadWriteOnce, hostPath at /mnt/reports, with storageClassName: manual. Create a 1Gi PVC pvc-reports that consumes it, and a Pod occupancy-reports with image busybox:1.36 that mounts it at /data and runs sleep 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-reports
kubectl apply -f reports.yaml

Check:

kubectl get pv,pvc -n rutas-norte-pre
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   2Gi

The 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-pro

Node node-3 shows up as NotReady. Investigate and bring it back to Ready without 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-pager

Typical diagnostic output:

● kubelet.service - kubelet: The Kubernetes Node Agent
     Loaded: loaded (/lib/systemd/system/kubelet.service; disabled)
     Active: inactive (dead)
sudo systemctl enable --now kubelet
sudo systemctl status kubelet
exit

kubectl get nodes
NAME     STATUS   ROLES    AGE   VERSION
node-3   Ready    <none>   42d   v1.30.4

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-pro

In rutas-norte-pro, bookings-postgres must only accept inbound traffic on port 5432 from pods labelled app=bookings-api in 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: 5432
kubectl apply -f np-postgres.yaml

Check:

# 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 5432

The 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-pro

Upgrade the worker node node-1 from 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-1

Check:

kubectl get nodes
NAME          STATUS   ROLES           VERSION
control-node  Ready    control-plane   v1.31.1
node-1        Ready    <none>          v1.31.1

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

  1. Practise on a real cluster, do not just read. You pass the CKA with your hands.
  2. Time yourself from day one. Knowing how to do something in 15 minutes is useless if the target is 6.
  3. Master kubectl explain. kubectl explain pod.spec.containers.livenessProbe --recursive saves you opening the browser.
  4. Hold the documentation in your head as a map. Do not memorise YAML: memorise which page it is on.
  5. Learn to read events. kubectl describe pod and kubectl get events --sort-by=.lastTimestamp solve half the troubleshooting domain.
  6. Get comfortable with sudo. Many administration tasks happen on the node, not in kubectl.
  7. 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:

  1. Back up etcd into /opt/backup.db and verify it with snapshot status.
  2. Drain node-1, upgrade its kubelet to the next patch version, and return it to service.
  3. Create the ServiceAccount auditor with read-only permissions on pods and services across all namespaces, and prove it with auth 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:

  1. Change the --secure-port in /etc/kubernetes/manifests/kube-apiserver.yaml to 6444.
  2. Rename /etc/kubernetes/pki/etcd/server.key to server.key.bak.
  3. Change staticPodPath in /var/lib/kubelet/config.yaml to /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 nodes

For 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    # no

The 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-context is 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

Module 2: Core Kubernetes Components

Module 3: Configuration and Secret Management

Module 4: Networking in Kubernetes

Module 5: Storage in Kubernetes

Module 6: Advanced Kubernetes Concepts

Module 7: Monitoring and Logging

Module 8: Kubernetes Security

Module 9: Scaling and Performance

Module 10: Kubernetes Ecosystem and Tooling

Module 11: Case Studies and Real-World Applications

Module 12: Preparing for Kubernetes Certification

© Copyright 2026. All rights reserved