7.10. Accessing faster builds with /dev/fuse
You can configure your pods with the /dev/fuse device to enable faster and more efficient container image builds, particularly for unprivileged users. This device allows unprivileged pods to mount overlay filesystems, which can be leveraged by tools such as Podman.
You can grant an unprivileged pod the capability to perform Filesystem in Userspace (FUSE) mounts by exposing the /dev/fuse device. With this setup, an unprivileged user within the pod can use tools such as podman with storage drivers such as fuse-overlayfs by mimicking privileged build capabilities in a secure and efficient manner without granting full privileged access to the pod.
You expose the /dev/fuse device by adding the io.kubernetes.cri-o.Devices: "/dev/fuse" annotation to your pod definition.
Procedure
Define the pod with
/dev/fuseaccess:Create a YAML file named
fuse-builder-pod.yamlwith the following content:apiVersion: v1 kind: Pod metadata: name: fuse-builder-pod annotations: io.kubernetes.cri-o.Devices: "/dev/fuse" spec: containers: - name: build-container image: quay.io/podman/stable command: ["/bin/sh", "-c"] args: ["echo 'Container is running. Use oc exec to get a shell.'; sleep infinity"] securityContext: runAsUser: 1000where:
metadata.annotations-
Specifies that the
io.kubernetes.cri-o.Devices: "/dev/fuse"annotation makes the FUSE device available. spec.containers.image-
Specifies a container that uses an image that includes
podman(for example,quay.io/podman/stable). spec.containers.args-
Specifies a command to keep the container running so you can
execinto it. spec.containers.securityContextSpecifies a
securityContextthat runs the container as an unprivileged user (for example,runAsUser: 1000).注意Depending on your cluster’s Security Context Constraints (SCCs) or other policies, you might need to further adjust the
securityContextspecification, for example, by allowing specific capabilities if/dev/fusealone is not sufficient forfuse-overlayfsto operate.
Create the pod by running the following command:
$ oc apply -f fuse-builder-pod.yaml
Verify that the pod is running by running the following command:
$ oc get pods fuse-builder-podAccess the pod and prepare the build environment:
After the
fuse-builder-podpod is in theRunningstate, open a shell session into thebuild-containerenvironment by running the following command:$ oc exec -ti fuse-builder-pod -- /bin/bashYou are now inside the container.
Because the default working directory might not be writable by an unprivileged user, change to a writable directory such as
/tmpby running the following commands:$ cd /tmp$ pwd/tmp
Create a dockerfile and build an image by using Podman:
Inside the pod’s shell and within the
/tmpdirectory, you can now create aDockerfileand usepodmanto build a container image. Iffuse-overlayfsis the default or configured storage driver, Podman is able to leveragefuse-overlayfsbecause of the available/dev/fusedevice.Create a sample
Dockerfile:$ cat > Dockerfile <<EOF FROM registry.access.redhat.com/ubi9/ubi-minimal RUN microdnf install -y findutils && microdnf clean all RUN echo "This image was built inside a pod with /dev/fuse by user $(id -u)" > /app/build_info.txt COPY Dockerfile /app/Dockerfile_copied WORKDIR /app CMD ["sh", "-c", "cat /app/build_info.txt && echo '--- Copied Dockerfile ---' && cat /app/Dockerfile_copied"] EOFBuild the image by running the following command. The
-tflag tags the image.$ podman build -t my-fuse-built-image:latest .You should see Podman executing the build steps.
Optional: Test the built image:
Still inside the
fuse-builder-pod, you can run a container from the image you just built to test it by running the following command:$ podman run --rm my-fuse-built-image:latestThis should output the content of the
/app/build_info.txtfile and the copied Dockerfile.Exit the pod and clean up:
After you are done, exit the shell session in the pod by running the following command:
$ exitDelete the pod if it is no longer needed by running the following command:
$ oc delete pod fuse-builder-podRemove the local YAML file by running the following command:
$ rm fuse-builder-pod.yaml