DEV Community

Cover image for Understanding Kubernetes: A Beginner's Guide to Container Orchestration
Bibek
Bibek

Posted on Originally published at bibekkakati.com AI-assisted

Understanding Kubernetes: A Beginner's Guide to Container Orchestration

If you have already explored Docker, you know how convenient containers are. You package your application, dependencies, and environment into a neat image, run docker run, and it just works.

Running one container on your local machine is simple. But what happens when your application grows into a real-world product with millions of users?

Imagine you launch an online food delivery app. On a Friday night at 8:00 PM:

  • Traffic spikes by 10x—you suddenly need 20 copies of your backend container to handle orders.
  • One of your physical servers overheats and crashes at 2:00 AM, taking down 5 containers with it.
  • You need to deploy a bug fix to the payment gateway without dropping ongoing user checkouts.
  • You need a way to distribute incoming user requests evenly across all running containers.

Doing this manually means waking up at 3:00 AM, SSH-ing into servers, running docker run commands by hand, and manually updating Nginx reverse proxy configs.

This is where Kubernetes comes in.


What is Kubernetes?

Kubernetes (often abbreviated as K8s, because there are 8 letters between 'K' and 's') is an open-source container orchestration platform. It automates the deployment, scaling, load balancing, and self-healing of containerized applications across a cluster of servers.

Originally developed by Google (based on over a decade of running Borg internally) and now maintained by the Cloud Native Computing Foundation (CNCF), Kubernetes has become the standard operating system for cloud-native infrastructure.

The Symphony Orchestra Analogy

Think of it this way:

  • A Docker Container is a single musician (like a violinist playing their sheet music perfectly).
  • Kubernetes is the orchestra conductor. The conductor ensures every musician plays in sync, brings in extra violinists when the crescendo builds, seamlessly replaces someone if a string snaps, and makes sure the entire performance sounds harmonious to the audience.
                +------------------------------------+
                |        Kubernetes Conductor        |
                | (Monitors, Scales, Heals, Routes)  |
                +-----------------+------------------+
                                  |
    +----------------------------+----------------------------+
    |                            |                            |
    v                            v                            v
[ Container 1 ]           [ Container 2 ]              [ Container 3 ]
 (Musician A)               (Musician B)                 (Musician C)
Enter fullscreen mode Exit fullscreen mode

What Problems Does Kubernetes Solve?

Problems How Kubernetes Solves It
Server Crash Self-Healing: Kubernetes detects the dead node and automatically restarts the affected containers on healthy servers within seconds.
Traffic Surges Horizontal Auto-Scaling: Automatically scales the number of container copies (replicas) up or down based on CPU, memory, or custom metrics.
Zero-Downtime Updates Rolling Deployments: Updates containers incrementally one by one. If an error occurs, it automatically rolls back to the last stable version.
Traffic Distribution Service Discovery & Load Balancing: Gives containers a single stable IP/DNS and distributes incoming network traffic evenly among healthy instances.
Secrets & Configs Centralized Management: Injects environment variables, passwords, and API keys securely without baking them into container images.

Kubernetes Architecture Explained

A Kubernetes setup is called a Cluster. A cluster is made of physical machines or Virtual Machines (VMs) divided into two main layers:

  1. The Control Plane (The Brain): Makes high-level decisions, monitors the cluster, and schedules workloads.
  2. Worker Nodes (The Muscle): The actual machines that run your containerized applications.
+-------------------------------------------------------------------------+
|                              CONTROL PLANE                              |
|                                                                         |
|   +-------------------+   +--------------------+   +----------------+   |
|   |  kube-apiserver   |   |        etcd        |   | kube-scheduler |   |
|   +-------------------+   +--------------------+   +----------------+   |
|             |                                                           |
|   +-------------------------+   +-----------------------------------+   |
|   | kube-controller-manager |   |      cloud-controller-manager     |   |
|   +-------------------------+   +-----------------------------------+   |
+------------------------------------+------------------------------------+
                                     |
              +----------------------+----------------------+
              |                                             |
