Namespaces and Cgroups
What It Is
Namespaces and cgroups are two Linux kernel features that, together, provide process isolation. They are the building blocks of containers -- Docker, Podman, LXC, and FortrOS's container runtime all use them.
Namespaces control what a process can see. A process in a PID namespace only sees processes in its namespace. A process in a mount namespace has its own filesystem view.
Cgroups (control groups) control what a process can use. A cgroup can limit CPU time, memory, disk I/O, and number of processes.
Together: namespaces hide the rest of the system, cgroups limit resource consumption. The result is an isolated environment that looks like its own machine.
Why It Matters
Without isolation, a misbehaving process can:
- See and kill other processes
- Read files it shouldn't
- Consume all available RAM or CPU
- Bind to ports that other services need
Namespaces and cgroups prevent all of these without the overhead of a full virtual machine. Containers start in milliseconds (just a process with restrictions), while VMs take seconds to minutes (full kernel boot).
How It Works
Namespaces
Linux provides 8 namespace types:
| Namespace | Isolates | Created with |
|---|---|---|
| PID | Process IDs | CLONE_NEWPID |
| Mount | Filesystem mounts | CLONE_NEWNS |
| Network | Network interfaces, IPs, ports, routing | CLONE_NEWNET |
| UTS | Hostname and domain name | CLONE_NEWUTS |
| IPC | Inter-process communication (shared memory, semaphores) | CLONE_NEWIPC |
| User | UIDs and GIDs | CLONE_NEWUSER |
| Cgroup | Cgroup root view | CLONE_NEWCGROUP |
| Time | System clocks (since 5.6) | CLONE_NEWTIME |
A process enters new namespaces via unshare() (detach from current namespace)
or clone() (create child in new namespace). FortrOS uses unshare +
pivot_root (change the root filesystem) to create isolated containers.
Cgroups v2
Cgroups v2 (unified hierarchy) organizes processes into a tree:
/sys/fs/cgroup/
system.slice/
fortros-maintainer.scope/
cgroup.procs # PIDs in this group
memory.max # 512M
cpu.max # 100000 100000 (100% of 1 core)
pids.max # 100
Key controllers:
- memory:
memory.maxlimits total memory.memory.hightriggers throttling before hard limit. - cpu:
cpu.maxlimits CPU time (quota/period in microseconds). - pids:
pids.maxlimits process count (prevents fork bombs). - io:
io.maxlimits disk I/O bandwidth.
How FortrOS Uses It
FortrOS's container runtime (~200 lines of Rust using the nix crate):
unshare(PID | MOUNT | UTS)-- create new namespacespivot_root(new_root, put_old)-- switch to the container's root filesystem- Set up cgroup v2 limits (memory, CPU, PIDs)
execthe container's entrypoint
Host network (WireGuard overlay) is shared -- tier 2 containers can access org services directly. This is a deliberate choice: container networking complexity (veth pairs, bridges, NAT) is avoided because the overlay already provides the network boundary.
Alternatives
VMs (KVM): Stronger isolation (separate kernel), more overhead. FortrOS uses VMs for tier 3/4 workloads where kernel-level isolation is needed.
gVisor: Google's container runtime with a user-space kernel. Intercepts syscalls for sandboxing. Stronger than raw namespaces but slower.
Firecracker: Amazon's microVM -- a minimal VMM that boots a VM in ~125ms. Lighter than QEMU but heavier than containers.