Using procMount in your Kubernetes Pod

Recently, I ran across Kubernetes Enhancement Proposal (KEP) 4265 where the authors update the Pod.spec.procMount capability to manage /proc visibility in a Pod’s security context. With this KEP moving to on-by default in v1.29.0, Unmasked disables masking and allows all paths in /proc (not just read-only).

What this means is the Default procMount prevents containers from accessing sensitive kernel data or interacting with host-level processes. With this enhancement, you can run unprivileged containers inside a container (a container-in-a-container), build container images within a Pod, and use buildah in a Pod.

The authors said it best in the KEP:

The /proc filesystem is a virtual interface to kernel data structures. By default, Kubernetes instructs container runtimes to mask or restrict access to certain paths within /proc to prevent accidental or malicious exposure of host information. But this becomes problematic when users want to:

Here is an example of creating a Pod:

  1. create the project
oc new-project proc-mount-example
  1. Create the Pod
cat << EOF | oc apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: nested-container-builder
  namespace: proc-mount-example
spec:
  securityContext:
    runAsUser: 0
  containers:
  - name: builder
    image: registry.access.redhat.com/ubi9/ubi
    securityContext:
      privileged: true
      procMount: Unmasked
    command: ["/bin/sh"]
    args: ["-c", "sleep 3600"]
EOF
  1. Switch to terminal and install podman
oc rsh nested-container-builder
dnf install -y podman
  1. Change the Shell (so you know when the parent is in focus…)
export PS1="parent-container# "
podman run --name abcd --rm -it registry.access.redhat.com/ubi9/ubi sh
  1. Run a privileged command again
parent-container# podman run --name abcd --rm -it registry.access.redhat.com/ubi9/ubi sh
sh-5.1# dnf install -y podman
  1. Now Run another in the nested one, you’ll see a failure in the /dev/net/tun.
sh-5.1# podman run --name abcd --rm -it registry.access.redhat.com/ubi9/ubi sh
Trying to pull registry.access.redhat.com/ubi9/ubi:latest...
Getting image source signatures
Checking if image destination supports signatures
Copying blob ea2f7ff2baa2 done   | 
Copying config 4da9fa8b5a done   | 
Writing manifest to image destination
Storing signatures
ERRO[0018] Preparing container d402a22ebe452597a83b3795639f86e333c1dbb142703737d6d705c6a6f445c7: setting up Pasta: pasta failed with exit code 1:
                Failed to open() /dev/net/tun: No such file or directory
                                                                        Failed to set up tap device in namespace 
Error: mounting storage for container d402a22ebe452597a83b3795639f86e333c1dbb142703737d6d705c6a6f445c7: creating overlay mount to /var/lib/containers/storage/overlay/ab589890d52b88e51f1f945b55d07ac465de1cefd2411d8fab33b4d2769c4404/merged, mount_data="lowerdir=/var/lib/containers/storage/overlay/l/K6CXJGRTW32MPWEIMAH4IGCNZ5,upperdir=/var/lib/containers/storage/overlay/ab589890d52b88e51f1f945b55d07ac465de1cefd2411d8fab33b4d2769c4404/diff,workdir=/var/lib/containers/storage/overlay/ab589890d52b88e51f1f945b55d07ac465de1cefd2411d8fab33b4d2769c4404/work,nodev,volatile": using mount program /usr/bin/fuse-overlayfs: unknown argument ignored: lazytime
fuse: device not found, try 'modprobe fuse' first
fuse-overlayfs: cannot mount: No such file or directory
: exit status 1

It has the default access:

  • Default: Maintains the current behavior—masking sensitive /proc paths. If procMount is not specified, it defaults to Default, ensuring backward compatibility and preserving security for most workloads.
  • Unmasked: Bypasses the default masking, giving the container full access to /proc.

Allowing unmasked access to /proc is a privileged operation. A container with root access and an unmasked /proc could potentially interact with the host system in dangerous ways. This powerful feature should be carefully used.

Good luck.

References