+-------------v---------------+               +-------------v---------------+
|         WORKER NODE 1       |               |         WORKER NODE 2       |
|                             |               |                             |
|  +-----------------------+  |               |  +-----------------------+  |
|  |        kubelet        |  |               |  |        kubelet        |  |
|  +-----------------------+  |               |  +-----------------------+  |
|  +-----------------------+  |               |  +-----------------------+  |
|  |      kube-proxy       |  |               |  |      kube-proxy       |  |
|  |   (Network Router)    |  |               |  |   (Network Router)    |  |
|  +-----------------------+  |               |  +-----------------------+  |
|  +-----------------------+  |               |  +-----------------------+  |
|  |   Container Runtime   |  |               |  |   Container Runtime   |  |
|  |   [ Pod ]   [ Pod ]   |  |               |  |   [ Pod ]   [ Pod ]   |  |
|  +-----------------------+  |               |  +-----------------------+  |
+-----------------------------+               +-----------------------------+
Enter fullscreen mode Exit fullscreen mode

The Control Plane Components

  • kube-apiserver:

    The main entry point for the entire cluster. Whenever you run a command via kubectl or an automated CI/CD pipeline triggers a deployment, it speaks directly to the API Server. No component talks to the cluster without going through kube-apiserver.

  • etcd:

    A fast, highly available, distributed key-value database. It stores the single source of truth for the entire cluster state (e.g., how many pods should be running, their IPs, secrets, and configurations). If it is not recorded in etcd, it doesn't exist.

  • kube-scheduler:

    When you request a new Pod, the scheduler decides which Worker Node should host it. It checks node capacity, CPU/memory availability, and specific constraints (like "only run on nodes with a GPU") to find the best match.

  • kube-controller-manager:

    Runs background loops that constantly compare the actual state of the cluster to your desired state. If you requested 3 replicas of an app and one crashes (actual = 2), the controller notices the mismatch and commands the cluster to spin up a replacement.

  • cloud-controller-manager:

    Interfaces with cloud providers (AWS, Google Cloud, Azure) to provision external resources like cloud load balancers, storage volumes, and firewall rules.

The Worker Node Components

Every Worker Node in the cluster runs three essential processes:

  • kubelet: An agent that runs on each node. It receives instructions from the kube-apiserver (e.g., "Run container X on this machine") and makes sure the containers are started and remain healthy.
  • kube-proxy: Manages network routing rules on each node. It ensures that requests sent to a Service get routed to the correct Pods, handling IP translations and load distribution across Pods.
  • Container Runtime: The software responsible for pulling container images and running them (e.g., containerd or CRI-O).

Core Kubernetes Objects & Concepts

Let's break down the building blocks you will interact with every day.

1. Pod (The Smallest Deployable Unit)

In Kubernetes, you never deploy a bare container directly. Instead, you deploy a Pod.

A Pod wraps one or more tightly coupled containers that share:

  • The same network namespace (meaning they can communicate with each other over localhost).
  • Shared storage volumes.
  • The same IP address.

Analogy: Think of a Pod as a pea pod. The peas inside are individual containers. Most Pods have just 1 container (e.g., your Node.js API), but some use helper "sidecar" containers (e.g., a logging or metrics collection agent).

+----------------------------------------------------+
| Pod (IP: 10.244.1.15)                              |
|                                                    |
|  +------------------------+  +------------------+  |
|  | Main Web App Container |  | Sidecar (Logger) |  |
|  |      (Port 3000)       |  |   (Port 9000)    |  |
|  +------------------------+  +------------------+  |
|               ^                       |            |
|               +--- talks via localhost --+         |
+----------------------------------------------------+
Enter fullscreen mode Exit fullscreen mode

2. Deployment (The Self-Healing Manager)

Pods are mortal. If a node loses power or a pod crashes due to an out-of-memory error, that individual Pod is gone forever.

