Kubernetes is an open-source system for automating the deployment, scaling, and management of containerised applications. It solves the problem of running software reliably across a cluster of machines — a group of computers that work together as a single system. Understanding its core concepts and architecture is the absolute foundation for passing the CKAD exam, because every exam question, whether about pods, deployments, services, or configuration, builds on this mental model.
Jump to a section
A simple way to picture Kubernetes Core Concepts and Architecture
A restaurant kitchen is a complex system of stations, tools, and people working together to serve a single meal. The head chef is the orchestrator, but they don't chop every vegetable or stir every pot. Instead, the kitchen is organised into stations: the grill station, the salad station, the pastry station. Each station has its own equipment, its own recipes, and its own cook. The head chef gives a command — "fire table six, medium-rare steak with a side salad" — and the stations work in parallel. The grill cook sears the steak. The salad cook tosses greens. The pastry cook plates a dessert that was prepared earlier. The head chef doesn't care which specific grill cook is on shift tonight; they just need a cook who can run the grill station. If one cook calls in sick, a new cook steps in and picks up exactly where the last one left off, because every station is standardised and every recipe is documented. The kitchen itself is the platform: the stoves, the fridges, the prep tables, the ventilation hoods. The head chef uses a ticket system — the order tickets hung on the rail — to decide what to cook next, how to allocate resources, and when to pivot if something burns. That ticket system is the API of the kitchen: a standard way to declare what you want, without having to shout across the room or rewrite the recipe each time. The head chef does not personally stir the sauce; the head chef manages the flow of tickets and makes sure each station has what it needs. This is Kubernetes. Kubernetes does not run your application directly. It provides a standard platform — the kitchen — and a standard way to declare what you want — the ticket system — so that your application can run reliably, scale up when more customers arrive, and recover when a cook (a server) fails.
This is the essence of Kubernetes architecture: a control plane (the head chef) that receives your desired state (the ticket), and a set of worker nodes (the stations) that actually do the work. The ticket is your application definition, written in YAML or JSON. The head chef compares the ticket to the current reality — is the steak medium-rare? Is the salad on the plate? — and takes action to make reality match the ticket. If the grill cook’s station catches fire, the head chef moves the ticket to a different grill station. If three more tables order steaks, the head chef assigns more cook capacity to the grill station. This is the core loop of Kubernetes: observe the current state, compare it to the desired state, and take action to close the gap. It is called the reconciliation loop. The restaurant kitchen analogy is powerful because it maps directly to every major concept: pods are the dishes, nodes are the stations, deployments are the recipes, services are the waiters who connect customers to the correct station, and the API server is the ticket rail where all orders are posted.
Kubernetes is often described as an orchestrator. To understand what that means, you must first understand the problem it solves. Before Kubernetes, teams deployed applications directly onto physical servers or virtual machines. If the application crashed, someone had to log in manually, restart it, and hope it came back. If traffic spiked, someone had to provision a new server, install the software, and add it to the load balancer. If the server failed, the application was down until a new server was ready. This process was slow, error-prone, and required human babysitting.
Kubernetes changes that. You tell Kubernetes what your application should look like — for example, "run three copies of my web server, expose them on port 80, and if one crashes, start a new one immediately" — and Kubernetes makes it happen. It constantly watches the current state of the system and compares it to the desired state you declared. When they differ, Kubernetes takes action to make them match. This is called the reconciliation loop, and it is the single most important concept in Kubernetes.
Now let's build the architecture piece by piece.
A Kubernetes cluster consists of two main parts: the control plane and the worker nodes. The control plane is the brain — it makes global decisions about the cluster. The worker nodes are the muscles — they actually run your applications.
The control plane runs several components. The most important is the kube-apiserver (API server). This is the front door to the cluster. All communication, whether from the command-line tool kubectl, from internal components, or from external systems, goes through the API server. It validates requests, authenticates users, and stores the desired state in etcd, a distributed key-value store. Etcd is the cluster's source of truth. If etcd is corrupted or lost, the cluster has no memory of what it should be running. Backing up etcd is therefore a critical operational task.
The scheduler is another control plane component. It decides which worker node should run a new application instance. It looks at resource requirements — CPU, memory, any constraints like "must run in a specific data centre" — and picks the best node. The controller manager runs the controllers — the background loops that monitor the state of various resources and act when reality deviates from the desired state. For example, the node controller checks if a worker node has stopped reporting and, if so, marks it as dead and reschedules its work elsewhere.
Worker nodes are simpler. Each worker node runs two main components: the kubelet and the kube-proxy. The kubelet is an agent that communicates with the control plane. It receives instructions from the API server — for example, "start a container with this image" — and uses the container runtime (like containerd or Docker) to actually start the container. The kubelet also reports back the status of the node and its containers. The kube-proxy manages network rules so that traffic can reach your containers from inside or outside the cluster.
Applications run in pods. A pod is the smallest deployable unit in Kubernetes. It is a wrapper around one or more containers that share a network namespace — meaning they share an IP address and can talk to each other via localhost. Usually, a pod contains a single container, but there are patterns where a helper container (called a sidecar) runs alongside the main container to handle logging, monitoring, or proxying.
Pods are ephemeral. They can be created, destroyed, rescheduled, and replaced at any time. Because of this, you almost never work with pods directly. Instead, you use higher-level abstractions called workloads. The most common workload is a Deployment. A Deployment manages a set of identical pods — called a replica set — and ensures the desired number of pods are running at all times. You define the pod template inside the Deployment, and the Deployment controller creates, updates, and scales pods based on that template. For example, if you define a Deployment with 3 replicas and one pod crashes, the Deployment controller sees that the actual count is 2 while the desired count is 3, and it creates a new pod to replace the failed one.
A Service is an abstraction that provides a stable network endpoint for a set of pods. Because pods come and go with different IP addresses, you cannot rely on a pod's IP directly. A Service selects pods using labels — key-value pairs attached to pods — and provides a single IP address or DNS name that always points to the healthy pods behind it. There are different types of Services: ClusterIP (internal-only), NodePort (exposes a port on each node's IP), LoadBalancer (provisions an external load balancer), and ExternalName (returns a DNS record).
To make configuration dynamic, Kubernetes provides ConfigMaps and Secrets. A ConfigMap stores non-sensitive configuration data like environment variables or configuration files. A Secret stores sensitive data like passwords or API keys, and it is base64-encoded (but not encrypted by default — you would need encryption at rest). You attach ConfigMaps and Secrets to pods so that your application can read configuration without hardcoding it in the container image.
Storage is handled by Volumes. Containers write to ephemeral storage by default — when the pod restarts, the data is gone. A Volume is a directory that persists across container restarts within a pod. For data that must survive pod restarts, you use PersistentVolumes (PVs) and PersistentVolumeClaims (PVCs). A PV is a piece of storage in the cluster provisioned by an administrator. A PVC is a request for storage by a user. Kubernetes binds PVCs to matching PVs automatically.
Namespaces are virtual clusters within a physical cluster. They allow you to divide resources between teams, environments (dev, stage, prod), or projects. Objects in different namespaces are isolated by default — a pod in namespace A cannot directly reach a pod in namespace B unless a Service or network policy explicitly allows it.
Finally, the command-line interface kubectl is how you interact with the Kubernetes API. You use kubectl to create, read, update, and delete resources, to view logs, to exec into containers, and to troubleshoot problems. Almost every CKAD question involves kubectl in some form. Mastery of kubectl is the single most practical skill for the exam.
This architecture — control plane, worker nodes, pods, workloads, services, configuration, storage, namespaces, and kubectl — forms the complete mental model you need for the CKAD. Every exam objective maps to one or more of these components.
Declare Desired State
You write a YAML or JSON file that describes the state you want, for example a Deployment with 3 replicas of a container image. This file is your desired state specification. You submit it to the API server using kubectl apply -f filename.yaml. The API server validates the file and stores it in etcd.
API Server Stores the Specification
The API server saves your specification in etcd, the cluster's distributed key-value store. etcd acts as the single source of truth for what the cluster should look like. If etcd is lost, the cluster forgets everything. This step ensures that even if the control plane restarts, it knows what you asked for.
Scheduler Assigns Pods to Nodes
The scheduler watches the API server for new pod definitions that have not yet been assigned to a node. It evaluates constraints like resource requirements, node affinity rules, and taints/tolerations. It picks the best node and updates the pod object in etcd with the node name. This is called binding.
Kubelet Creates the Container
The kubelet on the chosen worker node sees the bound pod object via the API server. It instructs the container runtime (e.g., containerd) to pull the container image and start the container. The kubelet then monitors the container's health and reports status back to the API server.
Reconciliation Loop Maintains the State
Once the pod is running, controllers in the control plane continuously monitor the actual state of the cluster. If a pod crashes, the ReplicaSet controller sees that the actual count is below the desired count and creates a new pod. If the container exits with an error, the kubelet restarts it. The loop never stops watching.
Service Provides Stable Network Access
When you create a Service, Kubernetes assigns it a stable virtual IP (ClusterIP) and sets up kube-proxy rules on every worker node. The Service selector matches labels on the pods. Traffic sent to the Service IP is forwarded to a healthy pod. This decouples the network endpoint from the pod lifecycle.
A medium-sized e-commerce company called ShopFast runs its online store on Kubernetes. The company has a microservices architecture: one service handles user accounts, another handles product catalogue, another handles shopping cart, another handles payments, and another handles order fulfilment. Each service is a separate container image.
Six months ago, ShopFast deployed everything on a single virtual machine. Every Friday at 3:00 PM, traffic spiked as people did their weekend shopping. The application slowed down, sometimes crashed, and the on-call engineer had to manually restart services or provision a larger VM. It was stressful, slow, and expensive.
The team decided to migrate to Kubernetes. Here is what they actually did, step by step.
First, the team installed a Kubernetes cluster. They chose a managed service like Amazon EKS, Google GKE, or Azure AKS so they did not have to manage the control plane themselves. The cluster came with three worker nodes, each a virtual machine with 4 CPUs and 16 GB of RAM.
The team wrote a Deployment YAML file for each microservice. The product catalogue Deployment spec looked roughly like this: - apiVersion: apps/v1 - kind: Deployment - metadata: name: catalogue - spec: replicas: 3 - spec: selector: matchLabels: app: catalogue - spec: template: metadata: labels: app: catalogue - spec: template: spec: containers: - name: catalogue image: shopfast/catalogue:v2 port: 8080
They applied this file with kubectl apply -f catalogue.yaml. Kubernetes created three identical pods running the product catalogue service. The team did the same for the other four services.
Next, the team created a Service for each microservice so that the services could talk to each other reliably. For the product catalogue, they created a ClusterIP Service that selects pods with label app: catalogue and exposes port 80. The user account service could now call catalogue.shopfast.svc.cluster.local:80 to reach the product catalogue. No more hardcoded IP addresses.
The team created a ConfigMap for configuration values that varied between environments, like the database connection string for the development cluster versus the production cluster. They created a Secret for the payment API key and mounted it into the payment service pods.
To handle the Friday traffic spike, the team set up a HorizontalPodAutoscaler (HPA). The HPA watches CPU usage on the pods. When CPU usage exceeds 70%, the HPA increases the replica count in the Deployment from 3 to 6. When usage drops, it scales back down. The team tested this by running a load generator, saw the pods scale automatically, and felt confident for the next Friday.
When a bug was discovered in the product catalogue service — orders were failing because a new feature broke the legacy API — the team built a new image tagged v2.1 and updated the Deployment: - kubectl set image deployment/catalogue catalogue=shopfast/catalogue:v2.1
Kubernetes performed a rolling update. It created new pods with the v2.1 image, waited until they were healthy, then terminated the old v2 pods. Zero downtime. If the update had failed, a single command — kubectl rollout undo deployment/catalogue — would have reverted to the previous version.
A worker node failed one night due to a hardware fault. The kubelet on that node stopped reporting to the control plane. After a timeout (usually 40 seconds), the node controller marked the node as NotReady. The pods on that node were rescheduled onto healthy nodes because the Deployment’s replica count was not satisfied. The application stayed up. The team received an alert about the node but did not need to page anyone at 3 AM.
This real scenario illustrates exactly what Kubernetes does: it takes your declarative specification (the YAML files) and constantly reconciles the actual state of the cluster to match that specification. The IT professional’s job shifts from manual server babysitting to writing and managing those YAML files — a skill called infrastructure as code.
The CKAD exam is a hands-on, performance-based test taken in a live Kubernetes cluster. You are given a terminal with kubectl preconfigured, and you must complete tasks within a time limit (typically 2 hours for approximately 20 questions). The exam focuses on your ability to use the Kubernetes API and CLI, not on theoretical knowledge. Here is what you need to know about how CKAD tests the core concepts and architecture.
The exam expects you to be fluent with kubectl. You must be able to create, get, describe, edit, delete, and apply resources. You must know how to use imperative commands (kubectl run, kubectl create deployment, kubectl expose) to solve problems quickly, because imperative commands are often faster than writing YAML files from scratch. The declarative approach (kubectl apply -f file.yaml) is also important, especially for multi-resource scenarios.
Key concepts that appear in nearly every exam session:
Pods: You will be asked to create a pod manually, list pods with specific labels, get logs from a pod, execute a command inside a pod (kubectl exec), and troubleshoot a failing pod (check events, describe pod, check container status).
Deployments: You will be asked to create a deployment, scale it (kubectl scale deployment --replicas=5), update its image, perform a rolling update, check rollout status, and roll back a failed deployment.
Services: You will be asked to expose a deployment (kubectl expose deployment), create a Service of a specific type (ClusterIP, NodePort, LoadBalancer), and verify that pods can reach the Service.
ConfigMaps and Secrets: You will be asked to create a ConfigMap or Secret, inject it into a pod as environment variable or mounted volume, and verify the configuration is present in the container.
Namespaces: You will be asked to create objects in a specific namespace, query objects across namespaces (--all-namespaces), and use context switching (kubectl config set-context).
Common exam question patterns: - 'Create a pod named nginx-pod with image nginx:1.25, exposed on port 80.' - 'Create a deployment named web-app with 3 replicas using image myapp:v1. Perform a rolling update to image myapp:v2. If the update fails, roll back.' - 'Create a ConfigMap named app-config with key LOG_LEVEL=debug. Create a pod that uses this ConfigMap as an environment variable.' - 'Expose the existing deployment frontend as a NodePort service on port 30080.' - 'Troubleshoot a pod that is in CrashLoopBackOff. Check logs and events, identify the issue, and fix it.'
Traps the exam sets:
Spelling and case sensitivity: pod vs Pod, namespace vs Namespace. Kubernetes resource names and fields are case-sensitive. Always use lowercase for resource types in kubectl commands (kubectl get pod, not kubectl get Pod).
Image tags: If you do not specify a tag, :latest is implied. Some questions expect a specific tag. Read the question carefully.
Port numbers: When exposing a Service, you must specify the targetPort (the port the container listens on) and the port (the port the Service listens on). These can be different. The exam loves asking you to map a Service port 80 to a container port 8080.
Labels and selectors: A Service will not route traffic to pods if the selector does not match the pod labels exactly. Double-check the key-value pairs.
Deletion and recreation: Some questions require you to edit a resource, but certain fields (like pod template in a deployment) are immutable after creation. You must delete and recreate the resource, not edit in place. Know the difference.
Key definitions to memorise:
Pod: smallest deployable unit, runs one or more containers sharing network and storage.
Deployment: manages a replica set, enables rolling updates and rollbacks.
Service: stable network endpoint for a set of pods, defined by label selector.
ConfigMap: non-sensitive configuration data.
Secret: sensitive data, base64-encoded.
Namespace: virtual cluster for resource isolation.
kubectl: CLI for communicating with the Kubernetes API server.
You will not be tested on control plane internals like etcd raft consensus or the scheduler algorithm. The exam is purely about using the API to manage application workloads. However, understanding the architecture helps you troubleshoot when things go wrong — which is exactly what the exam simulates.
A Kubernetes cluster has two parts: the control plane (the brains) and worker nodes (the muscles).
All communication with the cluster goes through the API server; it is the single front door for kubectl and internal components.
Pods are the smallest deployable units and are ephemeral; you should manage them via higher-level abstractions like Deployments.
A Deployment uses a reconciliation loop to ensure the actual number of running pods matches your desired count, and it supports rolling updates and rollbacks.
A Service provides a stable IP and DNS name to reach a set of pods, decoupling network communication from pod lifecycle.
ConfigMaps and Secrets decouple configuration from container images, making applications portable across environments.
kubectl is your primary tool; master its imperative commands (run, create, expose, scale) to answer exam questions quickly.
Namespaces provide resource isolation within a cluster; you must use the -n flag or set context to operate in the correct namespace.
These come up on the exam all the time. Here's how to tell them apart.
Pod
Smallest deployable unit in Kubernetes
Ephemeral — not resilient to node failure by itself
You create pods directly only for testing or debugging
Deployment
Manages a set of identical pods via a ReplicaSet
Provides self-healing, scaling, and rolling updates
You should use Deployments for production workloads
ClusterIP Service
Exposes the Service on a cluster-internal virtual IP
Only accessible from within the cluster
Default Service type, used for internal communication between microservices
NodePort Service
Extends ClusterIP by exposing a static port on each node's IP
Accessible from outside the cluster using nodeIP:NodePort
Suitable for development or simple ingress, but not for production load balancing
ConfigMap
Stores non-sensitive configuration data like environment variables
Data is stored in plain text (base64 encoded in YAML, but not encrypted)
Used for app configuration strings, feature flags, or config files
Secret
Stores sensitive data like passwords, API keys, or tokens
Data is base64-encoded by default, but you should enable encryption at rest
Has mechanisms like encryption at rest and integration with external secrets stores
Imperative kubectl Commands
You tell Kubernetes exactly what to do: create, delete, expose, scale
Commands are faster to type in the exam but harder to repeat or version-control
Examples: kubectl run, kubectl create deployment, kubectl expose
Declarative kubectl Commands
You give Kubernetes a YAML file defining the desired state, and it computes the difference
Commands are slower to type but easier to reuse, audit, and automate
Examples: kubectl apply -f file.yaml, kubectl diff -f file.yaml
etcd
Distributed key-value store that holds all cluster data
Not directly interacted with by users or kubectl
Requires regular backups and monitoring for cluster health
API Server
Front-end to etcd that validates and processes all API requests
The only component that talks to etcd directly
Exposes the REST API that kubectl and internal components use
Mistake
Pods and containers are the same thing, and a pod is just a renamed container.
Correct
A pod is a wrapper around one or more containers that share a network namespace and storage. A pod is the smallest unit in Kubernetes, not a container. Containers are run inside pods, and a pod often contains exactly one container, but they are distinct concepts.
Beginners come from Docker where the container is the unit of deployment. Kubernetes abstracts one level higher to allow multi-container patterns like sidecars.
Mistake
Services are optional because you can connect to pods directly by their IP address.
Correct
Services are essential because pod IP addresses change when pods are recreated. A Service provides a stable virtual IP and DNS name that always points to healthy pods, enabling reliable communication even as pods come and go.
When testing locally with Docker, containers keep the same IP until removed. In a dynamic cluster, pods are ephemeral, so direct IP reliance breaks quickly.
Mistake
The kubelet is the same as the container runtime, and you need Docker installed on every node.
Correct
The kubelet is an agent that communicates with the control plane and tells the container runtime what to run. The container runtime (like containerd or CRI-O) actually creates and manages containers. Docker is just one possible runtime, and newer Kubernetes versions have deprecated Docker in favour of CRI-compliant runtimes.
Docker is the most well-known container tool, so beginners assume it is mandatory. Kubernetes has moved to a standardised container runtime interface (CRI) that supports multiple runtimes.
Mistake
If a pod is in CrashLoopBackOff, the solution is always to delete and recreate the pod.
Correct
CrashLoopBackOff means the container inside the pod keeps crashing and Kubernetes is backing off from restarting it. The correct approach is to check the logs (kubectl logs podname) and events (kubectl describe pod podname) to find the root cause — typically a misconfiguration, missing dependency, or application bug. Deleting the pod without fixing the underlying issue will result in the same crash loop.
Beginners are used to 'turn it off and on again' as a fix. In Kubernetes, the pod will be automatically rescheduled by the deployment, so delete only helps if there is a transient issue, not a persistent configuration error.
Mistake
YAML is the only format for Kubernetes resource definitions, and indentation does not matter because JSON is used internally.
Correct
YAML indentation is critical. Incorrect whitespace leads to parsing errors. Kubernetes also accepts JSON as input to kubectl apply. Both formats are valid, but YAML is more common for readability. Indentation errors are the most frequent cause of failed kubectl commands during the exam.
YAML looks simple but is whitespace-sensitive. Beginners often skip learning proper indentation because they assume the system will interpret intent from the structure.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
A pod stays Pending when the scheduler cannot find a suitable node. Common reasons: the node has insufficient CPU or memory, there is a taint that repels the pod, or a PersistentVolumeClaim is not bound.
kubectl create is imperative — it creates a resource and fails if it already exists. kubectl apply is declarative — it creates the resource if absent, or updates it if present, based on the configuration provided.
Use kubectl exec -it podname -- command. For example, kubectl exec -it my-pod -- /bin/sh opens an interactive shell. Add -c containername if the pod has multiple containers.
You specify both. The spec.ports[].port is the port the Service listens on. The spec.ports[].targetPort is the port the container listens on. They can be different, and the Service maps port to targetPort.
The most common cause is a label mismatch. The Service's selector must exactly match the labels on the pods. Use kubectl get pods --show-labels to check pod labels, and verify that the Service selector uses the same key-value pairs.
After a timeout (default 40 seconds), the node controller marks the node as NotReady and eventually as Unreachable. Pods that were on that node are rescheduled onto healthy nodes if they are managed by a controller like a Deployment or StatefulSet.
You've finished Kubernetes Core Concepts and Architecture. Continue through the CKAD study guide to build a complete picture of the exam.
Done with this chapter?