为OpenShift构建Podman镜像时/etc/passwd权限随运行用户变化的异常问题
Great question! This behavior stems from the user injection mechanism built into Podman (and its underlying OCI runtime, like crun) when you run a container with a UID that doesn't exist in the container's /etc/passwd—which is exactly how OpenShift operates with random UIDs. Let’s break down the issue and solutions:
What’s Happening?
When you start a container with a UID that isn’t listed in /etc/passwd (like 1000701200 in your test), the runtime automatically modifies /etc/passwd to add a matching user entry (e.g., 1000701200:x:1000701200:0::/:/bin/bash). This explains:
- The increased file size (from 926 to 977 bytes): the new user line adds extra characters.
- The reset permissions (
rw-r--r--instead ofrw-rw-r--): when the runtime writes the modified/etc/passwd, it uses the default file permissions (governed by the runtime’s umask), overwriting theg+wpermission you set during build.
Custom files don’t trigger this mechanism, which is why their permissions stay intact.
Solutions for OpenShift
Since OpenShift relies on random UIDs, here are practical fixes to maintain the necessary permissions and avoid runtime modification of /etc/passwd:
1. Pre-Create a Range of User Entries
Add a batch of placeholder users to /etc/passwd during the build phase, covering the range of UIDs OpenShift might assign (typically starting at 100000). This way, the runtime won’t need to modify the file:
FROM ubuntu:20.04 USER root # Add 100 placeholder users (adjust range as needed for your OpenShift cluster) RUN for uid in $(seq 100000 100099); do \ echo "openshift-user$uid:x:$uid:0::/:/bin/bash" >> /etc/passwd; \ done # Set group-writable permission once RUN chmod g+w /etc/passwd
When OpenShift assigns a UID within this range, it will match an existing entry, and /etc/passwd will remain unmodified with your desired permissions.
2. Use nss_wrapper for Virtual User Management
nss_wrapper lets you provide a virtual /etc/passwd without modifying the actual file in the container. This is a clean approach for dynamic UIDs:
FROM ubuntu:20.04 USER root # Install nss_wrapper RUN apt-get update && apt-get install -y --no-install-recommends libnss-wrapper && \ apt-get clean && rm -rf /var/lib/apt/lists/* # Configure nss_wrapper paths ENV NSS_WRAPPER_PASSWD=/tmp/passwd ENV NSS_WRAPPER_GROUP=/tmp/group # Copy system passwd/group to temporary files RUN cp /etc/passwd $NSS_WRAPPER_PASSWD && \ cp /etc/group $NSS_WRAPPER_GROUP # Add a default placeholder (the runtime will override this dynamically) RUN echo "default:x:0:0::/:/bin/bash" >> $NSS_WRAPPER_PASSWD # Create an entrypoint to load nss_wrapper RUN echo '#!/bin/bash' > /entrypoint.sh && \ echo 'LD_PRELOAD=libnss_wrapper.so "$@"' >> /entrypoint.sh && \ chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]
With this setup, nss_wrapper intercepts user lookup calls and uses the temporary /tmp/passwd file (which the runtime updates with the random UID) instead of modifying the real /etc/passwd. The original /etc/passwd permissions stay as you set them.
3. Adjust Runtime Behavior (Cluster-Level)
If you have cluster admin access, you can disable the user injection feature in the OCI runtime (e.g., crun), but this is not recommended—it breaks standard user environment setup for non-root containers. Stick to the first two solutions for application-level fixes.
内容的提问来源于stack exchange,提问作者MeanStreet

