Kubernetes and Cloud Native Associate (KCNA) #2: Kubernetes Fundamentals 1 — Architecture and Core Resources
With the exam structure mapped out in #1, this post is where we step into the actual content. Our first stop is Kubernetes Fundamentals. This single domain accounts for 46% of the KCNA exam — nearly half — so locking down points here gets you halfway to the passing line. Because there is so much ground to cover, we split it into two parts: this #2 handles cluster architecture and core resources, and the next #3 covers the API, containers, and scheduling.
The core question this post answers is simple. What parts make up a Kubernetes cluster, what does each part do, and which resource solves which problem. KCNA hammers on both of these in role-matching form.
The big picture: control plane and worker node #
A Kubernetes cluster is divided into two kinds of nodes. The control plane is the brain of the whole cluster, and the worker node is the laborer that actually runs the containers (Pods). This division of roles is the starting point of Domain 1, and KCNA frequently asks “which component lives on the control plane and which lives on a worker node.”
| Category | Location | What it does |
|---|---|---|
| control plane | management node | Decides and maintains the cluster’s desired state. Handles user requests, scheduling, and state reconciliation |
| worker node | worker node | Runs the actual Pods and wires up networking, following the control plane’s decisions |
On a small cluster the control plane and worker can sit on a single node, but in production you separate the control plane onto dedicated nodes and run several of them for higher availability. The single-node cluster spun up with minikube in hands-on track #1 is also internally performing both roles on one node.
Control plane components #
The control plane is not a single program but a collection of several components. You should be able to summarize each component’s role in one line.
kube-apiserver: the gateway for all communication #
kube-apiserver is the cluster’s front door. kubectl, controllers, kubelet, and every other component never talk to each other directly — they always communicate through the apiserver. The apiserver exposes a REST API, and when a request arrives it authenticates, authorizes, and validates it before writing to the cluster state store. The apiserver is also the only component in the cluster that accesses etcd directly.
etcd: the cluster state store #
etcd is the key-value store that holds all of the cluster’s state. Which Pod is running where, how many replicas a given Deployment wants — all of the cluster’s desired state and current state live in etcd. etcd guarantees consistency through a distributed consensus algorithm (Raft). If etcd is corrupted, the cluster loses its entire state, which is why backups are central to operations.
kube-scheduler: deciding Pod placement #
kube-scheduler looks at new Pods that have not yet been assigned to a node and decides which worker node to place them on. It picks the best node by weighing constraints such as available resources (CPU, memory), node selectors, affinity and anti-affinity rules, and taints and tolerations. The scheduler only decides placement; the actual execution is handled by that node’s kubelet.
kube-controller-manager: the reconciliation loop #
kube-controller-manager is the component that bundles multiple controllers into a single process. Each controller continuously compares desired state with current state, and when the two diverge it runs a reconciliation loop to bring the current state in line with the desired state. For example, the ReplicaSet controller compares the declaration “3 replicas” against the number of Pods actually running, creating new ones when short and removing the excess.
cloud-controller-manager: cloud integration #
cloud-controller-manager is the component that connects Kubernetes to a specific cloud provider (AWS, GCP, Azure, etc.). It separates out the cloud-dependent logic from the core — creating cloud load balancers for LoadBalancer-type Services, managing node lifecycle, integrating cloud storage — and handles it. On an on-premises cluster you may not use it at all.
What happens when a component dies #
This is an angle KCNA loves to test. Knowing the impact of each component’s failure lets you confirm its role in reverse.
| Component | Impact when it fails |
|---|---|
| kube-apiserver | All communication halts. kubectl commands, new deployments, and state queries become impossible. But Pods already running keep running |
| etcd | Reading and writing cluster state becomes impossible. The apiserver is effectively paralyzed. Recovery from data corruption is the most catastrophic |
| kube-scheduler | New Pods can’t be assigned to nodes and stay in Pending. Existing Pods are unaffected |
| kube-controller-manager | Reconciliation stops. Recreating Pods on failed nodes, correcting replica counts, and the like all halt |
| kubelet (worker) | Pods on that node go unmanaged. The node is marked NotReady and its Pods may be moved to other nodes |
The key point is that even when the control plane stops, Pods already running do not die immediately. The control plane handles changes and reconciliation, so when it stops, only new work is blocked while existing work keeps chugging along for a while.
Worker node components #
A worker node takes the control plane’s decisions and runs the actual containers. There are three components to remember.
kubelet: the node agent #
kubelet is the agent that runs on each worker node. It receives instructions from the apiserver — “bring up these Pods on this node” — and then directs the container runtime to run them while continuously reporting whether the Pods are healthy. Running liveness and readiness probes to check container health is also kubelet’s responsibility. kubelet is the component ultimately responsible for ensuring that Pods run on the node.
kube-proxy: Service networking #
kube-proxy implements Service networking on each node. To distribute traffic arriving at a Service across the Pods behind it, it manages the node’s iptables (or IPVS) rules. This allows a client to send requests to a Service’s stable virtual IP without knowing the IPs of individual Pods. The actual packet forwarding is handled by kernel rules, and kube-proxy keeps those rules up to date.
Container runtime: actually running containers #
The container runtime is the software that pulls images and actually brings up containers. Today’s standard is containerd, and CRI-O is widely used as well. kubelet talks to these runtimes through a standard interface called CRI (Container Runtime Interface), so swapping out the runtime leaves the kubelet-side code unchanged. We’ll dig deeper into the details of CRI and runtimes in #4, which covers Domain 2.
The declarative model: declare the desired state and it gets matched #
The idea running through Kubernetes is the declarative model. The user does not spell out, step by step, a command procedure of “do this task this way.” Instead, the user declares a desired state — “I want it to end up in this state” — as a YAML manifest, and Kubernetes brings things into that state on its own.
- desired state. The state the user wants. e.g. “3 nginx Pods must always be running”
- current state. The actual state of the cluster right now. e.g. “2 nginx Pods are currently running”
- reconciliation loop. The process where a controller continuously compares the two and, if there’s a difference, brings current in line with desired. In the example above, it creates the missing one
Thanks to this model, even if a node dies and Pods disappear, the controller detects the difference and brings those Pods back up on another node. This self-healing — where the system returns to the desired state on its own without any user-issued recovery command — comes directly from the reconciliation loop. You can also issue commands imperatively with kubectl run, but both real-world operations and the exam treat declarative manifests as the baseline.
Core workload resources #
Now we move on to what you declare. Workload resources form a hierarchy, and the higher you go, the more is handled automatically.
Pod: the smallest deployable unit #
A Pod is the smallest unit that Kubernetes deploys and schedules. You don’t launch a container directly onto a node; you always wrap it inside a shell called a Pod and launch that. A single Pod can hold one or more containers, and containers in the same Pod share networking (the same IP) and storage volumes. The sidecar pattern of placing a helper container alongside operates on top of this structure.
That said, directly creating and managing Pods is rare in practice. If you launch a bare Pod, nothing will revive it when it dies. Normally a higher-level resource manages Pods on your behalf.
ReplicaSet: maintaining the replica count #
A ReplicaSet is a resource that guarantees a specified number of identical Pods are always running. Declare “3 replicas” and the ReplicaSet controller watches the Pod count via the reconciliation loop, creating a new one when one dies and removing any that unintentionally appear. A ReplicaSet identifies the Pods it manages by label selector.
Deployment: managing ReplicaSets + rolling updates #
A Deployment is a resource that wraps a ReplicaSet one level up, and it is the workload resource used most in practice. It delegates replica-count maintenance to the ReplicaSet and adds version management on top. When you update to a new image, the Deployment creates a new ReplicaSet and performs a rolling update that gradually replaces the Pods, and it also supports rollback to the previous ReplicaSet when something goes wrong.
ReplicaSet vs Deployment #
This is a comparison KCNA loves to test. You need to draw a clear line between the two.
| Resource | Responsibility | Direct use |
|---|---|---|
| ReplicaSet | Maintaining the replica count (scale guarantee) | Rarely used directly. Created and managed internally by a Deployment |
| Deployment | Managing ReplicaSets + rolling updates, rollback, version history | The practical standard. Used to deploy stateless workloads |
In one sentence: a Deployment manages a ReplicaSet, and a ReplicaSet manages Pods. If you need updates and rollback, use a Deployment; if you only need a simple replica guarantee, a ReplicaSet alone suffices. Workloads that are stateful and require stable identifiers and ordering use a StatefulSet instead, but we will cover that comparison in #3. A Deployment walkthrough can be found in hands-on track #4.
Service: a stable entry point for a set of Pods #
A Pod’s IP changes every time it dies and is restarted. Pointing directly at a Pod’s IP therefore means communication will break before long. A Service is a resource that places an unchanging virtual IP and DNS name in front of multiple Pods, letting clients reach the same address even as the Pods behind it turn over. A Service identifies the set of Pods it routes traffic to by label selector and distributes requests across them.
A Service has three main types depending on exposure scope.
- ClusterIP. The default type, reachable only from inside the cluster. Used for communication between internal services
- NodePort. Opens a specific port on each node so the cluster can be reached from outside via the node IP
- LoadBalancer. Attaches a cloud provider’s external load balancer to expose it to the internet. The cloud-controller-manager creates the actual LB
The differences between Service types are also frequently tested. If it’s internal-only, classify it as ClusterIP; if it’s externally exposed, as NodePort or LoadBalancer. A Service walkthrough is laid out in hands-on track #5.
Namespace and label/selector #
Namespace: logical partitioning of the cluster #
A Namespace is a resource that divides a single physical cluster into multiple logical spaces. It isolates resources by team or by environment (dev, staging, prod) and lets you put resources with the same name in different Namespaces. ResourceQuota and RBAC can also be applied per Namespace to separate resources and permissions. Default Namespaces like kube-system contain Kubernetes’ own components. Note that a Namespace is a purely logical partition; cluster-wide resources such as nodes do not belong to any Namespace.
label and selector: label-based grouping #
A label is a key-value tag attached to a resource (e.g., app=nginx, env=prod), and a selector is a query that identifies a set of resources by those labels. Most relationships in Kubernetes are built on labels. When a ReplicaSet selects the Pods it manages, or when a Service selects the Pods it routes traffic to, the selector matches on labels to determine the target group. This loose coupling by label rather than by name is what gives Kubernetes its flexibility.
Exam point: component role matching #
The most common form in Domain 1 is the matching question that asks “which component does this job” or “what is this component’s role.” Memorizing the one-line summaries below will let you answer a good number of these questions.
| Component / Resource | One-line role |
|---|---|
| kube-apiserver | The gateway for all communication. The only one that accesses etcd directly |
| etcd | The key-value store holding cluster state |
| kube-scheduler | Decides which node a new Pod goes on |
| kube-controller-manager | The reconciliation loop matching desired to current |
| cloud-controller-manager | Cloud provider integration (LB, nodes, storage) |
| kubelet | Node agent. Guarantees Pod execution and reports status |
| kube-proxy | Implements Service networking (iptables/IPVS) |
| container runtime | Pulls images and actually runs containers (containerd) |
| Pod | The smallest deployable unit. A shell holding one or more containers |
| ReplicaSet | Maintains the replica count |
| Deployment | Manages ReplicaSets + rolling updates, rollback |
| Service | A stable entry point for a set of Pods. Connects via label selector |
| Namespace | Logical partitioning of the cluster |
Wrap-up #
What we nailed down in this post:
- A cluster is divided into the control plane (the brain) and worker nodes (the laborers). Which component sits on which side is the exam point
- control plane. kube-apiserver (gateway), etcd (state store), kube-scheduler (placement decision), kube-controller-manager (reconciliation), cloud-controller-manager (cloud integration)
- worker node. kubelet (node agent), kube-proxy (Service networking), container runtime (containerd)
- declarative model. Declare a desired state and the reconciliation loop matches the current state to it. The basis of self-healing
- workload hierarchy. A Deployment manages a ReplicaSet and a ReplicaSet manages Pods. If you need updates and rollback, use a Deployment
- Service provides a stable entry point to a set of Pods via label selector (ClusterIP, NodePort, LoadBalancer), and Namespace divides the cluster logically
Next: Kubernetes Fundamentals 2 #
With the architecture and core resources nailed down, we now step into the mechanisms that operate on top of them.
In #3 Kubernetes Fundamentals 2: API, Containers, Scheduling we’ll cover the Kubernetes API and object structure, the basics of containers and images, and the criteria the scheduler uses to pick a node (resource requests, selectors, affinity, taints, tolerations). A good companion practical piece is K8s hands-on track #1, the starting point for confirming cluster structure with your own hands.