We use analytics cookies.We use cookies to analyze site traffic and improve your experience.
Loading...
System Design Masterclass · Kubernetes Containers
Free preview: the first 2 parts of this 7-part lesson.
Already bought the course? Sign in to read the whole lesson.
this lesson is part of
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design courseread the rest of this lesson in
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design coursein Kubernetes Containers
This lesson is part of the full System Design Masterclass. Unlock it along with 769 other lessons for a one-time payment.
One-time payment by card or PayPal
Get Lifetime AccessOne-time payment: UPI, card or netbanking
Get Lifetime Access18 Foundation lessons are free, no payment needed. Try them now
It is easy and good
“It is really nice and good Please join the course”
It's 2015. A developer writes an application on their Mac using Node.js 14, a specific version of ImageMagick, and a particular OpenSSL build. It works perfectly. They ship it to the staging server running Ubuntu with Node.js 12, a different ImageMagick, and a patched OpenSSL. It crashes. Three developers spend two days debugging environment differences.
This wasn't an edge case. It was the norm. Every deployment was a prayer. "It works on my machine" became the industry's most infamous excuse because application code is only one part of the picture. The operating system, system libraries, language runtime, and dependency versions all matter. A mismatch in any of them can break everything.
Containers solved this by packaging the application together with its entire runtime environment. OS libraries, language runtime, dependencies, configuration files, all of it goes into a single portable unit. If it runs in a container on your laptop, it runs in the same container on any server, any cloud, any operating system that has a container runtime. The "works on my machine" problem disappears because the machine is part of the package.
Docker popularized containers in 2013 by wrapping Linux namespaces and cgroups into a developer-friendly CLI. Today, containers are the standard unit of deployment. , ECS, Cloud Run, Fly.io, Railway, every modern platform runs containers. Netflix runs thousands per region. Spotify runs 1,800+ containerized services. Shopify migrated their entire merchant platform off bare metal and into containers. If you deploy software in 2026, you deploy containers.
Containers and VMs both provide isolation, but through fundamentally different mechanisms.
Virtual Machines run a complete operating system on top of a hypervisor. Each VM has its own kernel, OS, libraries, and application. A VM running Ubuntu on a macOS host literally boots an entire Linux OS. That's 500MB to 2GB just for the guest OS, before your application even starts.
Containers share the host's kernel. They use two Linux kernel features to create isolation without the overhead of a full OS:
Namespaces give each container its own isolated view of the system. There are six types: PID (process IDs), NET (network interfaces), MNT (filesystem mounts), UTS (hostname), IPC (inter-process communication), and USER (user IDs). Container process 1 thinks it's PID 1, but the host sees it as PID 4827.
Cgroups (control groups) limit how much CPU, memory, and I/O each container can consume. You can cap a container at 512MB RAM and 0.5 CPU cores. If it exceeds the memory limit, the kernel kills it instantly (OOM kill).
Together, namespaces provide isolation (each container sees its own world) and cgroups provide resource control (each container gets its fair share). No hypervisor. No guest OS. Just kernel-level process isolation.
A Dockerfile, the container recipe:
FROM node:20-alpine # Base image: Alpine Linux + Node.js 20
WORKDIR /app # Set working directory
COPY package*.json ./ # Copy dependency manifest
RUN npm ci --production # Install dependencies (cached layer)
COPY . . # Copy application code
EXPOSE 3000 # Document the port
CMD ["node", "server.js"] # Default start command
This Dockerfile produces an image, a read-only template. When you run the image, you get a container, a running instance with a thin writable layer on top. One image can spawn thousands of identical containers.