Kubernetes in Production · Configuration and Security

Privileged Containers and Pod Security Admission

A privileged pod or a hostPath mount is a path to the node; enforce the restricted Pod Security Standard per namespace.

Create a free account to save this page, take notes and track your progress. Sign in

Scenario

Example company: a team copies a debugging DaemonSet from a blog post into production. It runs privileged: true with the host filesystem mounted. Later, an application namespace is also found running containers as root with hostPath volumes.

What you see in production

A security assessment shows that anyone able to deploy into those namespaces can become root on the nodes by creating a privileged pod that mounts /. Nothing in the cluster stopped such pods from being created.

The naive code

securityContext:
  privileged: true            # full access to the host's devices and kernel features
volumes:
  - name: host
    hostPath: {path: /}

Reproduce it

Label a namespace to enforce the restricted Pod Security Standard and try to create a privileged pod and a compliant one:

Pod Security Admission rejects the unsafe pod
kubectl create namespace prod-psa > /dev/null
trap 'kubectl delete namespace prod-psa --wait=false > /dev/null' EXIT
kubectl label namespace prod-psa pod-security.kubernetes.io/enforce=restricted > /dev/null
kubectl -n prod-psa run unsafe --image=busybox:1.37 --overrides='{"spec":{"containers":[{"name":"unsafe","image":"busybox:1.37","command":["sleep","3600"],"securityContext":{"privileged":true}}]}}' 2>&1 | sed -E 's/^Error from server \(Forbidden\): //' | cut -c1-160
cat > safe.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata: {name: safe}
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 10001
    seccompProfile: {type: RuntimeDefault}
  containers:
    - name: app
      image: busybox:1.37
      command: ["sleep", "3600"]
      securityContext:
        allowPrivilegeEscalation: false
        capabilities: {drop: [ALL]}
        readOnlyRootFilesystem: true
EOF
kubectl -n prod-psa apply -f safe.yaml

Output

pods "unsafe" is forbidden: violates PodSecurity "restricted:latest": privileged (container "unsafe" must not set securityContext.privileged=true), allowPrivile
pod/safe created

Run this on your computer — see “Get Started” for setup.

Root cause

By default Kubernetes admits any pod the requester is allowed to create, including privileged containers, host namespaces and host path mounts, each of which can break out to the node. Pod Security Admission (built in since 1.25) applies the Pod Security Standards per namespace, but only when namespaces are labelled.

The fix

  • Label every application namespace pod-security.kubernetes.io/enforce=restricted (or baseline where restricted is impossible), with warn and audit labels to see violations before enforcing.
  • Write pods to the restricted profile: non-root user, allowPrivilegeEscalation: false, drop all capabilities, seccompProfile: RuntimeDefault, read-only root filesystem where possible.
  • Keep privileged system components (CNI, storage drivers, node agents) in dedicated namespaces with the privileged level and strict RBAC on who can deploy there.
  • Add a policy engine (Kyverno, Gatekeeper, ValidatingAdmissionPolicy) for rules beyond the standards (allowed registries, required labels).

Trade-offs

  • Some third-party charts don't meet restricted; you may need overrides or a baseline namespace.
  • Read-only root filesystems need writable emptyDir mounts for temp files.
  • Enforcing on existing namespaces can block deployments; roll out with warn first.

Detect it in production

  • Namespaces without Pod Security labels.
  • Audit annotations and warnings from warn/audit modes.
  • Pods running as root, privileged, or with hostPath volumes.

Key points

  • Privileged pods and host mounts are node compromise waiting to happen.
  • Pod Security Admission enforces the standards per namespace via labels.
  • Default to restricted; isolate the few privileged system workloads.

Further reading: Pod Security Standards · Pod Security Admission

Practice questions

How do you enable Pod Security Admission for a namespace?

Answer

Label it, for example pod-security.kubernetes.io/enforce=restricted, optionally with warn and audit labels; the built-in admission controller then checks every pod against that level.

Name four settings a pod needs to pass the restricted Pod Security Standard.

Answer

runAsNonRoot true, allowPrivilegeEscalation false, capabilities dropping ALL, and a seccomp profile of RuntimeDefault (plus no privileged mode, host namespaces or hostPath).

Why roll out Pod Security enforcement with warn and audit first?

Answer

To see which existing workloads would be rejected and fix them before enforcing, so deployments don't suddenly fail.

Open in the app to mark lessons complete, take notes and track your progress.

Was this page helpful?