SaveMyCert
Log in
5 of 5 free questions left today·for unlimited practice
Kubernetes Fundamentals

Kubernetes Core Concepts: Architecture, Pods, Deployments, and Services

14 min readKCNA · Kubernetes FundamentalsUpdated

Kubernetes core concepts are the building blocks of every cluster: a control plane that stores and enforces desired state, worker nodes that run containers, and a small set of API objects - Pods, ReplicaSets, Deployments, Services, and namespaces - that describe what should run and how it is reached. Kubernetes works declaratively: you submit a manifest describing the state you want, and controllers continuously reconcile reality toward it. The KCNA exam leans heavily on this topic. Many Kubernetes Fundamentals questions ask which component performs a given job, what a Pod actually is, or how a Deployment relates to a ReplicaSet. This lesson walks through the cluster architecture component by component, then the workload and networking objects, and finally the reconciliation loop that ties them together, so you can answer recognition-style questions quickly and confidently.

What you’ll learn
  • Describe the roles of the control plane and worker nodes in a Kubernetes cluster
  • Identify what the API server, etcd, scheduler, controller-manager, kubelet, and kube-proxy each do
  • Explain why the Pod is the smallest deployable unit and what its containers share
  • Distinguish Pods, ReplicaSets, and Deployments and pick the right object for a scenario
  • Explain how Services provide stable networking and how labels and selectors connect objects
  • Summarize the desired-state reconciliation loop behind declarative configuration

One cluster, two kinds of nodes

A Kubernetes cluster is a set of machines, called nodes, that run containerized applications. Every node plays one of two roles. Control plane nodes host the components that make global decisions: they expose the API, store cluster state, decide where workloads run, and detect and respond to events such as a crashed container. Worker nodes do the actual running: each one hosts the agents that start containers, keep them healthy, and route traffic to them.

The split matters because it explains the answer to a whole family of exam questions. When you are asked which component schedules a Pod, stores state, or forwards Service traffic, the first filter is: does that job belong to the brain of the cluster or to the muscle? The table below is the map you should memorize.

Where it runsComponentOne-line job
Control planekube-apiserverFront door for all cluster communication
Control planeetcdKey-value datastore holding all cluster state
Control planekube-schedulerPicks a node for each new Pod
Control planekube-controller-managerRuns the reconciliation controllers
Worker nodekubeletStarts Pods and keeps their containers running
Worker nodekube-proxyPrograms network rules so Service traffic reaches Pods
Worker nodeContainer runtimeActually runs the containers (for example containerd or CRI-O)

Note that the kubelet and a container runtime also run on control plane nodes in most setups, which is how the control plane components themselves can run as Pods. In managed cloud offerings such as EKS, AKS, and GKE, the provider operates the control plane for you and you mostly interact with worker nodes and the API.

Inside the control plane

The kube-apiserver is the front end of the control plane and the only component every other part of the system talks to. All communication - from kubectl, from the kubelet on each node, from controllers, from dashboards - flows through its REST API. It authenticates each request, authorizes it, validates the object, and persists it. Nothing bypasses it: components never talk to each other directly about cluster state, and clients never talk to etcd directly.

etcd is a consistent, distributed key-value store that acts as the cluster's single source of truth. Every object you create - Pods, Deployments, Services, ConfigMaps, Secrets - is stored in etcd. Only the API server reads from and writes to etcd. If etcd loses its data and you have no backup, the cluster forgets everything it was supposed to be running, which is why backing up etcd is the canonical cluster backup strategy.

The kube-scheduler watches for newly created Pods that have no node assigned and selects a node for each one. It filters out nodes that cannot fit the Pod (insufficient CPU or memory, unsatisfied constraints) and scores the remainder to pick the best. Crucially, the scheduler only makes the placement decision; it does not start containers.

