KCNA common mistakes
KCNA · Understand the traps and how to avoid them.
Answering component-role questions by assigning scheduling to kubelet or Service load-balancing to the scheduler - e.g. saying 'kubelet decides which node a Pod runs on' or 'kube-proxy reconciles desired replica counts'.
Candidates memorise the control-plane component list as a set of names without binding each name to its one-sentence job, so under time pressure they pattern-match 'node' to 'kubelet' and 'scheduling' to anything in the control plane.
What to do instead
Build a two-column drill you can recite: kube-scheduler = picks a node for an unscheduled Pod (writes nodeName); kubelet = node agent, starts containers, runs probes, reports status; kube-controller-manager = runs reconciliation loops (ReplicaSet, Node lifecycle, Job); kube-proxy = programs iptables/IPVS rules for Service VIPs; etcd = the only state store. For each practice question, ask 'which component owns the write to the API server?'
Running kubectl commands or answering questions as if every object were cluster-wide - e.g. expecting `kubectl get pods` to show Pods from all namespaces, or assuming a ClusterRole is created inside a namespace.
Practice clusters often have only a default namespace, so the scoping rule never causes a visible error and the distinction stays abstract.
What to do instead
Memorise the cluster-scoped short list (Node, Namespace, PersistentVolume, StorageClass, ClusterRole, ClusterRoleBinding, CustomResourceDefinition, PriorityClass, IngressClass) and treat everything else as namespaced. Habitually add -n <ns> or -A in commands, and when a question mentions a resource in another namespace without a fully qualified DNS name, flag it as the likely trick.
Assuming every Service type reaches the internet, or that a ClusterIP Service can be called from outside the cluster - e.g. picking ClusterIP when the requirement says 'expose to external clients' or assuming ExternalName creates a proxy.
The four Service types are learned as an ascending list ('bigger = more exposure') rather than as four different mechanisms with different owners (kube-proxy vs cloud controller vs CoreDNS).
What to do instead
Learn type → mechanism → who implements it: ClusterIP = virtual IP, in-cluster only, kube-proxy; NodePort = opens 30000–32767 on every node; LoadBalancer = NodePort plus a cloud provider load balancer provisioned by the cloud controller manager; ExternalName = a DNS CNAME with no VIP, no proxying, no kube-proxy. Also separate L4 from L7: Service/kube-proxy is L4, Ingress plus an ingress controller is L7.
Treating Deployment and StatefulSet as interchangeable, or expecting a Deployment's Pods to have stable names, ordered start-up, or per-Pod storage.
Deployments are used in almost every tutorial, so candidates generalise 'workload controller = random Pod names + shared nothing' to all controllers.
What to do instead
Anchor on three discriminators: identity (StatefulSet gives stable ordinal names pod-0, pod-1), ordering (StatefulSet creates/deletes in order; Deployment is unordered and parallel), and storage (StatefulSet pairs with volumeClaimTemplates to give each replica its own PVC, plus a headless Service for stable DNS). DaemonSet is the third case: exactly one Pod per eligible node.
Predicting the wrong outcome for resource overuse - saying a container that exceeds its CPU limit is killed, or that memory above the request triggers eviction of the Pod.
The words 'limit' and 'request' are learned as a pair of numbers rather than as two different mechanisms with two different enforcers (scheduler vs cgroups), and CPU and memory are treated as behaving identically.
What to do instead
Drill the matrix: request = what the scheduler reserves and uses for placement/fit; limit = enforced by the kernel via cgroups. CPU over limit = throttled, never killed. Memory over limit = OOMKilled. Then map QoS: Guaranteed when requests == limits for every container, BestEffort when none are set, Burstable otherwise - and remember BestEffort/Burstable are evicted before Guaranteed under node pressure.
Mixing up the three autoscalers - answering that HPA adds nodes, that VPA changes replica count, or that HPA works on a fresh cluster with no metrics pipeline.
All three contain 'auto' and 'scale', and the exam wording ('scale to meet demand') does not always name the layer being scaled.
What to do instead
Fix the axis each one moves: HPA changes replica count (needs metrics-server or a custom metrics adapter), VPA changes container requests/limits (and therefore usually restarts Pods), cluster autoscaler changes the number of nodes by reacting to unschedulable Pods. Ask 'what object is being resized: Pods, Pod specs, or Nodes?' before answering.
Assuming a failing readiness probe restarts the container, or that a liveness probe removes a Pod from Service endpoints.
The probes are memorised as 'health checks' with no distinct consequence attached, so the two effects get swapped under pressure.
What to do instead
Attach one consequence to each: readiness failure = Pod marked NotReady and removed from Endpoints (traffic stops, container keeps running); liveness failure = kubelet restarts the container; startup probe = suppresses the other two until it succeeds, protecting slow-starting apps from premature liveness kills. Also remember the kubelet executes probes on the node.
Reasoning about a rolling update as if it were all-at-once or as if maxSurge/maxUnavailable constrain total Pods - e.g. claiming maxUnavailable: 0 makes a rollout impossible, or that maxSurge adds extra nodes.
The percentage defaults (25%/25%) are memorised, but the direction of each parameter (above desired vs below desired) is not, and 'surge' is misread as infrastructure.
What to do instead
State it as a sentence before answering: maxSurge = how many Pods above the desired count may exist during the rollout; maxUnavailable = how many below desired may be unavailable. Both are Pod counts, both default to 25%, and both are reconciled by the Deployment controller against the ReplicaSets it manages. maxUnavailable: 0 with maxSurge > 0 is valid and is the zero-downtime pattern.
Defining SLI, SLO and SLA circularly - e.g. calling the SLO 'the contract with penalties' or treating the error budget as a separate monitoring tool.
The three acronyms look like synonyms and are usually skimmed rather than defined once in writing.
What to do instead
Write the chain out: SLI = the measured number (e.g. % of requests < 300 ms); SLO = the internal target for that SLI (e.g. 99.9% over 30 days); SLA = the external contract with consequences if the SLO is missed; error budget = 1 − SLO, the amount of unreliability you are allowed to spend. If an answer option mentions a legal agreement or refund, it is describing an SLA.
Assuming NetworkPolicy provides default isolation, or that a single 'deny all' policy cannot be overridden by a second policy - and equally, assuming RBAC starts permissive.
The two access-control systems have opposite defaults (network: allow-all until selected; RBAC: deny by default), and candidates collapse them into one mental model.
What to do instead
Hold the asymmetry explicitly: RBAC is deny-by-default and additive via Roles/ClusterRoles and bindings; NetworkPolicy is allow-all by default, and a Pod becomes isolated in a direction only once a policy selects it for that direction - after which only the union of all selecting policies' rules is permitted. Add the practical caveat that policies are no-ops unless the CNI plugin enforces them.