Kubernetes Container Security Hardening: Field Guide

Kubernetes container security hardening comes down to a small number of controls that stop the majority of real intrusions: blocking privileged pods, constraining what containers can reach, and limiting who can change any of it. Kubernetes ships a built-in Pod Security Admission controller that has been a stable feature since Kubernetes v1.25 and applies pod security restrictions at the namespace level when pods are created. That single mechanism, combined with role-based access control and network segmentation, eliminates most of the paths attackers actually use after they land on a cluster. This guide lays out the controls in deployment order, with the trade-offs engineering teams hit in production.
Why clusters get compromised
Container escapes and cluster takeovers rarely start with an exotic zero-day. The pattern seen in incident after incident is initial access through an unpatched internet-facing service, followed by credential theft and lateral movement. CISA incident responders documented a real intrusion in which attackers exploited an unpatched server for initial access, installed XMRig crypto-mining software and then moved laterally to a domain controller. In Kubernetes environments the equivalent entry points are exposed API servers, unpatched ingress controllers, container registries with weak authentication, and service accounts carrying far more permission than their workloads need. Hardening therefore has to cover both the workload layer and the control plane, because attackers who obtain a kubeconfig or a privileged service account token do not need any container escape at all. The controls below follow that attacker path.
Enforce pod security standards
The Pod Security Standards define three cumulative profiles: privileged, baseline and restricted. Applied through namespace labels, they gate every pod creation request before it reaches the scheduler. The Baseline profile blocks the most common privilege escalation paths: privileged containers are disallowed, sharing host network, PID or IPC namespaces must be denied, and hostPath volumes are forbidden. The Restricted profile enforces current hardening best practices: containers must run as non-root users, privilege escalation must be set to false, and containers must drop all Linux capabilities. For teams that also need policy beyond what the built-in controller checks, Kyverno and OPA Gatekeeper remain the standard alternatives.
| Profile | Blocks | Best fit |
|---|---|---|
| Privileged | Nothing; unrestricted | Trusted system add-ons only |
| Baseline | Privileged containers, host namespaces, hostPath volumes, added capabilities | General application workloads |
| Restricted | Everything in baseline plus root users, privilege escalation, seccomp gaps | Security-critical and multi-tenant workloads |
Each mode can run as enforce, audit or warn, which matters for migration: labeling a namespace baseline:enforce on day one for new workloads, while running restricted:audit against existing deployments, gives you a violation report without breaking production. Promotion checklist:
- Label all new namespaces baseline-enforce at creation time in the namespace template.
- Run restricted in audit mode for two sprint cycles and triage the violations.
- Fix security contexts in Helm charts and manifests, not with ad-hoc kubectl edits.
- Promote namespaces to restricted-enforce once violations reach zero.
- Promote namespaces to restricted-enforce only after the audit window shows zero violations.
Lock down access and traffic
Admission control stops bad pods; RBAC stops bad actors. Apply least privilege to service accounts, disable automounting of the default service account token in namespaces that do not need it, and never grant cluster-admin to CI pipelines. On the network side, a default-deny NetworkPolicy between namespaces converts a compromised pod into a contained problem instead of a pivot point. For teams building this out, the practical patterns in egress traffic control in cloud environments translate directly to Kubernetes egress policies, and the workflow described in cloud vulnerability management covers the scanning and patching discipline that closes the unpatched-server entry point attackers prefer. Keep the API server off the public internet or behind an authenticated proxy, enable audit logging with retention that survives an attacker’s cleanup attempts, and encrypt etcd at rest so node theft does not become secret theft.
Supply chain and runtime layers
Policies only evaluate what arrives at admission, so the images themselves need controls upstream. Pin base images by digest rather than mutable tags, scan images in the registry and in the pipeline, sign them and verify signatures at admission time, and strip setuid binaries and shells from runtime images. At runtime, keep seccomp set to RuntimeDefault across the fleet, consider sandboxed runtimes such as gVisor or Kata Containers for code that executes untrusted input, and alert on anomalous process execution inside pods rather than relying on perimeter alerts alone. These layers are where container security overlaps with the broader cloud vulnerability lifecycle, and treating them as one program rather than separate tooling is what keeps coverage gaps from becoming incident reports.
Operational trade-offs to plan
Hardening has real costs. Restricted profiles break legacy images that assume root, so budget time for rebuilding base images before enforcement, not after incidents. Network policies add debugging friction, which teams solve by pairing them with connection logging rather than loosening rules. Exemptions in Pod Security Admission must be explicit and enumerated, and controller service accounts should never be exempted, because that implicitly exempts every user who can create the corresponding workload. The workable pattern is progressive enforcement, treated as an engineering program with migration windows, rather than a compliance checkbox flipped on a Friday.