docker:启动容器时设置运行用户

xrf*_*ang 8 docker

我使用官方的 golang docker 映像来编译我的 go 程序,并将生成的可执行文件放在映射到我的主机目录的卷上。

问题是 docker 生成的文件属于 root:root,这非常烦人,因为我不想通过 sudo 运行我的脚本。

我搜索了使 docker 容器以非 root 身份运行的解决方案,但我发现的方法需要更改 Dockerfile 并将用户添加到映像中,例如

http://gbraad.nl/blog/non-root-user-inside-a-docker-container.html

有没有办法让docker容器以主机上的当前用户身份运行,即用户A运行此镜像将生成属于A:A的文件,用户B生成属于B:B的文件,而A和B都是用户在主机上定义(即卷所在的位置),而不需要通过 Dockerfile 将 A 和 B 添加到映像中?

der*_*ink 7

我能够为这个问题制定一个“解决方案”。这有点粗糙,但据我目前所知,它无需将用户安装到映像中即可完成工作。
本质上,我libnss-wrapper与自定义run_as_user脚本结合使用,而我又使用该脚本为那些因未知 UID(例如ssh)而给我带来麻烦的命令添加别名。

Dockerfile

FROM whatever
RUN apt-get update && apt-get install -y libnss-wrapper
COPY run_as_user /usr/local/bin/
RUN chmod a+x /usr/local/bin/run_as_user

# copy some command aliases that need to be early on the path
COPY ssh /usr/local/sbin
RUN chmod a+x /usr/local/sbin/ssh
Run Code Online (Sandbox Code Playgroud)

run_as_user脚本

该脚本根据当前用户的 UID 和 GID创建一个passwdand文件,然后使用它来参数化grouplibnss-wrapper

FROM whatever
RUN apt-get update && apt-get install -y libnss-wrapper
COPY run_as_user /usr/local/bin/
RUN chmod a+x /usr/local/bin/run_as_user

# copy some command aliases that need to be early on the path
COPY ssh /usr/local/sbin
RUN chmod a+x /usr/local/sbin/ssh
Run Code Online (Sandbox Code Playgroud)

ssh别名脚本

#!/bin/sh
# run a command as (non-existent) user, using libnss-wrapper

U=`id -u`
G=`id -g`

HOME_DIR=/tmp/user
PASSWD=/var/tmp/passwd
GROUP=/var/tmp/group

if [ ! -d "$HOME_DIR" ]; then
  mkdir "$HOME_DIR"
fi
if [ ! -f "$PASSWD" ]; then
  echo "user::$U:$G::$HOME_DIR:" > "$PASSWD"
fi
if [ ! -f "$GROUP" ]; then
  echo "user::$G:" > "$GROUP"
fi

LD_PRELOAD=libnss_wrapper.so NSS_WRAPPER_PASSWD="$PASSWD" NSS_WRAPPER_GROUP="$GROUP" "$@"
Run Code Online (Sandbox Code Playgroud)

同样,这很有效,因为/usr/local/sbin它是我道路上的第一个。

到目前为止,这对我来说一直有效。如果这方面存在(严重)问题,我很乐意让他们向我指出。


Von*_*onC 4

这是我通过 alphine-golang 加上 git 工具制作的),在我的笔记本电脑上使用 -u arg 运行,但是如果我在 debian 虚拟机上运行它,它会告诉我 No user存在于 uid 1001

理想情况下,您可以使用正确的预期 ID 制作自己的图像(基于现有图像):

RUN useradd -r -u 1001 -g appuser appuser
USER appuser
Run Code Online (Sandbox Code Playgroud)

请参阅Marc Campbell的“了解 uid 和 gid 在 Docker 容器中的工作原理” :

Docker 的 UID/GID


OP 补充道:

我理解原因,因为这正是我试图避免的:将用户添加到图像中。
如果我的问题没有解决,我会尝试直接修改容器。

实际上,还有另一种选择,它允许您修改映像也不添加用户:userns 或用户重新映射自 docker 1.10 起)。但是,正如我在这里提到的,您需要 docker 17.06 来避免一些错误。