无论我做什么,Podman 都会以 root 身份安装卷

问题描述 投票:0回答:2

我已将 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 身份挂载。我一生都无法弄清楚它还能在哪里获得这些权限。

containers podman
2个回答
3
投票

本教程很好地解释了这个问题。您有两个选择:

  • 使用
    podman unshare
    可以让您在与容器相同的命名空间中运行命令。
  • 在容器内以 root 身份运行(容器本身仍然是无 root 的)

podman unshare
不太好。它的工作方式是确定容器使用的 UID,然后使用
unshare
设置主机文件系统上目录的所有权以使用该命名空间。问题是这需要您更改主机系统上的所有者,这很少是可取的并且会导致权限问题。

第二种方法要好得多,尽管不是从安全角度来看 - 在容器内以 root 身份运行,然后使用

:Z
:z
挂载容器。我会让 ChatGPT 解释两者之间的区别(它做得很好):

  • “z”(小写z):当文件或目录具有“z”上下文标志时,意味着该对象被标记为私有非共享标签。这通常用于由容器内运行的进程创建的文件或目录。具有“z”上下文的对象被限制在容器内,其他容器或主机系统无法访问。
  • “Z”(大写 Z):另一方面,“Z”上下文标志用于共享对象。标有“Z”标志的文件或目录可供其他容器和主机系统访问。该标志允许多个容器共享资源并访问相同的文件或目录。

例如:

podman run -it --rm --name nexus2 \
    -v /home/tom/myshares/nexus2:/sonatype-work:Z \
    -u root \
    sonatype/nexus /bin/sh

希望这对其他人有帮助!


0
投票

Podman 默认情况下将主机用户 ID 映射到容器 root 用户 ID,这意味着主机用户拥有的任何挂载卷都将归容器内的 root 所有。您可以通过提供 --userns 选项来更改此设置,如下所述: https://docs.podman.io/en/v4.6.1/markdown/options/userns.container.html#userns-mode

© www.soinside.com 2019 - 2024. All rights reserved.