>_
EngineeringNotes
Back to Kubernetes

What is kubernetes

💡

Docker is a pre-requisite before you proceed to understand kubernetes

Kubernetes (popularly known as k8s) is a container orchestration engine, which as the name suggests lets you create, delete, and update containers.

This is useful when:

  1. You have your docker images in the docker registry and want to deploy it in a cloud native fashion
  2. You want to not worry about patching, crashes. You want the system to auto heal
  3. You want to autoscale with some simple constructs
  4. You want to observe your complete system in a simple dashboard

Before kubernetes

Backend

https://api.website.com
Load balancer
Backend EC2 machine 1
Backend EC2 machine 2

Frontend (Nextjs)

https://website.com
Frontend EC2 machine 1 (nextjs)

Frontend (React)

mywebsite.com
CDN
S3

Why the difference?

  • React applications are just static assets (HTML/CSS/JS). Once built, they don't change. The most efficient way to serve them is via a CDN & S3 (Object Storage), which is cheaper and faster.
  • Next.js (SSR) needs to generate HTML on every request. This requires a running Node.js server to compute the page. That's why it's treated like a backend service and deployed on an EC2 machine.

Note: Next.js can also be deployed horizontally scaled behind a load balancer, exactly like the Backend service shown above!

After kubernetes

Your frontend, backend are all pods in your kubernetes cluster

Kubernetes Cluster

mywebsite.com
AWS Machine 1 (worker)
BE pod 1
BE pod 2
AWS Machine 2 (worker)
BE pod 3
Developer
AWS Machine 4 (master)
AWS Machine 3 (worker)
FE Pod 1

Jargon

Ref - https://kubernetes.io/docs/concepts/overview/components/

Nodes

In kubernetes, you can create and connect various machines together, all of which are running kubernetes. Every machine here is known as a node.
There are two types of nodes

Master Node (Control pane)

The node that takes care of deploying the containers/healing them/listening to the developer to understand what to deploy

Master Node

API Server
etcd
kube-scheduler
kube-controller-manager
API Server
  1. Handling RESTful API Requests: The API server processes and responds to RESTful API requests from various clients, including the kubectl command-line tool, other Kubernetes components, and external applications. These requests involve creating, reading, updating, and deleting Kubernetes resources such as pods, services, and deployments.
  2. Authentication and Authorization: The API server authenticates and authorize all API requests. It ensures that only authenticated and authorized users or components can perform actions on the cluster. This involves validating user credentials and checking access control policies.
  3. Metrics and Health Checks: The API server exposes metrics and health check endpoints that can be used for monitoring and diagnosing the health and performance of the control plane.
  4. Communication Hub: The API server acts as the central communication hub for the Kubernetes control plane. Other components, such as the scheduler, controller manager, and kubelet, interact with the API server to retrieve or update the state of the cluster.
etcd

Consistent and highly-available key value store used as Kubernetes' backing store for all cluster data. Ref - https://etcd.io/docs/v3.5/quickstart/

kube-scheduler

Control plane component that watches for newly created Pods with no assigned node, and selects a node for them to run on. Its responsible for pod placement and deciding which pod goes on which node.

kube-controller-manager

Ref - https://kubernetes.io/docs/concepts/architecture/controller/

The kube-controller-manager is a component of the Kubernetes control plane that runs a set of controllers. Each controller is responsible for managing a specific aspect of the cluster's state.

There are many different types of controllers. Some examples of them are:

  • Node controller: Responsible for noticing and responding when nodes go down.
  • Deployment controller: Watches for newly created or updated deployments and manages the creation and updating of ReplicaSets based on the deployment specifications. It ensures that the desired state of the deployment is maintained by creating or scaling ReplicaSets as needed.
  • ReplicaSet Controller: Watches for newly created or updated ReplicaSets and ensures that the desired number of pod replicas are running at any given time. It creates or deletes pods as necessary to maintain the specified number of replicas in the ReplicaSet's configuration.
Worker Nodes - The nodes that actually run your Backend/frontend

Worker node

kubelet
kube-proxy
Container runtime
kubelet

An agent that runs on each node in the cluster. It makes sure that containers are running in a Pod.

How the kubelet Control Loop Works
  1. Watch for PodSpecs: The kubelet watches the API server for PodSpecs that are scheduled to run on its node. This includes both new pods that need to be started and existing pods that may need to be updated or terminated.
  2. Reconcile Desired State: The kubelet compares the current state of the node (which pods are running, their statuses, etc.) with the desired state as defined by the PodSpecs.
  3. Take Action: Based on this comparison, the kubelet takes actions to reconcile the actual state with the desired state:
    • Start Pods: If there are new PodSpecs, the kubelet will pull the necessary container images, create the containers, and start the pods.
    • Monitor Health: The kubelet performs health checks (liveness and readiness probes) on running containers. If a container fails a health check, the kubelet may restart it according to the pod's restart policy.
    • Update Pods: If there are changes to the PodSpecs (e.g., configuration changes), the kubelet will update the running pods accordingly.
    • Stop Pods: If a pod is no longer needed or should be terminated, the kubelet will stop and remove the containers.
  4. Report Status: The kubelet periodically reports the status of the pods and the node back to the API server. This includes resource usage (CPU, memory, etc.) and the status of each container.
