如何让Docker容器中的非root用户访问主机上安装的卷

Ant*_*ony 15 security docker

我作为非root用户在Docker容器中运行我的应用程序.我这样做是因为它是最好的做法之一.但是,在运行容器时,我将主机卷安装到它-v /some/folder:/some/folder.我这样做是因为我在docker容器内运行的应用程序需要将文件写入已安装的主机文件夹.但由于我以非root用户身份运行我的应用程序,因此它无权写入该文件夹

是否可以在docker容器中为非root用户提供对托管卷的访问权限?

如果没有,我唯一的选择是以root身份在docker容器中运行该进程吗?

lar*_*sks 16

这里没有神奇的解决方案:docker中的权限与没有docker的权限相同.你需要运行适当的chown,并chmod命令来更改目录的权限.

一种解决方案是让您的容器以root身份运行,并使用ENTRYPOINT脚本来进行适当的权限更改,然后将您CMD作为非特权用户.例如,将以下内容放入entrypoint.sh:

#!/bin/sh

chown -R appuser:appgroup /path/to/volume
exec runuser -u appuser "$@"
Run Code Online (Sandbox Code Playgroud)

这假设您有runuser可用的命令.你可以使用sudo相反的方式来完成相同的事情.

通过ENTRYPOINT在Dockerfile中包含一个指令来使用上面的脚本:

FROM baseimage

COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/bin/sh", "entrypoint.sh"]
CMD ["/usr/bin/myapp"]
Run Code Online (Sandbox Code Playgroud)

这将启动容器:

/bin/sh entrypoint.sh /usr/bin/myapp
Run Code Online (Sandbox Code Playgroud)

入口点脚本将更改所需的权限,然后运行/usr/bin/myappappuser.

  • 容器内无法检查可用的卷路径,但您可以传入一个环境变量(`docker run -v /some/path:/some/path -e MYVOLUME=/some/path ...`),并且然后在你的 `ENTRYPOINT` 脚本中使用 `$MYVOLUME`。 (2认同)
  • @larsks“让你的容器以 root 身份运行”违背了非 root 容器的目的。 (2认同)
  • @13013SwagR 我不同意。我认为以“root”身份启动容器,然后在“ENTRYPOINT”脚本中切换到非“root”用户可以让您获得*完全相同的安全级别。无论哪种情况,您的服务都不会以“root”用户身份运行。 (2认同)
  • @larsks - 我必须(礼貌地)不同意你的不同意见。我不是这里的专家,但很快谷歌就出现了(https://pythonspeed.com/articles/root-capability-docker-security/了解详细信息),这解释了为什么以 root 身份启动然后在容器内降级_不_提供与通过 Dockerfile 中的“USER”关键字指定非 root 用户所获得的相同级别的安全性。 (2认同)

小智 15

在使用从自定义 Dockerfile 构建的映像的特定情况下,您可以执行以下操作(使用 debian 映像的示例命令):

    FROM baseimage
    ...
    RUN useradd --create-home appuser
    USER appuser
    RUN mkdir /home/appuser/my_volume
    ...
Run Code Online (Sandbox Code Playgroud)

然后使用挂载卷

-v /some/folder:/home/appuser/my_volume
Run Code Online (Sandbox Code Playgroud)

现在appuser具有对该卷的写入权限,因为它位于其主目录中。如果卷必须安装在其主目录之外,您可以创建它并分配appuser写入权限,作为 Dockerfile 中的额外步骤。


Jam*_*ang 7

如果主机env没有appuserappgroup,则会抛出错误,因此最好使用用户ID代替用户名:

在您的容器中,运行

appuser$ id
Run Code Online (Sandbox Code Playgroud)

这将显示:

uid = 1000(appuser)gid = 1000(appuser)组= 1000(appuser)

在主机环境中,运行:

mkdir -p /some/folder
chown -R 1000:1000 /some/folder
docker run -v /some/folder:/some/folder [your_container]
Run Code Online (Sandbox Code Playgroud)

在您的容器内,检查

ls -lh
Run Code Online (Sandbox Code Playgroud)

查看用户名和组名,如果不是root,则应该可以使用。

  • @bananabrann `appuser` 不是一个工具,而是一些用户名,例如 `admin` 等,由容器的 `USER admin` 指令决定。 (2认同)