ReviseAlgo Logo

Containers & Virtualization Fundamentals

Linux Namespaces and cgroups — How Containers Actually Work

Under the hood of Linux kernel primitives for isolation and resource limitation.

Interview: Crucial for deep system architecture, platform engineering, and security-focused roles to demonstrate you understand that containers are just isolated processes, not lightweight virtual machines.

Last Updated: June 14, 2026 15 min read

Introduction

To the end-user, containers look and feel like lightweight Virtual Machines. You can log into them, install packages, configure networks, and run isolated processes. However, a container is not a physical or virtual machine; it is simply a standard Linux process running directly on the host's CPU.

The magic of containers lies entirely in two key features of the Linux Kernel: Namespaces (which provide boundary isolation) and Control Groups (cgroups) (which restrict resource utilization). Together, these features partition the host OS kernel's resources, creating the sandbox we call a container.

Why It Matters

Without namespaces, any container process could inspect the host's file system, kill other containers' processes, or hijack host network ports. Without cgroups, a single runaway container could consume 100% of the host's memory or CPU, starving the operating system and other containers (a classic "noisy neighbor" problem).

Real-World Analogy

Imagine a shared co-working office:
Namespaces are like walls and keycards. You can only see the people and desks in your rented suite (PID namespace), use the designated office WiFi (Network namespace), and access your designated storage locker (Mount namespace). You have no idea what other companies in the building are doing.
cgroups are like facilities rules and quotas. The office manager limits your suite to 10 power outlets (CPU limit), a max water flow rate (I/O limit), and a heating quota (Memory limit). If you try to plug in 100 heavy computers, the circuit breaker trips (OOM kill) to protect the rest of the building.

How Namespaces Work

Namespaces wrap global system resources in an abstraction layer, making processes inside the namespace believe they have their own isolated instance of the resource. There are 8 primary namespaces in Linux:

Namespace What It Isolates Container Behavior
PID (Process ID) Process IDs and trees The container's main process thinks it is PID 1. It cannot see host processes.
NET (Network) IP addresses, routing tables, ports, devices Container gets its own virtual network loopback and interface card (eth0).
MNT (Mount) File system mount points Container sees its own root directory (via chroot/pivot_root) instead of host directories.
IPC (Inter-Process) System V IPC, POSIX message queues Prevents processes in different containers from using shared memory segments.
UTS (Unix Timesharing) Hostname and NIS domain name Allows the container to have a unique hostname (e.g., a random hash like d18fbc8d3120).
USER User and Group IDs mappings UID 0 (root) inside the container can map to UID 10001 (unprivileged) on the host.
CGROUP cgroup directory view Hides host cgroup filesystem paths and shows only the container's own cgroup leaf node.
TIME System clocks (uptime, monotonic time) Allows virtual containers to have independent offsets for system time.

How cgroups Work

While namespaces control what a process can see, cgroups control how much resource a process can use. Under the hood, cgroups are exposed as a virtual filesystem located under /sys/fs/cgroup/.

There are two versions of cgroups in Linux:
cgroups v1: Resource controllers are separated into independent, overlapping trees (e.g., /sys/fs/cgroup/cpu, /sys/fs/cgroup/memory). This design made configuration complex and resource coordination difficult.
cgroups v2: A unified hierarchy model where all controllers are mounted on a single root tree (e.g., /sys/fs/cgroup/). This is the modern standard, resolving performance bugs and making resource tracking clean and consistent.

Practical Example

Let's create an isolated environment manually using the Linux command line. We'll use the unshare command to run a shell inside its own UTS and PID namespaces:

What just happened? The kernel cloned UTS memory maps for our shell. The shell modified its hostname inside the namespace, but the global host UTS data remained unchanged. This is exactly how Docker isolates hostnames!

Quick Quiz

Q1: If a container process consumes more memory than allowed by its cgroup limit, what happens?

A) The host operating system crashes.

B) The process continues running but slower (throttled).

C) The host kernel Out-of-Memory (OOM) Killer terminates the container process immediately.

D) The namespace is deleted.

Answer: C — The OOM Killer terminates the process (giving Exit Code 137) to prevent host crash.

Scenario-Based Challenge

Production Scenario:

A JVM application runs inside a Kubernetes pod with a memory limit of 512MB. The JVM heap is configured via -Xmx512m. The application crashes randomly with OOMKilled (Exit Code 137). Why did it crash, and how do you resolve it?

View Solution

The JVM requires memory beyond just the heap (such as Metaspace, threads stack, garbage collector overhead, and off-heap allocations). Setting -Xmx512m tells the JVM heap it can grow to 512MB, pushing the total process usage beyond 512MB. The kernel cgroup intercepts this exceedance and sends a SIGKILL (Exit Code 137).

Solution: Configure the JVM heap to use roughly 70-80% of the cgroup limit (e.g., -Xmx384m), or use modern flags like -XX:MaxRAMPercentage=75.0 which automatically align JVM memory with container cgroup limits.

Interview Questions

1. What is the fundamental difference between namespaces and cgroups?

Namespaces restrict visibility (what resources a process can see and touch). cgroups restrict utilization (how much of a hardware resource like CPU, memory, or disk I/O a process can consume).

2. What is a fork bomb, and how do cgroups protect a host from it?

A fork bomb is a process that infinitely spawns children to deplete host process resources, causing system denial of service. Under cgroups v2, the pids controller limits the total number of processes a cgroup slice can create (e.g., max 50 processes). Once the limit is hit, the fork call fails, isolating the impact entirely inside the container.

Production Considerations

In production, never run containers without memory and CPU cgroup limits. A memory leak in one container could exhaust the host's memory, prompting the kernel OOM killer to terminate critical system services like sshd or kubelet. Always configure resource limits and test under load to ensure appropriate CPU throttling configuration and prevent unexpected OOM failures.