What is Kubernetes? #

In the modern software development landscape, we often hear the terms containerization and container orchestration. If you’re already used to packaging applications into containers with Docker, you might think your job is done. However, running containers on your local machine is very different from managing hundreds of interconnected containers spread across dozens of production servers in various data centers. This is where Kubernetes comes to the rescue.

Kubernetes (often shortened to K8s, where the 8 replaces the eight letters between “K” and “s”) is an open-source platform designed specifically to automate the deployment, scaling, and management of application containers. Kubernetes acts as the captain of the ship, coordinating all containers so they run harmoniously, efficiently, and without interruption.


The Evolution of IT Infrastructure Architecture #

To truly understand why we need Kubernetes, we have to look at how the industry has managed server infrastructure over the past few decades. This journey is divided into four major eras:

flowchart TD
    subgraph Era_1["1. Bare-Metal Era (Physical Servers)"]
        direction TB
        A1["One OS Directly on Hardware"] --> A2["One App Dominates Resources"]
        A2 --> A3["Dependency Conflicts & Slow Provisioning"]
    end

    subgraph Era_2["2. Virtualization Era (VMs)"]
        direction TB
        B1["Hypervisor Splits One Physical Machine into Many VMs"] --> B2["Each VM Has Its Own OS (Guest OS)"]
        B2 --> B3["Safe Isolation but Heavy OS Overhead"]
    end

    subgraph Era_3["3. Containerization Era (Docker)"]
        direction TB
        C1["OS-Level Isolation (Namespaces & Cgroups)"] --> C2["Share the Same Host OS Kernel"]
        C2 --> C3["Lightweight, Fast Boot, Highly Portable"]
    end

    subgraph Era_4["4. Orchestration Era (Kubernetes)"]
        direction TB
        D1["Manages a Server Cluster (Many VMs/Physical Machines)"] --> D2["Automated Placement, Healing & Scaling"]
        D2 --> D3["Declarative Infrastructure at Production Scale"]
    end

    Era_1 --> Era_2
    Era_2 --> Era_3
    Era_3 --> Era_4

    style Era_1 stroke:#7f8c8d,stroke-width:2px
    style Era_2 stroke:#2980b9,stroke-width:2px
    style Era_3 stroke:#27ae60,stroke-width:2px
    style Era_4 stroke:#8e44ad,stroke-width:2px

1. Bare-Metal Era (Physical Servers) #

In the beginning, organizations ran applications on physical servers. In this era, a single operating system runs directly on the hardware. The biggest weakness of this approach is the inability to cap resource allocation for each application. If you run application A and application B on the same server, and application A develops a memory leak, application B will also run out of resources and die. The solution back then was to run one application per physical server, which led to wasted hardware capital expenditure (CapEx) because average server utilization was very low.

2. Virtualization Era (Virtual Machines) #

Virtualization was introduced as a solution to the bare-metal drawbacks. With the help of a hypervisor, you can split one physical server into several Virtual Machines (VMs). Each VM acts as an independent computer with its own operating system (Guest OS), virtual CPU, memory, and storage. Virtualization drastically improved hardware utilization and provided excellent security isolation between applications. However, VMs have an inherent weakness: each VM is very heavy (requiring several gigabytes of storage for its own OS) and takes a long time to boot (several minutes) because the OS has to fully initialize its kernel.

3. Containerization Era #

Containers arrived as a much lighter alternative to virtualization. Unlike VMs, which separate hardware, containers isolate at the operating system level (using Linux kernel features such as namespaces and control groups, or cgroups). Containers running on one physical server share the same host OS kernel. This makes containers extremely lightweight (their size is often only tens of megabytes) and able to boot instantly (in milliseconds). Container portability ensures that what you run on your developer laptop behaves exactly the same on staging and production servers.

4. Container Orchestration Era (Kubernetes) #

