Harshit Batra
← Back to Resources

Operating System

Virtualization vs Abstraction (and Why VMs Aren't Containers)

I open every OS course with one question before touching a diagram: why does an operating system need to exist at all? Without one, every program would need to know exactly where in physical RAM it runs, and no two programs could safely share one CPU. The OS's job is maintaining an illusion — that your process owns the CPU, owns a clean memory space, owns its own disk — while actually managing a resource shared across dozens of processes doing the same thing.

Abstraction and virtualization are not the same thing

  • Abstraction hides complexity. A file descriptor is an abstraction over the mess of disk blocks, sectors, and controllers underneath.
  • Virtualization shares resources. It creates the illusion that you have exclusive access to something you're actually sharing with other processes.

They're related — virtualization is built using abstractions — but distinct. Shorthand: abstraction = complexity, virtualization = resources.

Physical Hardware What hardware actually provides OS Abstraction What the programmer sees
CPU Executes instructions on a limited number of cores Process / Thread main(), threads, processes
RAM Physical memory addresses Virtual Memory Variables, pointers, malloc()
SSD / HDD Blocks, sectors, physical storage File / Directory open(), read(), write()
Network Card Ethernet/IP packets Socket socket(), send(), recv()

Every row is the same move: the OS takes something physical and messy, hands the programmer something clean and logical instead.

Where this gets tested: VM vs container

The question that actually separates understanding from memorized "containers are lighter than VMs": what, specifically, is being virtualized in each case?

A virtual machine virtualizes the entire machine — a hypervisor virtualizes hardware, and each VM runs its own full guest OS on top. A container doesn't virtualize hardware at all; it isolates a process's view of an already-running OS, and every container shares the host's kernel.

VM = virtualization, container = isolation. Calling containers "lightweight VMs" gets the mechanism backwards — it's the single most common mistake I see in interviews.

flowchart TB
    subgraph VM["Virtual Machines"]
        direction TB
        VA["App 1 | App 2 | App 3"] --> VB["Bins/Libs (x3)"]
        VB --> VC["Guest OS (x3)"]
        VC --> VD["Hypervisor"]
        VD --> VE["Host OS"]
        VE --> VF["Infrastructure"]
    end
    subgraph CT["Containers"]
        direction TB
        CA["App 1 | App 2 | App 3"] --> CB["Bins/Libs (x3)"]
        CB --> CC["Container Engine"]
        CC --> CD["Operating System"]
        CD --> CE["Infrastructure"]
    end

Three guest OS copies vs. zero — that's where the weight difference comes from, not a vague "containers are more efficient."

How containers isolate without a hypervisor

Namespaces. One of the few OS concepts you can inspect directly on a running system:

$ lsns
NS TYPE    NPROCS PID USER COMMAND
... mnt     21    117 vscode /bin/sh
... uts     21    117 vscode /bin/sh
... ipc     21    117 vscode /bin/sh
... pid     21    117 vscode /bin/sh
... net     21    117 vscode /bin/sh

Each namespace type hides a different category of resource — PID namespace hides other processes' PIDs, net namespace hides other containers' network interfaces. A container is, mechanically, a regular process on the host OS given a restricted namespace view. Docker's "magic" is namespaces + cgroups + capabilities wired together — cgroups cap what resources a process can use, namespaces control what it can see.

One more distinction worth being exact about: userspace is where ordinary programs (shell, app, libc) run, as opposed to the kernel. Namespaces control visibility; userspace is about protecting the kernel from a crashing app — different problems.

Quick recall

  • OS exists to maintain an illusion: exclusive CPU, clean memory, private disk — over resources actually shared across processes
  • Abstraction hides complexity; virtualization shares resources — related but not the same thing
  • VM = virtualization (own guest OS, hypervisor); container = isolation (shares host kernel, uses namespaces)
  • Namespaces control what a process can see; userspace is where it executes — different problems

I don't move to processes or scheduling until this is solid — "why does a container start in milliseconds" and "why can a container see host CPU count" both fall out of it directly once abstraction-vs-virtualization and VM-vs-container are genuinely distinct in your head.

Quick quiz

  • 1. What's the one-line distinction between abstraction and virtualization?

  • 2. What's the actual mechanism difference between a VM and a container?

  • 3. What do Linux namespaces actually control?