Containers, namespaces and cgroups

A container is processes with a restricted view, not a virtual machine — how namespaces isolate each resource, what cgroups limit, and how layered images work.

One namespace per kind of isolation

NamespaceIsolatesVisible effect
PIDProcess idsThe container sees its own PID 1
MountFile system treeIts own root and mounts
NetworkInterfaces, routes, portsIts own IP, its own port space
UTSHostname and domain nameIts own hostname
IPCShared memory and message queuesIsolated queues
UserUser and group id mappingRoot inside is unprivileged outside
CgroupCgroup hierarchy viewOnly its own slice is visible
TimeBoot and monotonic offsetsBoot time differs from the host
# the same view a container runtime builds, done by hand
unshare --pid --fork --mount-proc --uts --ipc --net bash
# inside: a new PID 1, a new hostname, no host network interfaces yet

# what the current process can see
ls -l /proc/self/ns/
readlink /proc/self/ns/net
lsns | head
  • Namespaces change what a process can see; they do not limit how much it can consume.
  • The user namespace is what makes rootless containers possible, mapping container root to an unprivileged host user.
  • A container shares the host kernel, so a kernel vulnerability is a shared risk in a way that does not apply to a virtual machine.
  • Mounting the host's namespace is how debugging tools inspect a running container from outside.

cgroups constrain resources

# inspect the cgroup of a process and its limits
cat /proc/self/cgroup
systemd-cgtop

# a slice with CPU and memory limits
systemctl set-property user-1000.slice MemoryMax=4G CPUQuota=200%

# the kernel's own view
cat /sys/fs/cgroup/system.slice/api.service/memory.max
cat /sys/fs/cgroup/system.slice/api.service/cpu.max
cat /sys/fs/cgroup/system.slice/api.service/memory.current
cat /sys/fs/cgroup/system.slice/api.service/memory.events
ControllerLimitsFailure mode when exceeded
memoryHard and soft limits, swap useThe OOM killer kills the largest process in the cgroup
cpuQuota per period, weightThrottling; the process is paused until the next period
ioBandwidth and IOPS weightsSlower I/O, no error
pidsMaximum process countFork fails with a resource error
cpusetWhich cores may be usedScheduling only on the allowed cores
hugetlbHuge page reservationAllocation fails

A memory limit triggers an OOM kill of a process inside the cgroup, whereas an unbounded container can trigger a host-level kill instead. Setting the limit is what makes the failure local and diagnosable.

Images and why they are layered

  • An image is a stack of read-only layers; a container adds one writable layer on top.
  • A copy-on-write file system means a small change copies one file, not the whole layer.
  • Reusing a base layer shares its bytes across every image built on it, which is why registry pulls are usually fast.
  • Layer order matters for cache hits: put rarely changing instructions early and frequently changing ones last.
  • The writable layer disappears with the container, which is why persistent data must be in a volume or a bind mount.
# dependencies first, source last: this keeps the expensive layer cached
COPY package.json package-lock.json ./
RUN npm ci --omit=dev

COPY . .
RUN npm run build

# a non-root runtime user costs nothing and removes a whole class of risk
USER node
ENTRYPOINT ["node", "dist/server.js"]
⚠️
--memory without --memory-swap can still let a container swap heavily and appear slow rather than fail. Size the limit against the working set, watch memory.events for OOM counts, and treat a rising OOM rate as a capacity signal rather than noise.

FAQ

Is a container as isolated as a virtual machine?
No. Containers share the host kernel, so kernel bugs and some side channels cross the boundary. For untrusted workloads, a VM or a sandboxed runtime is the stronger boundary.
Why does my container see the host's CPU count?
CPU count is not namespaced. Runtime-aware libraries must read the cgroup quota, and many languages needed updates to do that — check the version before trusting thread pool sizing.

Virtualisation and hypervisors Storage and file systems

Last refreshed 2026-09-18.