The kube-controller-manager runs the built-in controllers as a single process: the ReplicaSet controller, the Deployment controller, the node controller that notices unresponsive nodes, the job controller, and many more. Each controller runs a watch loop that compares desired state with observed state and issues API requests to close the gap. A separate cloud-controller-manager holds the cloud-provider-specific controllers, such as the one that provisions a cloud load balancer for a Service.

What runs on every worker node

The kubelet is the node agent. It registers the node with the API server, watches for Pods scheduled to its node, and makes sure the containers described in each PodSpec are running and healthy. It instructs the container runtime to pull images and start containers, runs liveness and readiness probes, and reports Pod and node status back to the API server. Remember the boundary: the kubelet manages containers that belong to Kubernetes Pods, not arbitrary containers someone started by hand on the node.

The container runtime is the software that actually runs containers. Kubernetes talks to it through the Container Runtime Interface (CRI), a standard API that lets any conformant runtime plug in. The common choices are containerd and CRI-O. Docker Engine is not a CRI runtime by itself; Kubernetes removed its special-case Docker integration (dockershim) in version 1.24, and Docker-built images continue to run fine because they follow the OCI image standard.

kube-proxy runs on each node and implements the Service abstraction at the network level. It watches Services and their backing endpoints through the API server and programs forwarding rules on the node - typically iptables or IPVS rules - so that traffic sent to a Service's virtual IP is routed to one of the healthy Pods behind it. Despite the name, it usually does not proxy packets through itself; it programs the kernel to do the forwarding.

A useful exam heuristic: if a question is about deciding or recording, the answer is a control plane component; if it is about running containers or moving packets on a node, the answer is the kubelet, the runtime, or kube-proxy.

Pods: the smallest deployable unit

A Pod is the smallest deployable unit in Kubernetes. You never deploy a bare container; you deploy a Pod that wraps one or more containers. The containers in a Pod are always scheduled together onto the same node, and they share two things: a network namespace - one IP address, one port space, so they can reach each other on localhost - and optionally volumes, shared storage directories that any container in the Pod can mount.

Most Pods hold a single application container. Multi-container Pods exist for tightly coupled helpers: a log-shipping sidecar, a proxy that terminates TLS in front of the app, or an init container that runs setup work to completion before the main container starts. If two processes scale independently or do not need to share an IP and volumes, they belong in separate Pods.

A minimal Pod manifest looks like this:

apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    app: web
spec:
  containers:
  - name: web
    image: nginx:1.27
    ports:
    - containerPort: 80

Pods are ephemeral. They are not resurrected when they die: if a node fails, the Pods on it are lost, and a replacement Pod is a new object with a new name and a new IP. That is why you almost never create Pods directly in production. Instead you create a controller object such as a Deployment, which creates and replaces Pods for you, and a Service, which gives clients a stable address in front of the churn. Both patterns follow in the next sections.

ReplicaSets and Deployments: from replicas to rollouts

A ReplicaSet has one job: keep a specified number of identical Pod replicas running. It uses a label selector to count the Pods it owns; if there are too few it creates more from its Pod template, and if there are too many it deletes the extras. This gives you self-healing and horizontal scale, but nothing else - a ReplicaSet has no concept of versions or updates.

A Deployment sits one level above. It manages ReplicaSets and provides declarative rolling updates and rollbacks. When you change a Deployment's Pod template - for example, a new image tag - the Deployment creates a new ReplicaSet and gradually scales it up while scaling the old one down, keeping the app available throughout. Because old ReplicaSets are retained as revision history, kubectl rollout undo deployment/web can roll back to the previous version. In everyday work you create Deployments and let them own the ReplicaSets; you rarely create a ReplicaSet directly.

ObjectWhat it gives youWhen you use it
PodOne deployable unit of one or more containersAlmost never directly; debugging and one-off tasks
ReplicaSetKeeps N identical Pod replicas aliveRarely directly; created and managed by Deployments
DeploymentDeclarative rollouts, rollbacks, and scaling of ReplicaSetsThe default choice for stateless applications

