Technology · ssh / indianDevelopers
Demystifying Kubernetes: An Engineer’s Deep Dive into K8s Architecture and Internal Mechanics
Hey everyone! Welcome to Indian Developers. If you’ve worked in backend, infrastructure, or DevOps over the last few years, you’ve almost certainly interacted with Kubernetes (k8s)—or at least heard people talking about it as if it’s the solution to every problem in software engineering.

It isn’t a silver bullet. But when you understand how it works under the hood, Kubernetes stops looking like a black box of magic YAML files and starts looking like what it actually is: an incredibly robust, distributed operating system for containerized workloads.
In this guide, we are going to bypass the marketing fluff and break down Kubernetes from an engineering perspective. We'll explore the problem space it solves, walk through its architectural components, unpack how state reconciliation works, and trace the exact lifecycle of a pod from kubectl apply to running code.
1. The Paradigm Shift: Why Do We Need Orchestration?
To appreciate Kubernetes, we first need to remember the pain points of how we used to deploy software.
The Evolution of Deployment
Bare Metal Era: Applications ran directly on physical servers. If an app needed more resources, you bought a bigger box. Resource isolation was non-existent; a memory leak in one service crashed the entire host.
Virtual Machine (VM) Era: Hypervisors allowed us to run multiple isolated OS instances on a single physical machine. Better isolation, but heavy overhead—running a full OS kernel per app wasted massive amounts of CPU and RAM.
Container Era (Docker): Containers leveraged Linux kernel features—specifically namespaces (for isolation) and cgroups (for resource limits)—to run processes in isolated user spaces sharing the host kernel. Applications became portable and lightweight.
The Container Sprawl Problem
Docker solved application packaging, but it created an operational bottleneck. When you move from running 5 monoliths to running 150 containerized microservices across dozens of EC2/GCP instances, manual management breaks down completely:
How do you automatically restart a container when it crashes?
How do you scale services up or down based on CPU load?
How do you route traffic to healthy containers while performing zero-downtime rolling updates?
How do containers discover each other without hardcoding IP addresses?
This is Container Orchestration. Kubernetes was created by Google (inspired by their internal Borg system) and open-sourced to solve precisely these cluster-level management problems.
2. The Core Philosophy: Declarative State & Reconciliation
If you only remember one concept from this article, let it be this: Kubernetes operates entirely on a declarative model backed by continuous control loops.
Imperative vs. Declarative
Imperative (Do this): "Spin up 3 Docker containers on Host A, install Nginx, and bind port 80."
Declarative (Be like this): "I want a state where 3 replicas of Nginx are always running and accessible on port 80."
In Kubernetes, you never tell the system how to build something step-by-step. You submit a desired state (usually via a YAML or JSON file) to the API. Kubernetes continuously checks the actual state of the cluster against your desired state and performs operations to bridge any gap.

This constant observation, comparison, and action cycle is known as the Reconciliation Loop.
3. Kubernetes Architecture Overview
A Kubernetes cluster consists of two distinct operational planes:
The Control Plane (Master Nodes): The "brain" of the cluster. Makes global decisions (e.g., scheduling), detects cluster events, and responds to state changes.
Worker Nodes: The "muscle" of the cluster. Hosts the actual workloads (containers) and handles local networking and storage operations.

