Tutorials

How Kubernetes Works | Kubernetes Tutorial

Key Takeaways

  • Kubernetes runs application containers in Pods on worker nodes; the control plane coordinates scheduling and cluster-wide management.
  • You declare a desired state through API objects. Controllers repeatedly observe the cluster and request changes to bring reality closer to that state.
  • The scheduler chooses nodes, kubelets manage assigned Pods, and container runtimes start the containers.
  • A Deployment manages application replicas and updates. A Service gives clients a stable way to reach changing Pod backends.
  • Three requested replicas are a target, not an availability guarantee: recovery still needs capacity, working infrastructure, and valid configuration.

Kubernetes works by running containerized applications in Pods on worker nodes while a control plane coordinates where they run and what should exist. You declare a desired state through API objects, and controllers repeatedly compare that target with observed state and act to reduce the difference.

That continuous correction is called reconciliation. To understand Kubernetes, follow how its components cooperate to turn an application definition into running containers—and keep correcting things afterward. For the broader introduction, start with what Kubernetes is.

Kubernetes Architecture: Control Plane and Worker Nodes

A cluster combines a control plane with worker nodes, which can be physical or virtual machines. Creating a cluster establishes that infrastructure; deploying an application creates resources inside an existing cluster.

These are responsibilities, not necessarily separate machines in every setup. Development clusters can colocate components, while production control planes commonly span multiple machines for availability. A managed Kubernetes service can operate the control plane on your behalf and may also manage worker nodes.

CONTROL PLANE
kubectl ----> API server <----> etcd
                  ^  ^
                  |  +<------> scheduler
                  +<---------> controllers
                  ^
                  | Pod specifications / status
WORKER NODE       v
               kubelet --CRI--> runtime --> Pods
                  |                |
                  v                v
             CSI driver        CNI plugin
              (storage)      (Pod networking)

Service routing on nodes: kube-proxy or a replacement

The arrows show coordination, not application request traffic. Components exchange cluster state through the API server; controllers don't directly launch application processes.

What Runs on Kubernetes Worker Nodes?

Pods Group Containers That Run Together

A Pod is Kubernetes' smallest deployable computing unit. It contains one or more containers that run together on one node and share a network namespace, including IP addresses and ports. Containers within a Pod can reach one another through localhost.

Storage sharing isn't automatic. Containers can share data through explicitly configured volumes mounted into those containers. A Pod might contain just your application container, or tightly coupled containers that need this shared environment.

Kubelet and the Container Runtime Do Different Jobs

The kubelet is an agent on each node. It reconciles the Pod specifications assigned to that node, coordinates container execution, runs configured probes, and reports status. It doesn't choose which node a Pod should use.

The kubelet communicates with a container runtime through the Container Runtime Interface (CRI), the protocol between Kubernetes and a compatible runtime. Common choices include containerd and CRI-O.

Building an image with Docker doesn't make Docker Engine the node's CRI runtime. Kubernetes removed its built-in Docker Engine adapter, dockershim, in version 1.24; Docker-built images can still run with compatible runtimes. The official container runtime documentation explains the supported integrations, and our Kubernetes vs Docker comparison explains the distinction.

CNI, Service Routing, and CSI Supply Networking and Storage

The cluster's Pod network implementation provides Pod connectivity, commonly through Container Network Interface (CNI) plugins. kube-proxy implements Service traffic forwarding on many clusters, typically by maintaining networking rules on nodes. It's optional when the network implementation supplies a replacement; see the Kubernetes networking overview.

Storage integrations commonly use Container Storage Interface (CSI) drivers. These connect Kubernetes to storage systems and support operations such as attaching and mounting volumes, depending on the driver. They're distinct from both the container runtime and CNI; the volume documentation describes that boundary.

How the Kubernetes Control Plane Works

The API Server Exposes Shared Cluster State

kube-apiserver exposes the Kubernetes API. When you use kubectl or a Kubernetes client library to create, read, modify, or delete resources, requests go through this API. Other cluster components also use it to observe resources and submit changes.

You can run multiple API-server instances behind a load balancer. They share the cluster's backing state; adding API servers alone doesn't make the entire control plane highly available. The scheduler, controllers, and state store must also remain available.