A Deployment is a higher-level controller that manages Pods for you. You declare your desired state: "I want 3 replicas of my web app running at all times."

The Deployment:

  • Creates and tracks the Pods.
  • Automatically replaces any dead or degraded Pods.
  • Performs zero-downtime rolling updates when you change the image version.

3. Service (The Stable Front Door)

Because Pods frequently start, stop, and move between nodes, their internal IP addresses are ephemeral and change constantly. If your Frontend needs to talk to your Backend, it cannot rely on hardcoded Pod IPs.

A Service provides a stable, permanent IP address and DNS name that sits in front of a group of Pods and automatically load-balances traffic across them.

Incoming Request
       |
       v
+--------------+
| Service VIP  |  (e.g., backend-service:80)
+-------+------+
        |
        +--------+------------------+
        |                           |
        v                           v
  [ Backend Pod 1 ]           [ Backend Pod 2 ]
  (IP: 10.244.1.5)            (IP: 10.244.2.8)
Enter fullscreen mode Exit fullscreen mode

Common Service types:

  • ClusterIP (Default): Accessible only inside the Kubernetes cluster.
  • NodePort: Exposes the service on a static port on each worker node's IP.
  • LoadBalancer: Automatically provisions a cloud load balancer (e.g., AWS ALB or GCP Network Load Balancer) to expose your service to the internet.

4. Ingress (The Traffic Gatekeeper)

While a LoadBalancer Service gives you a dedicated public IP for a single service, spinning up a new cloud load balancer for every microservice is expensive and hard to manage.

An Ingress acts as a single, smart HTTP/HTTPS reverse proxy and router for your entire cluster:

  • Routes api.example.com to your backend-service.
  • Routes example.com to your frontend-service.
  • Handles SSL/TLS certificate termination in one place.

5. ConfigMap & Secret (Configuration Decoupling)

Following the 12-factor app methodology, your application code should be completely separated from its configuration.

  • ConfigMap: Stores non-sensitive configuration data (e.g., PORT: 8080, ENVIRONMENT: production, LOG_LEVEL: debug).
  • Secret: Encrypts and securely stores sensitive data (e.g., database passwords, OAuth tokens, API keys).

These values can be injected into your Pods as environment variables or mounted as configuration files.

6. Volume (Persistent Storage)

By default, container filesystems are temporary (ephemeral). When a container restarts, any files saved to local disk are wiped clean.

A Volume attaches persistent storage (such as AWS EBS, Google Persistent Disk, or NFS) to a Pod so data survives pod restarts and migrations.

The "Glue": How YAML Files Connect (Labels & Selectors)

Beginners often find Kubernetes YAML files confusing because they wonder: How does a Service know which Pods belong to it? How does a Deployment know which Pods it is managing?

The secret is Labels and Selectors:

  1. Labels: Key-value tags attached to resources (e.g., app: my-web-app).
  2. Selectors: Queries used by Deployments and Services to find matching Pods.

Let's see this in action with annotated YAML files.

1. Deployment YAML

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
    name: web-app-deployment
spec:
    # Desired number of copies
    replicas: 3

    # 1. SELECTOR: The Deployment manages Pods with this label
    selector:
        matchLabels:
            app: web-app
            tier: frontend

    # 2. TEMPLATE: Blueprint for creating each Pod
    template:
        metadata:
            # These labels MUST match the selector above!
            labels:
                app: web-app
                tier: frontend
        spec:
            containers:
                - name: web-container
                  image: nginx:1.25-alpine
                  ports:
                      - containerPort: 80
                  envFrom:
                      - configMapRef:
                            name: app-settings
Enter fullscreen mode Exit fullscreen mode

2. Service YAML

service.yaml

apiVersion: v1
kind: Service
metadata:
    name: web-app-service
spec:
    type: ClusterIP
    # The Service routes traffic to any Pod matching these labels:
    selector:
        app: web-app
        tier: frontend
    ports:
        - protocol: TCP
          port: 80 # Port exposed by the Service
          targetPort: 80 # Port on the container inside the Pod