Let's do a deep dive into each component.
4. Deep Dive: Control Plane Components
4.1 kube-apiserver (The Gateway)
The API Server is the front door of the Kubernetes control plane. It exposes the Kubernetes REST API and serves as the central hub that all other components talk to.
Stateless: The API Server does not store state locally. It validates, authenticates, authorizes, and persists incoming REST requests straight to
etcd.Security Layer: Every request passing through the API Server undergoes three stages:
Authentication (AuthN): Validates who is making the request (using Client Certificates, Bearer Tokens, or OIDC).
Authorization (AuthZ): Validates if the requester has permission (usually handled via RBAC—Role-Based Access Control).
Admission Control: Modifies or validates objects before they are written to
etcd(e.g., enforcing resource limits, injecting sidecars via Mutating/Validating Webhooks).
Senior Dev Note: No worker component ever communicates directly with
etcdor with other worker components across the control plane. Everything talks exclusively throughkube-apiserver.
4.2 etcd (The Brain & Source of Truth)
etcd is a strongly consistent, distributed key-value store developed by CoreOS (now CNCF). It stores the entire state of the Kubernetes cluster—every Pod configuration, Secret, Node status, and Namespace.
Consensus Mechanism: Uses the Raft consensus algorithm to ensure high availability and data consistency across cluster master nodes.
Key Feature - Watch API: Instead of components constantly polling the API Server to check if something changed,
etcd(and by extension the API Server) supports a Watch API. Components open a persistent HTTP/2 stream and receive instant push notifications whenever a key/resource changes.
Production Warning:
etcdperformance relies heavily on low-latency disk IOPS. Slow disk performance onetcdnodes can freeze the control plane, cause false node heartbeats, and paralyze cluster scheduling.
4.3 kube-scheduler (The Placement Engine)
The scheduler’s job is straightforward on paper: find an optimal worker node for newly created, unscheduled pods (spec.nodeName is empty).
How does it decide where a Pod goes? It uses a two-step process:
Filtering (Predicates): Eliminates nodes that do not meet the pod’s requirements.
Does the node have enough free CPU/RAM?
Does the node match the required
nodeSelectorornodeAffinity?Does the node have a
taintthat tolerates the pod'stolerations?
Scoring (Priorities): Ranks the remaining eligible nodes based on optimization metrics (e.g., spreading pods across failure zones, balancing resource usage across nodes).
Once the best node is selected, kube-scheduler notifies the API Server through a Binding object, updating the Pod's spec.nodeName field.
4.4 kube-controller-manager (The Enforcer)
This daemon embeds all core controller loops that ship with Kubernetes. A "controller" is simply a background loop listening to the API server to ensure current state matches desired state.
Some key controllers inside this manager:
Node Controller: Monitors worker node health and handles node eviction if a node goes offline.
ReplicaSet Controller: Ensures the exact number of pod replicas declared in a ReplicaSet spec are running.
Deployment Controller: Manages declarative updates for Pods/ReplicaSets (enables zero-downtime rolling updates).
ServiceAccount & Token Controller: Creates default accounts and API access tokens for new namespaces.
5. Deep Dive: Worker Node Components
5.1 kubelet (The Node Agent)
kubelet is an agent that runs on every single worker node in the cluster. It acts as the bridge between the Control Plane and the host's container engine.
PodSpec Execution:
kubeletreceives a set ofPodSpecs(via the API server) and ensures that the containers described in those specs are running and healthy.Container Runtime Interface (CRI):
kubeletdoesn't run Docker directly anymore. Instead, it talks to a container runtime using the CRI protocol over gRPC sockets.Health Probes: Executes
livenessProbe,readinessProbe, andstartupProbeconfigured for containers, restarting them or removing them from endpoints if they fail.
5.2 Container Runtime (The Muscle)
The container runtime is the low-level software responsible for pulling images, mounting volumes, and executing the actual containers.
While Docker was the original container runtime, modern Kubernetes uses lightweight runtimes that implement the Container Runtime Interface (CRI):
containerd: A daemon originally carved out of Docker, now a standalone CNCF graduated project.
CRI-O: A high-performance runtime built explicitly to implement the CRI for Kubernetes.
Underneath the CRI runtime lies a lower-level runtime like runc (compliant with the Open Container Initiative / OCI specification) which interacts directly with the Linux kernel namespaces and cgroups to instantiate processes.
5.3 kube-proxy (The Network Router)
kube-proxy runs on each worker node and maintains network rules on the host. It enables the Kubernetes Service abstraction—allowing network traffic to be load-balanced across dynamic Pod IP addresses.
How does it work?
iptables Mode (Default):
kube-proxywritesiptablesrules on the host OS. When traffic hits a Virtual Service IP (ClusterIP),iptablesuses random probability rules to translate that virtual IP to a real target Pod IP (DNAT).IPVS Mode: Designed for massive clusters (10,000+ services). Uses Linux IP Virtual Server (IPVS) in kernel space, offering $O(1)$ routing lookup performance compared to $O(N)$ sequential lookups in
iptables.eBPF (Modern Alternative): Tools like Cilium completely bypass
kube-proxyby executing eBPF code directly inside the Linux kernel network stack, dramatically reducing latency and overhead.
6. Kubernetes API Objects: The Building Blocks
To write effective applications on Kubernetes, you need to understand its fundamental API abstractions:
AbstractionWhat it RepresentsPodThe smallest deployable unit in K8s. Holds one or more containers sharing network namespaces (localhost), IPC, and storage volumes.DeploymentManages stateless applications. Handles declarative updates, pod rollouts, and automatic rollbacks.StatefulSetManages stateful applications (e.g., PostgreSQL, Kafka). Provides stable network identifiers (pod-0) and persistent disk bindings.DaemonSetEnsures a copy of a specific Pod runs on every (or selected) node. Ideal for logging agents (Fluentbit) and monitoring (Prometheus Node Exporter).ServiceAn abstract way to expose an application running on a set of Pods as a network service (ClusterIP, NodePort, LoadBalancer).Ingress / Gateway APIAn API object that manages external HTTP/HTTPS access to services within a cluster (L7 traffic routing, TLS termination).PersistentVolume (PV) / PVCDecouples storage request definitions (PVC) from actual underlying infrastructure provisioning (PV/StorageClass).
7. Tracing the Lifecycle: What Happens During kubectl apply -f deployment.yaml?
To consolidate everything we've discussed, let's step through the sequence of events when a developer deploys an app.