kube-proxy

The kube-proxy is a network proxy that runs on each node in a Kubernetes cluster. It is responsible for you being able to talk to a pod

Worker node

kube-proxy
iptables/IPVS
(Network rules managed by kube-proxy)
Backend Pods
Container runtime

In a Kubernetes worker node, the container runtime is the software responsible for running containers.

It interacts with the kubelet, which is the agent running on each node, to manage the lifecycle of containers as specified by Kubernetes pod specifications. The container runtime ensures that the necessary containers are started, stopped, and managed correctly on the worker node.

Common Container Runtimes for Kubernetes
  1. containerd
  2. CRI-O
  3. Docker
Kubernetes Container Runtime Interface (CRI)

The Container Runtime Interface (CRI) is a plugin interface that allows the kubelet to use a variety of container runtimes without needing to know the specifics of each runtime. This abstraction layer enables Kubernetes to support multiple container runtimes, providing flexibility and choice to users.

Control pane
Kubernetes API Server
Worker node
kubelet
Container Runtime Interface
Container Runtime
Running Containers

Cluster

A bunch of worker nodes + master nodes make up your kubernetes cluster. You can always add more / remove nodes from a cluster.

Images

A Docker image is a lightweight, standalone, and executable software package that includes everything needed to run a piece of software, including the code, runtime, libraries, environment variables, and configuration files. Images are built from a set of instructions defined in a file called a Dockerfile.

Eg - https://hub.docker.com/_/mongo

Containers

A container is an image in execution. For example if you run

docker run -p 5432:5432 -e POSTGRES_PASSWORD=mysecretpassword -d postgres

Pods

A pod is the smallest and simplest unit in the Kubernetes object model that you can create or deploy

cluster

Master Node
Worker Node
Pod
BE container
FE container
🤔Why start a Pod instead of a Container?

You might wonder: "If the worker node has a container runtime, why doesn't Kubernetes just run the container directly? Why do we need this extra wrapper called a Pod?"

1️⃣Containers Are Just Processes

A container:

  • Is just a Linux process
  • Has its own namespace & cgroups
  • Runs independently

But Kubernetes needs more than just docker run my-backend. It needs:

NetworkingRestart policiesScalingService discoveryShared storageHealth checksScheduling

A single container object cannot handle all that cleanly.

2️⃣Pod = Deployment Unit

Pod is the smallest deployable unit in Kubernetes.

When you say:

replicas: 3

Create 3 Pods

NOT

Create 3 containers

Why? Because Kubernetes schedules Pods to nodes — not containers.

3️⃣Networking Reason
Very Important

Each Pod gets:

Its own IPIts own network namespace

⚠️ Scheduled directly:

  • Every container needs an individual IP
  • Service routing becomes overly complex
  • Sidecar communication becomes messy

🚀 With Pods:

  • Pod = One IP
  • Containers inside share that IP

This simplifies:

Service load balancingDNSCommunication

4️⃣Sidecar Pattern
Real Production Use

Imagine these containers:

Backend container
Logging container
Metrics exporter
Envoy proxy

These must:

🤝 Share localhost📂 Share volumes🔄 Restart together

You cannot attach multiple containers directly at node level and expect this behavior cleanly.

💡

Pod gives you: One logical application unit

5️⃣Lifecycle Management

📉

If Kubernetes ran containers directly:

  • If one container crashes → what happens?
  • How do you tie containers together?
  • How do you guarantee co-scheduling?
🌱

Pod solves this:

  • Containers start together
  • Containers share lifecycle
  • Restart policy applies to whole unit

6️⃣Scheduling Reason
Very Important

Kubernetes scheduler behavior:

Find best node → Place POD
Find best node → Place container

Why?

Because a Pod defines the full workload definition:

CPUMemoryVolumesNetworkingSecurity context

A container alone is incomplete.

7️⃣Real-World Analogy

Think like this:

Container=Single employeePod=Department teamKubernetes=HR system

HR assigns teams to offices, not individual employees randomly.

🔥

🔥 THE CORE TRUTH

Kubernetes is NOT a container manager.

It is a Pod orchestrator.

Containers are just an implementation detail.

Can I run two Backends in one Pod?

Yes, BUT only if they use different ports!

Inside a single Pod, all containers share the same Network Namespace. This means they share the same IP address and the same localhost.

Think of a Pod like your localhost (Laptop/PC). If you try to run two apps on port 3000 on your laptop, the second one will crash with a "Port already in use" error.

The same thing happens in a Pod. If Container A listens on port 8080, Container B cannot listen on port 8080. It must use a different port (e.g., 9090).

✅ Valid Setup

Pod (IP: 10.1.0.5)
Shared Localhost
App A
:3000
localhost
App B
:4000

Different ports = Happy Neighbors!
App A can talk to App B via localhost:4000

❌ Port Conflict

Pod (IP: 10.1.0.6)
App A
:3000
💥
App A (Copy)
:3000
Error

Same port = Crash!
Just like running two servers on port 3000 on your Mac.