Other workload controllers cover other shapes at the same conceptual level: a StatefulSet for Pods that need stable identities and storage, a DaemonSet for one Pod on every node (agents such as log collectors), and a Job or CronJob for run-to-completion work. For KCNA you only need to recognize which controller fits which description.

Services: stable networking for ephemeral Pods

Pods come and go, and every new Pod gets a new IP address. Clients cannot chase that churn, so Kubernetes provides the Service: an object that defines a stable virtual IP (the ClusterIP) and a stable DNS name in front of a dynamic set of Pods. The Service selects its backend Pods with a label selector; whichever Pods currently match the selector and pass their readiness checks receive the traffic. The set of matching Pod addresses is tracked in EndpointSlice objects, and kube-proxy on every node programs the rules that spread connections across them.

Service types build on each other, and the exam expects you to match type to scenario:

  • ClusterIP (the default): a virtual IP reachable only inside the cluster. Use it for internal service-to-service traffic.
  • NodePort: additionally opens the same port on every node, so external clients can reach the Service at any node's IP on that port.
  • LoadBalancer: additionally asks the cloud provider to provision an external load balancer that forwards to the Service. The standard way to expose an app publicly on a managed cloud cluster.
  • ExternalName: no proxying at all; it returns a DNS CNAME pointing at an external hostname.

In-cluster DNS makes discovery simple: a Service named db in namespace prod resolves as db from inside that namespace, or as db.prod.svc.cluster.local from anywhere in the cluster. For HTTP routing concerns such as virtual hosts and paths, an Ingress (or the newer Gateway API) sits in front of Services, but the Service remains the stable target underneath.

Namespaces, labels, and selectors