Containers are amazing, but when your application starts being split into dozens of microservices deployed as hundreds of containers across dozens of server machines, you face a new kind of complexity. You need a system to manage the lifecycle of those containers centrally: which server machine is free to run a new container? What if a server machine physically dies? How do you distribute user traffic evenly across all containers? This need gave birth to the container orchestration era, with Kubernetes as its leading player.


The History and DNA Behind Kubernetes #

Kubernetes is not a hastily built project. The platform has very mature DNA because it was born from Google’s giant-scale operational experience. For more than a decade before Kubernetes was released, Google had been managing all of its workloads — from Gmail and Google Search to YouTube — using a highly secret internal orchestration system called Borg, which later evolved into the Omega project.

Borg was responsible for managing millions of compute tasks and launching billions of containers every week across Google’s data centers. When container technology started gaining traction in the broader industry (especially after Docker was released to the public in 2013), Google realized the industry needed a standard orchestration tool built on the lessons they had learned while developing Borg.

In 2014, a group of Google engineers (including Joe Beda, Brendan Burns, and Craig McLuckie, assisted by other Borg architects) announced the Kubernetes project as an open-source, redesigned-from-scratch version written in the Go programming language.

To ensure the project’s longevity and neutrality, Google partnered with the Linux Foundation to establish the Cloud Native Computing Foundation (CNCF) in 2015 and contributed Kubernetes as its first seed project. Today, Kubernetes is maintained by a global community of thousands of contributors and backed by the world’s technology giants, making it the de facto standard of the modern cloud-native platform.


Kubernetes’ Main Roles in the Application Lifecycle #

As an orchestrator, Kubernetes takes over all the tedious operational tasks from the engineering team. Concretely, here are the main roles Kubernetes plays to keep your application reliable in production:

1. Smart Scheduling #

When you ask Kubernetes to run an application, it doesn’t place it randomly. The API Server coordinates with the Scheduler to analyze the capacity status of every node in the cluster. Kubernetes picks the most suitable node based on the container’s CPU/memory requirements, affinity policies, and the network and storage constraints you define.

2. Self-Healing #

Kubernetes assumes infrastructure failure is inevitable. If a container dies because of a code crash, Kubernetes immediately detects it and restarts the container. Going further, if an entire server machine (node) suffers a physical failure (for example, a power outage), Kubernetes automatically moves and reschedules all containers on the failed node to another healthy node.

3. Automatic Scaling (Horizontal Scaling) #

You no longer need to monitor traffic manually to add servers during peak hours. Through the Horizontal Pod Autoscaler (HPA), Kubernetes continuously monitors CPU usage, memory, or even custom metrics from your application. If the workload crosses the threshold you defined, Kubernetes immediately creates new container replicas within seconds. Conversely, when traffic drops, the extra containers are removed to save infrastructure costs.

4. Service Discovery & Load Balancing #

In Kubernetes, containers are dynamic and can move between nodes at any time, which means container IP addresses are always changing. Kubernetes solves this problem by giving a stable DNS name to a group of containers. Kubernetes also has a built-in load balancer to distribute traffic evenly across all healthy container replicas.

5. Config & Secret Management #

Kubernetes lets you store application environment configuration (such as database URLs) in ConfigMap objects and sensitive data (such as passwords, API keys, and SSL certificates) in Secret objects. This information can be dynamically injected into containers at runtime as environment variables or mounted as files, without baking it into the container image.


Declarative Model vs Imperative Model #

One of the secrets of Kubernetes’ power lies in its use of the Declarative Model. To understand the difference, let’s compare it with the Imperative Model we typically use in traditional scripts.

Imperative Model (How to Get There):
  "SSH into server-1, download image version 2, stop the old container, run the new container,
   make sure the port is open. If it fails halfway, send an alert and leave the system broken."

Declarative Model (Desired End State):
  "I want the system to always be in this state: running 3 replicas of application X
   using image version 2 on port 80."

In the declarative model, you only write a YAML document that defines the Desired State. You then submit this document to the Kubernetes API Server. Your job ends there.

Kubernetes then continuously runs a mechanism called the Reconciliation Loop. This control loop works as follows:

