这是关于使用与 docker 主机交互的 docker 容器的一个相当技术性的问题,通常与使用容器内的主机文件系统有关。
这种情况尤其发生在可重复的研究背景下。
我开发了一个开源实用程序来帮助解决这个问题。
docker 容器的初始和主要用例:一个自包含应用程序,仅通过某些网络端口与主机系统交互。
考虑一个 Web 应用程序:docker 容器通常包含一个 Web 服务器和一个 Web 应用程序,例如在端口 80(容器内部)上运行。然后,通过将容器内部端口 80 绑定到主机端口(例如 8000),容器在主机上运行。
那么容器化应用程序和主机系统之间的唯一交互就是通过这个绑定的网络端口。
容器作为执行环境是完全不同的:
但是,为了使用这些执行环境,这些容器必须有权访问主机系统,特别是主机用户文件系统。
假设您已经容器化了一个 IDE,例如工作室。
您的 Rstudio 安装并在 docker 容器内运行,但它需要读取和编辑项目文件夹中的文件。
为此,您使用 docker run --volume 选项绑定挂载您的项目文件夹(在主机文件系统中)。
然后可以从 docker 容器访问您的文件。
现在的挑战是文件权限。假设您的主机用户具有用户 ID 1001,并假设在容器中拥有 Rsudio 进程的用户是 0(root)或 1002。
如果容器用户是root,那么读取你的文件不会有问题。
但是,一旦您编辑一些现有文件,生成新文件(例如 pdf、html),这些文件将属于主机文件系统上的根目录 !.
这意味着您的本地主机用户将无法使用它们或删除它们,因为它们属于 root。
现在,如果容器用户 ID 是 1002,Rstudio 可能无法读取您的文件、编辑它们或生成新文件。
即使可以,通过设置一些非常宽松的权限,您的本地主机用户也可能无法使用它们。
当然,解决该问题的一种强力方法是在主机上和 docker 容器中都以 root 身份运行。这并不总是可行,并且会引发一些明显的关键安全问题。
因为我们无法提前知道主机的userid是什么(这里1001),所以我们无法预先配置
docker容器用户的userid。
docker run 现在提供了一个 --user 选项,可以使用一些提供的 userid 创建一个 pseudo 用户
在运行时。例如, docker run --user 1001 ... 将创建一个运行进程的 docker 容器
属于用户 ID 为 1001.
那么我们还在讨论这个问题什么呢?还没解决吗?
这里有一些关于动态创建的用户的怪癖:
我们可以解决这些问题,但这可能会很乏味且令人沮丧。
我们真正想要的是预先配置一个 docker 容器用户,并且能够在 runtime... 动态更改他的 userid
docker_userid_fixer 是一个开源实用程序,旨在用作 docker 入口点 来修复我刚刚提出的用户 ID 问题。
让我们看看如何使用它:将其设置为 docker ENTRYPOINT,指定应使用哪个用户并动态修改他的 userid:
ENTRYPOINT ["/usr/local/bin/docker_userid_fixer","user1"]
让我们准确地说:
然后,在容器运行时创建时,有两个选项:
所以在实践中这解决了我们的问题:
您可以在此处找到有关设置的说明。
但归结为:
构建或下载小型可执行文件 (17k)
将其复制到您的 docker 镜像中
使其作为 setuid root 可执行
将其配置为您的入口点
我写了一些简短的注释 https://github.com/kforner/docker_userid_fixer#how-it-works
但我会尝试改写。
实现的关键是容器中docker_userid_fixer可执行文件的setuid root。
我们需要 root 权限来更改 userid,并且此 setuid 仅为
启用特权执行
docker_userid_fixerprogram,并且持续很短的时间。
一旦需要修改userid,docker_userid_fixer就会切换主进程
到请求的用户(和用户 ID!)。
如果您对这些主题(docker、可重复研究、R 包开发、算法、性能优化、并行性...)感兴趣,请随时与我联系,讨论工作和商业机会。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3