我已将 Podman 配置为用户,如我在这篇文章
中所述在我的 dockerfile 中,我将竭尽全力绝对确保该目录由相关用户拥有,并且甚至对这些值进行硬编码,以绝对确保它不是环境变量的问题,同时进一步删除带有节点的任何组或用户,然后使用该特定 ID 重新创建它们,只是为了更加确定:
ARG USER_ID 1000
ARG GROUP_ID 1000
ARG GROUPNAME node
ARG USERNAME node
# getent group ${GROUP_ID} - Get the name of the group. Ex: `somegroup:x:999:`. This makes sure the group exists
# echo groupdel by-id ${GROUP_ID} - This is just there to tell the user what we're doing
# groupdel $(getent group ${GROUP_ID} | cut -d: -f1) - Gets the group string as above (`somegroup:x:999:`)
# and then passes it into `cut -d: -f1` which will grab the `somegroup` part and pass that into groupdel
# ||: The || is the or operator and : is the null operator. This just has the effect of ensuring the line
# returns with "success" rather than failure in the event the group doesn't exist
RUN (getent group ${GROUP_ID} && (echo groupdel by-id ${GROUP_ID}; groupdel $(getent group ${GROUP_ID} | cut -d: -f1))) ||:
RUN (getent group ${GROUPNAME} && (echo groupdel ${GROUPNAME}; groupdel ${GROUPNAME})) ||:
RUN (getent passwd ${USERNAME} && (echo userdel ${USERNAME}; userdel -f ${USERNAME})) ||:
RUN groupadd -g ${GROUP_ID} ${GROUPNAME}
RUN useradd -l -u ${USER_ID} -g ${GROUPNAME} ${USERNAME}
WORKDIR /home/node/app
RUN mkdir /patches
RUN chown node:node /patches
这仍然不起作用,所以在 docker-compose 中的构建中,我进一步明确指定了权限:
build:
dockerfile: podman-build/Dockerfile.patches_backend
args:
USER_ID: ${USER_ID:-1000}
GROUP_ID: ${GROUP_ID:-1000}
USERNAME: node
GROUPNAME: node
我不知道我还缺少什么,容器中的UID/GID是正确的,容器外的文件夹的权限是预期的UID/GID=1000:
但是这个卷挂载:
volumes:
- type: bind
source: repos/xml
target: /patches/xml
仍然顽固地以 UID/GID=0 的 root 身份挂载。我一生都无法弄清楚它还能在哪里获得这些权限。
本教程很好地解释了这个问题。您有两个选择:
podman unshare
可以让您在与容器相同的命名空间中运行命令。podman unshare
不太好。它的工作方式是确定容器使用的 UID,然后使用 unshare
设置主机文件系统上目录的所有权以使用该命名空间。问题是这需要您更改主机系统上的所有者,这很少是可取的并且会导致权限问题。
第二种方法要好得多,尽管不是从安全角度来看 - 在容器内以 root 身份运行,然后使用
:Z
或 :z
挂载容器。我会让 ChatGPT 解释两者之间的区别(它做得很好):
例如:
podman run -it --rm --name nexus2 \
-v /home/tom/myshares/nexus2:/sonatype-work:Z \
-u root \
sonatype/nexus /bin/sh
希望这对其他人有帮助!
Podman 默认情况下将主机用户 ID 映射到容器 root 用户 ID,这意味着主机用户拥有的任何挂载卷都将归容器内的 root 所有。您可以通过提供 --userns 选项来更改此设置,如下所述: https://docs.podman.io/en/v4.6.1/markdown/options/userns.container.html#userns-mode