【问题标题】:Let non-root user write to linux host in Docker让非 root 用户写入 Docker 中的 linux 主机
【发布时间】:2018-01-13 02:14:41
【问题描述】:

我创建了一个 OpenSuse 42.3 docker 容器镜像,它有一个用户,我们称之为“streamuser”。每当有人从我的图像创建容器时,我希望它成为活跃的用户。我已将主机的主目录挂载到 streamuser 的主目录。我遇到的问题是,如果我在 Linux 主机上运行 Docker 容器,streamuser 无法向主机目录写入任何内容。这是因为 streamuser 不与主机共享相同的 UID 和 GID。有没有一种干净的方法来解决这个问题,避免我将图像中的默认用户帐户设置为 root 帐户?如果我在容器中以 root 身份登录,那么我可以写入 linux 主机,但这是不可取的。

我的码头工人电话是:

docker run  -it -d --name ${containerName}  --user="streamuser"         \
    --workdir="/home/streamuser" --volume="${home}:/home/streamuser"    \
    ${imageName}  /bin/bash -rcfile /opt/Codebase/image_env_setup_v206.sh

我看到有人使用 --volume 选项将主机密码、sudoers 等文件传递给容器的解决方案。我不喜欢这个选项,因为它会覆盖我在容器中精心设计的环境,而且它看起来像是一个笨拙的解决方案。

我的 dockerfile 是:

FROM opensuse:42.3

RUN zypper update -y && \
    zypper install -y \
    sudo \
    vim \
    gcc-fortran \
    infinipath-psm-devel \
    openmpi \
    openmpi-devel \
    openmpi-libs \
    hdf5-openmpi \
    blas-devel \
    blas-devel-static \
    lapack-devel \
    which

RUN echo "root:streamuser_2017" | chpasswd
RUN useradd -m streamuser
RUN passwd -d streamuser
CMD /bin/bash

RUN mkdir -p -m0755 \
    /opt/codeA/lib \
    /opt/codeA/bin \
    /opt/codeB/lib \
    /opt/codeC/lib \
    /opt/codeC/bin \
    /opt/petsc/lib

USER streamuser
WORKDIR /home/streamuser

RUN source $HOME/.bashrc

COPY ./Docker/critical_dependencies/codeA_lib/* /opt/codeA/lib/
COPY ./Docker/critical_dependencies/codeA_bin/* /opt/codeA/bin/
COPY ./Docker/critical_dependencies/codeB_lib/* /opt/codeB/lib/
COPY ./Docker/critical_dependencies/petsc_lib/* /opt/petsc/lib/
COPY ./lib/* /opt/codeC/lib/
COPY ./bin/* /opt/codeC/bin/
COPY ./Docker/image_env_setup_v206.sh /opt/codeC

RUN source /opt/codeC/image_env_setup_v206.sh

【问题讨论】:

  • 如何将容器内的streamuser的Gid改成属于容器内的根组?
  • @Ayushya 我曾想过这样做,但我认为将用户添加到根组通常是不受欢迎的。
  • 没错,我提出了这个解决方案,但即使我同意“用户不应该被添加到根组”

标签: linux docker file-permissions opensuse


【解决方案1】:

您可以在 Dockerfile 映像中添加 fixuidCaleb Lloyd)。
moby/moby issue 7198:

我们为此问题创建了一个解决方法,将构建时设置的 Docker 容器的用户/组和文件权限更改为容器在运行时启动时使用的 UID/GID。

项目和安装说明位于:https://github.com/boxboat/fixuid

例子:

  • Docker 容器是使用用户/组 dockeruser:dockergroup 作为 UID/GID 1000:1000 构建的。
  • 主机以 UID/GID 1001:1002 运行。
  • 图像使用docker run -u 1001:1002 运行。

fixuid 将:

  • 将 dockeruser UID 更改为 1001
  • 将 dockergroup GID 更改为 1002
  • 将旧dockeruser:dockergroup 的所有文件权限更改为1001:1002
  • 将容器内的$HOME 更新为dockeruser $HOME
  • 现在容器和主机 UID/GID 匹配,并且在主机装载的容器中创建的文件将匹配。

它可以作为ENTRYPOINT 或作为启动脚本的一部分运行。它作为root 拥有的带有setuid 位的二进制文件安装在容器中,并升级权限以进行适当的更改。它只能在开发容器中使用。

【讨论】:

  • 这看起来是一个很好的解决方案。Github repo 中的说明的第 2 步对我来说失败并出现错误:tar:fixuid:无法打开:权限被拒绝 tar:退出,由于先前的错误状态错误。在步骤 2 的说明中,它说该命令必须以 root 身份运行,但我不确定如何保证该特定命令将在我的 Dockerfile 中以 root 身份运行。
  • @wandadars 可以,如果您在 RUN 之前添加 USER root
  • 如果它可以工作,那就太棒了。不幸的是,在我的情况下,消息fixuid: already ran on this system; will not attempt to change UID/GID 没有任何改变:(
  • @KansaiRobot 是在 docker build 期间吗?您是否使用了使用 fixuid (boxboat.com/2017/07/25/fixuid-change-docker-container-uid-gid) 的基本映像?
猜你喜欢
  • 2019-04-22
  • 2017-01-16
  • 2017-07-03
  • 2020-11-21
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多