Namespaces divide one physical cluster into virtual slices. Object names must be unique only within a namespace, so team A and team B can each have a Deployment called api without colliding. Namespaces are also the scope for access control and resource limits, which makes them the standard boundary between teams, environments, or applications sharing a cluster. Every cluster starts with a few: default (where objects land when you specify nothing), kube-system (Kubernetes' own components), kube-public, and kube-node-lease. Not everything is namespaced - nodes and PersistentVolumes, for example, are cluster-scoped.

Labels are key-value pairs attached to objects, such as app: web or tier: frontend. They carry no meaning to Kubernetes by themselves; their power is that other objects select on them. A selector is a query over labels, and it is the glue of the whole object model: a ReplicaSet's selector.matchLabels decides which Pods it counts as its replicas, and a Service's selector decides which Pods receive its traffic. You can use the same mechanism interactively: kubectl get pods -l app=web lists only the matching Pods.

Two distinctions are worth locking in for the exam. First, labels are for selection; annotations are also key-value metadata but are for non-identifying information (build numbers, tool configuration) and cannot be used in selectors. Second, namespaces isolate names and policy, not the network: by default, Pods in different namespaces can still reach each other, and restricting that traffic is the job of NetworkPolicies.

Declarative configuration and the reconciliation loop

Kubernetes is a declarative system. You do not send it a sequence of commands to execute; you send it a manifest - typically YAML - that describes the desired state, and you apply it with kubectl apply -f deployment.yaml. The API server validates the object and stores it in etcd. From that moment, a set of controllers works continuously to make the observed state of the cluster match what you declared. This watch-compare-act cycle is the reconciliation loop, and it never stops: it is not a one-time deployment script but a standing promise.

Walk through a concrete scenario. You apply a Deployment named web with replicas: 3. The Deployment controller sees it and creates a ReplicaSet; the ReplicaSet controller sees it needs three Pods and creates three Pod objects; the scheduler assigns each Pod to a node; the kubelet on each chosen node sees a Pod bound to it and tells the container runtime to pull the image and start the containers; kube-proxy updates its rules so the web Service can reach them. Now a worker node dies. The node controller marks it unhealthy, its Pods are eventually removed, the ReplicaSet controller observes two replicas where three are desired, and it creates a replacement Pod, which is scheduled onto a surviving node and started. Nobody paged an operator; the loop healed the gap.

This is why declared state beats imperative commands: the same manifest can be applied repeatedly with the same result, stored in version control, and reviewed like code - the foundation of GitOps. It is also the definition of self-healing that KCNA questions probe: Kubernetes does not prevent failures, it detects divergence from desired state and corrects it.

Tip. KCNA probes this topic almost entirely at recognition depth: expect questions of the form which component stores cluster state, which object is the smallest deployable unit, or what a Deployment adds on top of a ReplicaSet. Watch for trigger phrases: front door or single point of entry points to the kube-apiserver, key-value store points to etcd, assigns Pods to nodes points to the scheduler, and node agent points to the kubelet. Scenario stems about a stable address for changing Pods want a Service, and anything about self-healing or desired versus observed state wants the controller reconciliation loop. Distractors often swap the scheduler for the kubelet or claim kubectl talks to etcd directly - both are wrong.

Key takeaways
  • A Pod is the smallest deployable unit; its containers share one network namespace (one IP) and can share volumes.
  • The kube-apiserver is the front door: kubectl, the kubelet, and all controllers talk to the cluster only through it.
  • etcd is the cluster's key-value datastore and single source of truth; only the API server reads and writes it directly.
  • The kube-scheduler only picks a node for each Pod; the kubelet on that node actually starts the containers via the runtime.
  • A ReplicaSet keeps N identical Pods alive; a Deployment manages ReplicaSets to add rolling updates and rollbacks.
  • A Service gives a stable virtual IP and DNS name to an ever-changing set of Pods selected by labels.
  • Namespaces scope names, access, and quotas; labels plus selectors are the glue that connects Services and controllers to Pods.
  • Kubernetes is declarative: controllers continuously reconcile observed state toward the desired state stored in etcd, which is what self-healing means.

Frequently asked questions

What is the smallest deployable unit in Kubernetes?

The Pod. Kubernetes never runs a bare container; every container runs inside a Pod, which can hold one or more containers that are scheduled onto the same node together and share a single IP address, port space, and optionally volumes. In practice most Pods contain one main application container, with extra containers reserved for tightly coupled helpers such as sidecars.

What is the difference between a Deployment and a ReplicaSet?

A ReplicaSet only keeps a fixed number of identical Pod replicas running. A Deployment manages ReplicaSets on your behalf and adds declarative rolling updates and rollbacks: when you change the Pod template, the Deployment creates a new ReplicaSet and shifts replicas over gradually, keeping the old one as revision history so you can roll back. You normally create Deployments and let them own the ReplicaSets.

What does the kube-apiserver do?

The kube-apiserver is the front end of the control plane and the only component clients and other components communicate with. It exposes the Kubernetes REST API, authenticates and authorizes every request, validates objects, and persists them to etcd. Everything - kubectl commands, kubelet status reports, controller actions - flows through the API server.

Why do Pods need Services?

Because Pods are ephemeral: they are replaced rather than repaired, and each replacement gets a new IP address. A Service provides a stable virtual IP and DNS name in front of the Pods that match its label selector, so clients keep one address while the backing Pods scale, fail, and get replaced underneath it. kube-proxy programs the rules that spread traffic across the current healthy Pods.

What is etcd used for in Kubernetes?

etcd is the consistent, distributed key-value store where the entire cluster state lives: every Pod, Deployment, Service, ConfigMap, and Secret you create is persisted there. Only the kube-apiserver talks to etcd directly, and backing up etcd is the standard way to back up a cluster, because losing it means losing the record of everything the cluster should be running.

Is the scheduler responsible for starting containers?

No. The kube-scheduler only decides which node a new Pod should run on, by filtering out nodes that cannot fit it and scoring the rest. The kubelet on the chosen node is what actually starts the Pod, by instructing the container runtime (such as containerd or CRI-O) to pull the image and run the containers.

Test yourself on this topic
Practice questions with full explanations.
Practice now

Sign up free to mark lessons complete, bookmark topics and track your exam readiness.