Pular para o conteúdo principal
Processes, IPC (including semaphores), scheduling, memory, I/O, file systems, virtualization, concurrency models, performance profiling, and the hardware-software interface.

Operating Systems

Processes, IPC (including semaphores), scheduling, memory, I/O, file systems, virtualization, concurrency models, performance profiling, and the hardware-software interface.

Virtualization & Containers

The OS Virtualized Again

The OS virtualizes hardware for applications. Virtualization virtualizes an entire OS: one physical machine runs multiple OS instances (VMs), each believing it owns the hardware. The layer that makes this possible is the hypervisor — and the same isolation instinct, taken a level higher, produces containers, which don’t virtualize a machine at all but package an application with its own view of the OS.

This topic connects the OS abstractions you’ve learned to the two isolation technologies you’ll actually deploy: VMs and containers. The thread through both is the same one from the OS Architecture topic — each guest must be fooled into thinking it has the whole machine.

Why Virtualize

  • Consolidation — many underused physical servers collapse onto one, raising utilization.
  • Isolation & security — a compromised VM doesn’t reach the host or its neighbors.
  • Snapshots, migration, and clones — a VM is just files; it can be checkpointed, moved live, or duplicated in seconds.
  • Portability & testing — run different OS versions side by side on one developer machine.

The cost is overhead: the extra layer between guest and hardware, and the price of sharing.

Hypervisor Architectures

  • Type 1 (bare-metal) — the hypervisor is the OS on the hardware: Xen, KVM (Linux’s kernel module), Microsoft Hyper-V, VMware ESXi. Guests run above it. Used in every cloud — when you rent an EC2 or Azure VM, this is what runs underneath.
  • Type 2 (hosted) — the hypervisor runs as an application on a normal OS: VirtualBox, VMware Workstation, QEMU (user mode). Good for developer laptops; adds a layer (host OS + hypervisor) so it’s heavier and less suited to production density.

In practice the line blurs: KVM is a Type-1-style hypervisor built into the Linux kernel, so a Linux host provides the management while the kernel does the virtualization.

Full, Para-, and Hardware-Assisted Virtualization

Early hypervisors used binary translation: the hypervisor rewrote privileged guest instructions on the fly so the guest couldn’t grab the hardware. That worked but was slow and fragile. Two cleaner approaches followed:

  • Para-virtualization — the guest knows it’s virtualized: its kernel is modified to call the hypervisor directly (hypercalls) for privileged operations instead of trying to execute them. Fast, but requires a modified guest OS. Xen’s PV mode is the classic example.
  • Hardware-assisted virtualization — modern CPUs (Intel VT-x, AMD-V, ARM virtualization extensions) add a guest mode to the hardware. Privileged operations trap to the hypervisor automatically, and a nested page table (EPT/NPT) lets the guest manage its own page tables without the hypervisor mediating every mapping. Unmodified guests run at near-native speed — this is the default today.

The practical result: modern VMs don’t need a modified guest kernel, and the virtualization overhead is mostly I/O — which is why clouds pair VMs with paravirtualized I/O devices (virtio on Linux/KVM, Hyper-V’s vmbus) that give guests a fast, shared path to disks and NICs.

Containers: The OS-Feature View

A container is not a virtual machine. It is a set of processes on a shared kernel that the OS has been told to isolate. Two kernel features do the work (on Linux; Windows has an analogous job-object/sil-launcher model):

  • Namespaces — give a process group its own view of the system: its own PID tree (a container’s PID 1 isn’t the host’s PID 1), its own network stack, mount table, user IDs, IPC queue, hostname, and UTS identity. Namespaces are what make ps inside a container show only the container’s processes.
  • Cgroups — control and account resource usage: CPU shares, memory limits, block I/O, PID counts. Cgroups are what enforce “this container may use 512 MB and 2 CPUs” and are the measuring stick for docker stats.

A container runtime (Docker, containerd, CRI-O) is mostly a manager: it creates a set of namespaces, applies cgroup limits, mounts the image’s root filesystem, and runs the container’s init process. The security enforcement you see in the OS Security topic — seccomp syscall filtering, capability dropping, read-only root — is layered on top.

VM vs Container Trade-offs

DimensionVirtual MachineContainer
What’s isolatedEntire OS (guest kernel)Process group on the host kernel
Isolation strengthStrong (separate kernel)Weaker (shared kernel; escapes affect host)
Boot timeSeconds (full OS boot)Milliseconds (start a process)
FootprintGBs (guest OS image)MBs (app + runtime layers)
Density per hostTensHundreds to thousands
OS flexibilityAny guest OSMust share the host kernel (Linux/Windows)
Snapshots/checkpointMatureEmerging
Typical useFull workloads, mixed OSesMicroservices, CI, app packaging

The rule of thumb: containers for application density and velocity, VMs for hard isolation and running foreign OSes. In practice clouds combine them — containers run inside VMs (Kubernetes nodes are VMs) so that a container escape is contained by the VM boundary.

The OS as the Isolation Boundary

Both technologies lean on concepts you already know:

  • A VM’s memory isolation uses the same page-table machinery the Memory Management topic covered — the hypervisor’s nested page tables extend it one level.
  • A container’s CPU/memory limits use the same scheduling and memory management the OS already does.
  • Both are only as secure as the boundary: a hypervisor bug is a cloud-wide vulnerability; a container with too many capabilities and an open seccomp profile is a host-escalation path (see OS Security).

Understanding OS fundamentals is precisely what lets you reason about where the boundary is — and therefore what a breach actually breaks.

Worked Example: What a Container Sees

Launch a container running bash. Inside it:

  1. ps aux shows only the container’s processes — because the PID namespace remaps PIDs (the container’s PID 1 is bash, not the host’s init).
  2. cat /sys/fs/cgroup/... shows the memory/CPU limits — the cgroup of the container.
  3. The root filesystem is the image, not the host’s — the mount namespace + an overlay/chroot-like view.
  4. ifconfig shows the container’s virtual NIC (veth), which the bridge connects to the host’s network namespace.

Nothing inside is magic: it is a normal Linux process tree, just with namespaces and cgroups applied. That’s why the ps//proc/journalctl skills from Linux/Unix Fundamentals work identically inside a container.

Practice Trajectory

  1. On a Linux host, use unshare -n (or unshare --mount) to create a throwaway namespace and observe the different view of the network/mount table; nsenter back into the host namespace.
  2. Run docker run --rm -it --memory=128m --cpus=0.5 alpine sh and inspect /sys/fs/cgroup; stress the memory limit and watch the OOM killer act.
  3. Compare uname and ps aux inside a container vs on the host; identify which namespaces are doing the isolation.
  4. On a VM host, read lscpu/systeminfo inside a guest and spot the virtual CPU/NIC models — evidence of the paravirtualized device layer.
  5. Explain, in two sentences, why a container escape is more dangerous than a VM escape.

When It’s the Right Tool

SituationTakeaway
Cloud VMs (EC2, Azure, GCP)Type-1 hypervisors (KVM/Hyper-V) with virtio I/O
Application packaging & microservicesContainers — fast, dense, portable
Running a foreign OSVM — you need a separate kernel
Hard multi-tenant isolationVM boundary, not bare containers
Developer environmentsHosted (Type 2) hypervisors like VirtualBox
Security reviewKnow where the boundary is: hypervisor vs namespaces/cgroups