Enter fullscreen mode Exit fullscreen mode

3. ConfigMap YAML

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
    name: app-settings
data:
    APP_ENV: "production"
    CACHE_ENABLED: "true"
Enter fullscreen mode Exit fullscreen mode

Step-by-Step: What Happens When You Apply the YAML files?

When a developer types kubectl apply -f deployment.yaml, here is the exact sequence of events that unfolds behind the scenes:

+-----------------------------------------------------------------------+
| 1. Developer runs: kubectl apply -f deployment.yaml                   |
+-----------------------------------+-----------------------------------+
                                    |
                                    v
+-----------------------------+           +-----------------------------+
|       kube-apiserver        | <-------> |            etcd             |
|  (Receives & validates API) |           |  (Saves cluster state)      |
+--------------+--------------+           +-----------------------------+
               |
               | 2. Notifies controller of desired state
               v
+-----------------------------+
|   kube-controller-manager   |
| (Creates 3 Pod definitions) |
+--------------+--------------+
               |
               | 3. Detects unscheduled Pods
               v
+-----------------------------+
|       kube-scheduler        |
|  (Finds best Worker Nodes)  |
+--------------+--------------+
               |
               | 4. Dispatches Pods to Node
               v
+-----------------------------+
|           kubelet           |
| (Worker Node Agent receives)|
+--------------+--------------+
               |
               | 5. Pulls image & starts Pod
               v
+-----------------------------+
|      Container Runtime      |
|    (containerd / CRI-O)     | ===> Pod is LIVE & Healthy!
+-----------------------------+
Enter fullscreen mode Exit fullscreen mode
  1. Submission: kubectl sends the YAML manifest via an HTTP POST request to kube-apiserver.
  2. Persistence: kube-apiserver validates the request and saves the record in etcd.
  3. Controller Loop: The Deployment Controller detects that 3 Pods are desired, but 0 are currently running. It creates 3 unscheduled Pod objects.
  4. Scheduling: The kube-scheduler observes the unscheduled Pods, inspects the available Worker Nodes, and assigns each Pod to a node.
  5. Execution: The kubelet on each assigned node detects the Pod assignment, instructs containerd to pull the nginx image, and starts the container.
  6. Network Setup: kube-proxy configures routing so traffic sent to web-app-service reaches the new Pods.

Essential Cheat Sheet for Beginners

Here are the most common kubectl commands you will use daily:

# Check the status of your cluster nodes
kubectl get nodes

# View all running Pods and Deployments
kubectl get pods
kubectl get deployments
kubectl get services

# Deploy or update resources using a YAML file
kubectl apply -f deployment.yaml

# View detailed debugging info and events for a specific Pod
kubectl describe pod <pod-name>

# View real-time logs from a container
kubectl logs -f <pod-name>

# Open an interactive shell inside a running container
kubectl exec -it <pod-name> -- /bin/sh

# Manually scale your deployment up or down
kubectl scale deployment web-app-deployment --replicas=5

# Delete a resource
kubectl delete -f deployment.yaml
Enter fullscreen mode Exit fullscreen mode

When Should You Use Kubernetes (and When Should You Avoid It)?

Kubernetes is powerful, but it comes with a steep operational learning curve. It is not always the right tool for every project.

When to Use Kubernetes:

  • You run a microservices architecture with dozens or hundreds of services.
  • You need automated horizontal scaling, self-healing, and multi-cloud portability.
  • You have a dedicated DevOps or Platform Engineering team to maintain the cluster.
  • You need complex rolling deployments, canary releases, or blue-green updates.

When to Avoid Kubernetes:

  • Small projects or MVPs: If you have a single monolithic app or a small side project, Kubernetes will add unnecessary complexity.
  • Simpler alternatives are sufficient: Managed container services like AWS ECS, Google Cloud Run, Render, or Railway offer 90% of the benefits with zero cluster management overhead.
  • Local development only: Use docker compose instead.

Top comments (0)