The Scheduler Assigns Pods to Nodes

kube-scheduler watches for Pods without an assigned node. It filters out unsuitable nodes, scores suitable candidates, and records a placement decision through the API.

Placement considers resource requests and constraints such as affinity, taints, and storage requirements. If no node qualifies, the Pod remains unscheduled. The scheduler chooses placement; the node's kubelet and runtime perform execution. The scheduler documentation explains filtering and scoring.

Controllers Reconcile Individual Parts of the System

kube-controller-manager runs built-in controllers. Each controller watches relevant resources and takes action when observed state differs from its target. Examples include:

  • Deployment and ReplicaSet controllers: coordinate application updates and maintain requested Pod replica counts.
  • Node controller: notices and responds when nodes become unavailable.
  • EndpointSlice controller: maintains backend information linking selector-based Services to Pods.
  • ServiceAccount controller: creates the default ServiceAccount in each namespace.

A ServiceAccount is a workload identity, not a container of permanent credentials. Pod API credentials normally use short-lived tokens obtained through TokenRequest, mounted as projected volumes, and rotated by the kubelet. Automatically creating permanent token Secrets isn't the modern provisioning model; see ServiceAccounts and token provisioning.

Etcd Persists API State, Not Application Files

etcd is a separate distributed key-value store used to persist Kubernetes API state, including resource specifications and Secret objects. It isn't where Kubernetes stores your application's database rows or the files inside persistent volumes.

Cluster-state backups and application-data backups are therefore different responsibilities. If you operate the control plane yourself, include an etcd backup and recovery plan; the etcd operations guide covers those tasks.

Cloud Integration Is Optional

The optional cloud-controller-manager integrates with cloud-provider APIs for functions such as node information, routes, and load balancers. It isn't required merely because you use a third-party Kubernetes vendor. Managed services may supply this integration alongside the control plane; the cloud-controller-manager documentation explains its responsibilities.

Kubernetes Objects Describe the Desired State

An API object is a resource represented through the Kubernetes API. You commonly define resources in a YAML manifest: apiVersion selects an API group/version, kind identifies the resource type, and metadata identifies the object.

For resources such as Deployments, spec describes the desired state, while status reports observed state. Not every resource has both fields; ConfigMaps, for example, store configuration in data fields. The object documentation explains the conventions.

ResourceMain responsibilityWhat it doesn't do
PodGroups containers that run together on one node.Doesn't replace itself after deletion.
ReplicaSetMaintains a requested number of matching Pods.Doesn't manage application rollouts like a Deployment.
DeploymentManages ReplicaSets and application updates.Doesn't provide a stable network endpoint.
ServiceProvides a stable way to reach selected Pod backends.Doesn't create application Pods.

For a typical stateless application, create a Deployment rather than managing a ReplicaSet directly. ReplicationController is the legacy workload API; Deployment-managed workloads use ReplicaSets.

Example: A Three-Replica Deployment and a Service

To try this, use a non-production cluster with Linux worker nodes, configured kubectl access, and permission to create a namespace and workloads. Save the following two resources as demo.yaml. The example uses the official NGINX image.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      automountServiceAccountToken: false
      containers:
        - name: nginx
          image: nginx:stable
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 50m
              memory: 64Mi
          readinessProbe:
            httpGet:
              path: /
              port: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80

The Deployment requests three Pods with the label app: web. The Service selects Pods with that label in its namespace and exposes port 80 through a cluster-internal IP. The readiness probe checks HTTP responses before those Pods are considered ready to receive Service traffic.

Check your current context before creating anything, then apply the manifest and inspect the resulting resources:

kubectl config current-context
kubectl create namespace architecture-demo
kubectl -n architecture-demo apply -f demo.yaml
kubectl -n architecture-demo rollout status deployment/web --timeout=120s
kubectl -n architecture-demo get deployments,replicasets,pods,services,endpointslices

The rollout command waits for completion, with a 120-second timeout for this invocation; it doesn't guarantee the workload can start. When you're finished, remove the demo namespace and its resources:

kubectl delete namespace architecture-demo

