gpt4 book ai didi

docker - 如何在docker容器中正确使用系统用户

转载 作者:行者123 更新时间:2023-12-02 17:51:05 28 4
gpt4 key购买 nike

我正在从我的 docker 镜像启动容器,如下所示:

$ docker run -it --rm --user=999:998 my-image:latest bash

其中 uid 和 gid 用于名为 sdp 的系统用户:
$ id sdp uid=999(sdp) gid=998(sdp) groups=998(sdp),999(docker)

但是:容器说“不”...
groups: cannot find name for group ID 998
I have no name!@75490c598f4c:/home/myfolder$ whoami
whoami: cannot find name for user ID 999

我究竟做错了什么?

请注意,我需要在多个系统上运行基于此镜像的容器,并且不能保证用户的 uid:gid 跨系统是相同的,这就是为什么我需要在命令行而不是在 Dockerfile 中指定它的原因。

提前致谢。

最佳答案

当容器内的/etc/passwd 或/etc/group 文件中不存在 uid/gid 时,就会发生这种错误。有多种方法可以解决这个问题。一种是将这些文件从您的主机直接映射到容器中,如下所示:

$ docker run -it --rm --user=999:998 \
-v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro \
my-image:latest bash

我不喜欢该解决方案,因为容器文件系统内的文件现在可能拥有错误的所有权,从而导致潜在的安全漏洞和错误。

通常,人们想要更改容器内的 uid/gid 的原因是因为他们将文件从主机挂载到容器中作为主机卷,并希望权限在两者之间无缝连接。在这种情况下,我的解决方案是以 root 身份启动容器并使用调用脚本的入口点,例如:
if [ -n "$opt_u" ]; then
OLD_UID=$(getent passwd "${opt_u}" | cut -f3 -d:)
NEW_UID=$(stat -c "%u" "$1")
if [ "$OLD_UID" != "$NEW_UID" ]; then
echo "Changing UID of $opt_u from $OLD_UID to $NEW_UID"
usermod -u "$NEW_UID" -o "$opt_u"
if [ -n "$opt_r" ]; then
find / -xdev -user "$OLD_UID" -exec chown -h "$opt_u" {} \;
fi
fi
fi

以上来自我的 base image 中包含的修复权限脚本。 .发生的事情是将容器内用户的 uid 与挂载到容器中的文件或目录的 uid(作为卷)进行比较。当这些 id 不匹配时,容器内的用户被修改为具有与卷相同的 uid,并且容器内具有旧 uid 的所有文件都将被更新。我的入口点的最后一步是调用类似的东西:
exec gosu app_user "$@"

这有点像作为 app_user 运行“CMD”值的 su 命令,但有一些 exec 逻辑用“CMD”进程替换 pid 1 以更好地处理信号。然后我使用如下命令运行它:
$ docker run -it --rm --user=0:0 -v /host/vol:/container/vol \
-e RUN_AS app_user --entrypoint /entrypoint.sh \
my-image:latest bash

查看我链接到的基本镜像存储库,包括使用 nginx 显示这些部分如何组合在一起的示例,并避免需要以 root 身份在生产中运行容器(假设生产已经知道可以烘焙的 uid/gid)到镜像中,或者您没有在生产中安装主机卷)。

关于docker - 如何在docker容器中正确使用系统用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50658883/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com