Authentication & Authorization:
kubectlsends an HTTP POST with the manifest tokube-apiserver. The server authenticates your credentials and checks your RBAC permissions.Mutating & Validating Webhooks: Admission controllers mutate defaults (e.g., inject sidecars) and validate your spec syntax.
Persistence: The API Server writes the Deployment object to
etcd.Deployment Controller Reacts: The Deployment Controller (watching
etcd) notices a new Deployment. It creates a ReplicaSet object representing this desired version.ReplicaSet Controller Reacts: The ReplicaSet Controller notices the new ReplicaSet and generates the required number of Pod objects. These pods are marked as
Unscheduled(nodeNameis blank).Scheduler Assigns Nodes: The
kube-schedulersees the unscheduled Pods via its Watch stream. It filters and scores available nodes, picks Nodeworker-02, and sends a binding update to the API Server.Kubelet Takes Over: The
kubeletdaemon onworker-02receives the Watch notification that a Pod has been assigned to it.Container Creation:
kubelettalks to the CNI (Container Network Interface) to set up the Pod IP network, and issues gRPC requests to the Container Runtime (containerd) to pull the container image and run the container.Status Update:
kubeletstreams the status (Running) back to the API Server, which updatesetcd.
8. Senior Dev Perspective: Common Production Pitfalls
While Kubernetes is amazingly powerful, misuse leads to outages and inflated cloud costs. Here are three hard-earned takeaways from running K8s in production:
1. Always Set Memory and CPU Requests/Limits
If you do not specify resources.requests and resources.limits in your Pod specs:
kube-schedulerwon't know how much room your container actually needs, leading to heavily over-subscribed nodes.An unexpected memory spike in one application will trigger an OOM (Out Of Memory) Killer event on the host, potentially bringing down neighboring containers.
2. Don't Treat Pods as Stateful Machines
Pods are ephemeral by design. A node failure, cluster auto-scaler event, or rolling update will terminate Pods at any time. Design your applications to be stateless, store session data in distributed caches (like Redis), and offload database state to dedicated managed services or well-configured StatefulSets.
3. Avoid "K8s-itis" (Over-Engineering)
Before adopting Kubernetes, ask yourself if you actually need it. If you are running a monolithic web application or a few microservices with a small engineering team, a managed PaaS (like AWS ECS, App Runner, or GCP Cloud Run) will deliver 90% of the containerized benefits with 10% of the operational overhead. Use Kubernetes when your scale, service complexity, or platform engineering requirements justify its operational cost.

Conversation
Comments
Sign in to join the conversation.