How Reconciliation Brings the Replica Count Back to Three

  1. The API server accepts and persists the Deployment definition.
  2. The Deployment controller creates a ReplicaSet, whose controller requests the required Pod objects.
  3. The scheduler assigns unscheduled Pods to suitable nodes.
  4. Kubelets coordinate with runtimes to start containers; networking and storage integrations provide the configured infrastructure.
  5. If one Pod is deleted or enters a terminal failed state, the ReplicaSet requests a replacement to bring the count back toward three.

A container crash is different: the kubelet can restart a container inside the existing Pod according to its restart policy. An unready Pod also doesn't automatically trigger a replacement simply because its readiness check fails.

Recovery requires suitable capacity, accessible images, working networking and storage, and satisfied policies. After a node failure, detection and eviction also take time; an existing Pod isn't live-migrated to another node. See the Pod lifecycle documentation for these distinctions.

How the Service Keeps Up With Replacement Pods

A replacement Pod can have a different IP address. Clients use the Service's stable address or DNS name instead of tracking individual Pod IPs. For this selector-based Service, the EndpointSlice controller updates backend information as matching Pods change.

Use EndpointSlices to understand those backends. The older Endpoints API was deprecated in Kubernetes 1.33. The example's ClusterIP Service doesn't expose the application publicly.

Namespaces, Configuration, and Persistent Data

Know Your Cluster and Namespace Boundaries

Namespaces scope names and organize resources within a cluster. Pods, Deployments, Services, and PersistentVolumeClaims are namespaced; Nodes and PersistentVolumes are cluster-scoped.

A kubeconfig context groups cluster, user, and namespace settings. Selecting another namespace isn't the same as switching clusters. Use an explicit namespace for operational commands, as the example does.

Keep Settings and Persistent Storage Separate From Containers

  • ConfigMaps hold non-confidential configuration that Pods can consume as environment variables or mounted files.
  • Secrets hold sensitive values such as credentials. Base64 encoding isn't encryption; verify encryption at rest and restrict access.
  • A PersistentVolumeClaim (PVC) requests storage. A PersistentVolume (PV) represents provisioned storage; a StorageClass can enable dynamic provisioning through a compatible provisioner.

A Pod's volumes field configures its volumes; it isn't a standalone Volume API resource. PersistentVolumes and PersistentVolumeClaims are API resources. Their storage lifecycle is separate from an individual container's lifecycle.

Common Mistakes

  • Treating API acceptance as deployment success. Check rollout status, Pod status, and events; reconciliation can be blocked after a resource is accepted.
  • Confusing running containers with a healthy application. Configure meaningful readiness, liveness, and startup probes. Readiness controls traffic eligibility; liveness can trigger container restarts.
  • Assuming three replicas means three independent failure domains. If placement resilience matters, configure topology spread or anti-affinity rather than relying on the replica count alone.
  • Copying manifests without checking API compatibility. Kubernetes APIs and component behavior are versioned. Use documentation matching your cluster release and check your provider's upgrade requirements.

FAQ

What is the difference between a Kubernetes control plane and a worker node?

The control plane coordinates cluster-wide decisions, API state, scheduling, and reconciliation. Worker nodes host application Pods and run node components such as the kubelet and container runtime.

What does kubelet do in Kubernetes?

The kubelet reconciles Pod specifications assigned to its node, coordinates container execution through a runtime, and reports status. It doesn't select nodes for Pods or replace the scheduler.

Does Kubernetes require kube-proxy?

No. Many clusters use kube-proxy for Service traffic forwarding, but network implementations can provide a replacement. Pod networking and Service forwarding are related but distinct responsibilities.

How does Kubernetes replace a failed pod?

For a Deployment-managed workload, the ReplicaSet controller requests a replacement when a Pod is deleted or reaches a terminal failed state. The scheduler places the replacement and a kubelet starts its containers, provided capacity and other constraints allow it.

Where does Kubernetes store cluster state?

Kubernetes uses etcd to persist its API state, including resource definitions and Secret objects. Application database contents and persistent-volume files live in their respective storage systems, not in Kubernetes' etcd store.

Further Reading

Written by Sam Erickson

Software engineer. I write every article on StackChief myself. Author of Mastering the Tech Interview. More about me