6.4 Container and cluster security
Describes container and cluster security as of August 2026
What this is and why it exists
Containers isolate less than people assume and clusters trust more than people expect, and both gaps are closed by settings that are off by default. This lesson names the ways a container escapes or a cluster gets taken, and the small set of changes that block the common ones — all of which cost nothing and are almost never applied to a cluster nobody has thought about.
The vocabulary
- Base image provenance — knowing who published the image you build on, and being able to prove it has not changed.
- Digest pinning — referring to an image by its content hash rather than a tag that can move.
- Non-root — running the container's process as an ordinary user rather than as root inside the container.
- Capabilities — the pieces of root's power the kernel hands out separately; a container starts with more than it needs.
- Privileged container — one given essentially the host's power, which removes most of the isolation.
- RBAC — role-based access control inside the cluster: who and what may call the API.
- Service account — the identity a Pod presents to the cluster API.
- Network policy — a rule about which Pods may talk to which; absent one, everything can talk to everything.
The mental model
Two attack surfaces, and they are separate. The first is the container itself: what is inside the image, and what the process inside it is allowed to do. The second is the cluster: what a Pod can ask the API for, and what it can reach across the network. Most real compromises use both — a vulnerability in an application gets someone inside a Pod, and then the cluster's defaults let them go somewhere interesting.
Start with the image, because it is the cheapest thing to fix. An image is a filesystem somebody assembled; running one whose origin you cannot name is running a stranger's code with your permissions. So build from official base images, pin them by digest rather than by a tag that moves under you, scan images in the build pipeline and fail the build rather than filing the result, and rebuild regularly so that a patched base actually reaches production. That last one is the habit most teams lack: scanning finds the problem, and only rebuilding fixes it.
Then what the process may do. A container that runs as root runs as root — the same user as the host's root in the common configuration — and if anything ever crosses the boundary, that is who crosses it. Running as a non-root user and dropping the capabilities you do not need turns a hypothetical escape into a much less useful one, and almost no application needs any of it. Never grant privileged mode to something you do not fully understand, because it removes most of what is between the container and the machine.
Escape itself is worth being honest about. It is rare and it usually needs a kernel vulnerability or a misconfiguration you supplied — a privileged container, the host filesystem mounted in, the container runtime's socket exposed. The reason to care is not that escape is likely but that the mitigations are free, and that mounting the runtime socket into a container is equivalent to handing over the node, which people do accidentally when a build job needs to build images.
The cluster half has one big default worth knowing before anything else: without a network policy, every Pod can reach every other Pod. A compromised frontend can talk directly to the database Pod, to the metrics stack, to everything in every namespace. A default-deny policy per namespace with explicit allowances is the single most valuable thing you can add to a cluster nobody has secured, and it is the one people leave until last because nothing is broken without it.
RBAC is the other half, and the failure is the same one from the identity module wearing cluster clothes. Every Pod gets a service account and its token is available inside the Pod; if that account is bound to a broad role, an application vulnerability becomes cluster access. So: give each workload its own service account, bind it to only what it needs, turn off token mounting for the many workloads that never call the API at all, and be extremely careful with anything granted cluster-wide permissions. Read a role binding the way you read an access policy — identity, action, resource — because that is exactly what it is.
What you should now be able to explain or do
Name the two separate attack surfaces and give one control for each. Explain why scanning alone does not fix a vulnerable base image. Say what running as non-root and dropping capabilities buys, and why it is nearly free. State what mounting the container runtime's socket into a Pod is equivalent to. Say what Pods can reach by default and what to do about it. Explain how a service account turns an application vulnerability into cluster access, and the three ways to stop it.
Check yourself
Your scanner reports a vulnerable library in your base image and you upgrade nothing else. Are you fixed?
No. Scanning finds; rebuilding from the patched base fixes. A finding that is filed rather than rebuilt is a known vulnerability you have chosen to keep running.
Why pin a base image by digest rather than by tag?
Because a tag can be repointed at different content, so the same Dockerfile stops producing the same image. A digest is the content, which is what reproducibility and provenance both need.
Two Pods in different namespaces, no network policies anywhere. Can one reach the other?
Yes. The default is that every Pod can reach every other Pod. A default-deny policy per namespace with explicit allowances is usually the highest-value change available.
What does mounting the container runtime's socket into a Pod give whoever is in that Pod?
Effectively the node — the ability to start containers with any settings, including privileged ones. It comes up when a build job needs to build images, and it is worth solving another way.
An application in a Pod is compromised. What decides whether that becomes cluster access?
The Pod's service account and what it is bound to. Give each workload its own account with only what it needs, turn off token mounting where the API is never called, and treat cluster-wide roles as exceptional.
Go deeper
We haven't checked most of these for screen reader use yet.
Back to Container and cluster security: work through the checklist