Security Contexts and Container Permissions
When building and deploying containers, a common misconception is that the environment inside a container is completely divorced from the host operating system. While the filesystem is isolated, the User IDs (UID) and Group IDs (GID) are not.
This nuance becomes critical when attaching persistent storage (like an NFS share) to your Kubernetes pods.
The Root Problem
By default, unless specified otherwise in the Dockerfile, a container process runs as the root user (UID 0).
If a pod running as root writes a file to an attached NFS Persistent Volume, that file will be created on the physical storage array with root:root ownership. This causes a massive problem in a shared media stack:
- Audiobookshelf (Running as Root) downloads a book and saves it to
/data/media/books. The folder is owned byroot. - LazyLibrarian (Running as UID 1000) attempts to scan or rename that folder.
- The operating system blocks LazyLibrarian with a
Permission Deniederror because UID 1000 is not allowed to modify files owned by UID 0.
The LinuxServer.io Approach (PUID/PGID)
To solve this, many community images (specifically those published by linuxserver.io) use a clever workaround.
The container still starts as root, but the entrypoint script reads environment variables named PUID and PGID. Before launching the actual application (e.g., Radarr, Sonarr), the script uses a tool like s6-overlay to dynamically drop privileges down to the specified UID and GID.
The Kubernetes Native Approach (securityContext)
The PUID/PGID approach is an image-specific hack. If an image (like advplyr/audiobookshelf) doesn't support those specific environment variables, it will ignore them and run as root.
The proper, Kubernetes-native way to handle this is using a Security Context.
Instead of relying on the container's entrypoint script to drop privileges, you instruct the Kubernetes kubelet to launch the entire container process as a specific, non-root user from the very beginning.
runAsUser: Forces the primary process to run as UID 1000.runAsGroup: Forces the primary process to run as GID 1000.fsGroup: A special supplemental group that applies to all containers in a Pod. Kubernetes will automatically ensure that the volume permissions match this group, granting the pod write access.
[!WARNING] While
securityContextis safer and more standard, it can break containers that were strictly designed to start as root (e.g., containers that need to bind to privileged ports below 1024, or containers that hardcodechowncommands in their startup scripts). Always check the container's documentation!
TrueNAS SMB vs Kubernetes Container Permissions
When integrating an enterprise storage array (like TrueNAS) with Kubernetes, you often encounter complex multi-protocol permission conflicts.
A common scenario is wanting to copy media files from your Mac to the NAS via SMB (Server Message Block), so that a Kubernetes pod (like Jellyfin) can read them via NFS (Network File System).
The Conflict
- You create an SMB user (
truenas_smb_user) in TrueNAS and connect your Mac to the share. - You try to paste a movie into the
movies/directory on the share, but macOS says Permission Denied. - Why? Because the
movies/directory was originally created by the Jellyfin Kubernetes Pod over NFS. - The Jellyfin pod runs as the
abcuser (UID 1000). When it created themovies/directory, it applied standard Linux permissions (e.g.,755- Owner can read/write, everyone else can only read). - Your SMB user is a completely different entity on the TrueNAS server. It does not map to UID 1000. Therefore, it falls under the "everyone else" category and is denied write access by the Linux permissions set by the container.
The Escape Hatch
If you are just doing a one-off copy and do not want to wrestle with complex TrueNAS ACLs or ID mapping, you can use Kubernetes itself to unlock the folder dynamically.
Since the container created the folder and owns it, the container has the authority to change its permissions. You can use kubectl exec to break into the pod and forcefully change the directory permissions to 777 (Read/Write for everyone):
Now, your external SMB user will be able to write files directly into that folder!