Capabilities, namespaces & cgroups
Drop ALL, non-root, and the isolation primitives.
Namespaces, capabilities, and cgroups are the primitives every container is built from, and hardening them is what makes the container boundary meaningful. A container is just a process with isolated views and reduced privilege — so the security work is minimizing that privilege and tightening those views.
Capabilities: split and drop root
The Linux kernel splits root’s power into roughly forty capabilities — CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, CAP_SYS_PTRACE, CAP_DAC_READ_SEARCH, and so on. A container should drop ALL and add back only the few it genuinely needs; most web workloads need none. CAP_SYS_ADMIN is the one to fear most — it re-enables mounts and namespace operations that underpin many escapes, which is why it is nicknamed "the new root". Auditing which containers hold which capabilities is one of the highest-value hardening exercises.
securityContext:runAsNonRoot: truerunAsUser: 10001allowPrivilegeEscalation: false # block setuid/gaining new privsreadOnlyRootFilesystem: truecapabilities:drop: ["ALL"] # start from zeroadd: ["NET_BIND_SERVICE"] # add back only if truly neededseccompProfile: { type: RuntimeDefault }# Never: privileged: true, hostPID, hostNetwork, or a hostPath mount of /
Namespaces, user namespaces, and cgroups
Namespaces isolate a container’s view of PIDs, network, mounts, and users; user namespaces go further by mapping root inside the container to an unprivileged UID on the host, so container-root is not host-root and an escape lands with far less power. cgroups cap resources (CPU, memory, PIDs) — which is also a security control, since a PID or memory limit blunts fork-bomb and resource-exhaustion attacks. Sharing host namespaces (hostPID, hostNetwork, hostIPC) or running privileged collapses these boundaries, which is why they are the settings admission policy should forbid.