我使用官方的 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 添加到映像中?
我能够为这个问题制定一个“解决方案”。这有点粗糙,但据我目前所知,它无需将用户安装到映像中即可完成工作。
本质上,我libnss-wrapper与自定义run_as_user脚本结合使用,而我又使用该脚本为那些因未知 UID(例如ssh)而给我带来麻烦的命令添加别名。
DockerfileFROM 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它是我道路上的第一个。
到目前为止,这对我来说一直有效。如果这方面存在(严重)问题,我很乐意让他们向我指出。
这是我通过 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 容器中的工作原理” :
OP 补充道:
我理解原因,因为这正是我试图避免的:将用户添加到图像中。
如果我的问题没有解决,我会尝试直接修改容器。
实际上,还有另一种选择,它允许您不修改映像也不添加用户:userns 或用户重新映射(自 docker 1.10 起)。但是,正如我在这里提到的,您需要 docker 17.06 来避免一些错误。
| 归档时间: |
|
| 查看次数: |
9459 次 |
| 最近记录: |