我如何使用 "docker run --user" 但具有 root 权限

How can I use "docker run --user" but with root priviliges

我有一个包含分析管道的 Docker 图像。对于 运行 这个管道,我需要提供输入数据并且我想保留输出。此管道必须能够由除我以外的其他用户在他们自己的笔记本电脑上 运行。

简单地说,我的根(/)文件夹结构如下:

total 72
drwxr-xr-x   1 root   root 4096 May 29 15:38 bin
drwxr-xr-x   2 root   root 4096 Feb  1 17:09 boot
drwxr-xr-x   5 root   root  360 Jun  1 15:31 dev
drwxr-xr-x   1 root   root 4096 Jun  1 15:31 etc
drwxr-xr-x   2 root   root 4096 Feb  1 17:09 home
drwxr-xr-x   1 root   root 4096 May 29 15:49 lib
drwxr-xr-x   2 root   root 4096 Feb 24 00:00 lib64
drwxr-xr-x   2 root   root 4096 Feb 24 00:00 media
drwxr-xr-x   2 root   root 4096 Feb 24 00:00 mnt
drwxr-xr-x   1 root   root 4096 Mar 12 19:38 opt
drwxr-xr-x   1 root   root 4096 Jun  1 15:24 pipeline
dr-xr-xr-x 615 root   root    0 Jun  1 15:31 proc
drwx------   1 root   root 4096 Mar 12 19:38 root
drwxr-xr-x   3 root   root 4096 Feb 24 00:00 run
drwxr-xr-x   1 root   root 4096 May 29 15:38 sbin
drwxr-xr-x   2 root   root 4096 Feb 24 00:00 srv
dr-xr-xr-x  13 root   root    0 Apr 29 10:14 sys
drwxrwxrwt   1 root   root 4096 Jun  1 15:25 tmp
drwxr-xr-x   1 root   root 4096 Feb 24 00:00 usr
drwxr-xr-x   1 root   root 4096 Feb 24 00:00 var

管道脚本在 /pipeline 中,并在我的 Docker 文件中使用 "COPY. /pipeline" 指令打包到图像中。

出于各种原因,此管道(这是一个遗留管道)的设置使得输入数据必须位于 /pipeline/project 等文件夹中。对于 运行 我的管道,我使用:

docker run --rm --mount type=bind,source=$(pwd),target=/pipeline/project --user "$(id -u):$(id -g)" pipelineimage:v1

换句话说,我将一个包含数据的文件夹挂载到/pipeline/project。我发现我需要使用 --user 来确保输出文件具有正确的权限 - 即在容器退出后我将在我的主机上具有 read/write/exec 访问权限。

管道 运行s 但我有一个问题:管道使用的一种特定软件会自动尝试生成(我无法更改)1 $HOME 中的文件夹(所以 / - 我在上面显示的)和我的 WORKDIR 中的 1 个文件夹(我在 Docker 文件中将其设置为 /pipeline)。这些尝试都失败了,我猜这是因为我没有 运行 将管道设置为 root。但我需要使用 --user 来确保我的输出具有正确的权限 - 即我不需要 sudo 权限来读取这些输出等。

我的问题是:我该如何处理?似乎通过使用--user,我为成功制作了许多输出文件的安装文件夹(/pipeline/projects)设置了正确的权限,没有问题。但是如何确保其他 2 个文件夹在该挂载之外正确创建?

我试过以下但没有成功:

我错过了什么吗?我不明白为什么 "easy" 处理挂载文件夹的权限,但处理容器中其他文件夹的权限却困难得多。谢谢。

如果您的软件不依赖于相对路径(~/./),您只需将 $HOMEWORKDIR 设置为任何用户都可以访问的目录可以写:

ENV HOME=/tmp
WORKDIR /tmp

如果你不能那样做,你可以通过环境将 uid/gid 传递给入口点脚本 运行ning 作为 root,chown/chmod 必要时,然后放弃权限到运行管道(runusersusudosetuidgid)。

例如(未经测试):

entrypoint.sh

#!/bin/bash

[[ -v "RUN_UID" ]] || { echo "unset RUN_UID" >&2; exit 1; }
[[ -v "RUN_GID" ]] || { echo "unset RUN_GID" >&2; exit 1; }

# chown, chmod, set env, etc.
chown $RUN_UID:$RUN_GID "/path/that/requires/write/permissions"
export HOME=/tmp

# Run the pipeline as a non-root user.
sudo -E -u "#$RUN_UID" -g "#$RUN_GID" /path/to/pipeline

Dockerfile

...
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

最后,在 运行ning:

时通过环境传递用户和组 ID

docker run --rm --mount type=bind,source=$(pwd),target=/pipeline/project -e RUN_UID=$(id -u) -e RUN_GID=$(id -g) pipelineimage:v1