flowchart TD
    A["Start Loop (Control Loop)"] --> B["Observe Actual State"]
    B --> C["Compare with Desired State"]
    C --> D{Are They the Same?}
    D -- Yes --> E["Sleep for a While (Loop Back to Start)"]
    D -- No --> F["Take Corrective Action (Fix the Difference)"]
    F --> B

A Real-World Example of the Reconciliation Loop: #

  1. Desired State: 3 replicas of the payment application Pod must be running.
  2. Actual State: Kubernetes detects only 2 Pods running because 1 Pod died from OOM (Out Of Memory).
  3. Corrective Action: The Controller Manager detects the difference and instructs the scheduler to immediately create 1 new Pod on a node with available memory capacity.
  4. End Result: The actual state is back in sync with the desired state.

With this model, your infrastructure becomes highly resilient because Kubernetes automatically fixes any deviation that occurs without requiring human intervention.


Clearing Up the Confusion: Kubernetes vs Docker #

For beginners new to the cloud-native ecosystem, a common question arises: “Which is better, Kubernetes or Docker?” This is the wrong question to ask because the two sit at different layers of the technology stack and complement each other.

  • Docker is a tool for packaging an application along with its dependencies into a single standard container unit and running it on a machine.
  • Kubernetes is the orchestrator that manages how those containers run across a cluster of many machines.

For an easy-to-grasp analogy:

  • Docker is a car, while Kubernetes is the city traffic controller.
  • Docker is a musician, while Kubernetes is the orchestra conductor.
  • Docker is a physical shipping container, while Kubernetes is the cargo port with its heavy equipment and logistics system.

The Role of the Container Runtime Interface (CRI) #

Note that Kubernetes is not exclusively tied to Docker. Kubernetes talks to container engines through an open API standard called the Container Runtime Interface (CRI).

Since version 1.24, Kubernetes has removed built-in support for the Docker engine (the dockershim deprecation) for efficiency reasons. However, this does not mean you can no longer use Docker. Container images you build with Docker comply with the Open Container Initiative (OCI) standard, which means they can run perfectly on Kubernetes using modern runtimes that are lighter and purpose-built for orchestration, such as containerd or CRI-O.


Anti-Pattern: Treating Kubernetes Like a Virtual Machine (VM) #

One of the most fatal mistakes teams new to Kubernetes make is treating Pods (containers) like traditional Virtual Machines.

ANTI-PATTERN:
// WHAT WE DO:
- Enter the Pod using `kubectl exec -it` to edit configuration directly.
- Upload database configuration files or static assets into the Pod's filesystem.
- Ignore the fact that a Pod can be deleted, die, or move at any time (ephemeral).
// THE RESULT:
- When the Pod is restarted or moved to another node by the scheduler, all manual changes
  and data inside it are lost forever.
- Our deployment becomes inconsistent and cannot be reproduced declaratively.
✓ THE RIGHT SOLUTION:
- Always treat containers as temporary (*ephemeral* / *stateless*) entities.
- To change configuration, edit the YAML manifest in a `ConfigMap` or `Secret`, then redeploy.
- To store persistent data (such as user uploads or database data), use a `PersistentVolumeClaim` (PVC) object.
- The entire deployment pipeline should run automatically through manifest declarations, not ad-hoc manual configuration inside the container.

Summary #

  • Kubernetes (K8s) is a container orchestration platform — it automates the deployment, scaling, and recovery of application containers centrally across a server cluster.
  • Google Borg DNA — designed from Google’s 10+ years of experience managing billions of containers with its internal Borg system.
  • The Power of the Declarative Model — you define your application’s desired state, and Kubernetes keeps running its reconciliation loop to ensure the cluster’s actual state always matches.
  • Kubernetes and Docker Complement Each Other — Docker packages applications into containers, while Kubernetes runs those containers at production scale.
  • Avoid the VM Mentality — containers in Kubernetes are ephemeral. All configuration must be declared in YAML manifests, not configured manually inside a running container.

← Previous: Introduction   Next: Problems It Solves →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact