我从我的码头图片中启动容器,如下所示:
$ 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。
提前致谢。
答案 0 :(得分:1)
当容器内的/ 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的原因是因为他们正在将文件从主机作为主机卷装载到容器中,并且希望权限在两者之间是无缝的。在这种情况下,我的解决方案是以根用户身份启动容器,并使用调用脚本的入口点,例如:
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中的Fix-Perms脚本。将容器内部用户的uid与安装在容器中(作为卷)的文件或目录的uid进行比较。如果这些ID不匹配,则将容器内的用户修改为具有与该卷相同的uid,并使用旧uid更新容器内的任何文件。我的入口点的最后一步是调用以下内容:
exec gosu app_user "$@"
有点像su命令,以app_user的身份运行“ CMD”值,但是带有一些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可以烘焙到映像中,或者您不将主机卷挂载到生产环境中。
答案 1 :(得分:0)
1)确保用户999
在当前目录上具有正确的特权,您需要在docker文件中尝试类似的操作
来自
RUN mkdir /home/999-user-dir && \
chown -R 999:998 /home/999-user-dir
WORKDIR /home/999-user-dir
USER 999
尝试在不使用用户参数的情况下使用此图片旋转容器,看看是否可行。
2)其他原因可能是以下文件的权限问题,请确保您的群组998
对这些文件具有读取权限
-rw-r--r-- 1 root root 690 Jan 2 06:27 /etc/passwd
-rw-r--r-- 1 root root 372 Jan 2 06:27 /etc/group
谢谢
答案 2 :(得分:0)
因此,在您的主机上,您可能会看到您的用户和组:
$ cat /etc/passwd
sdp:x:999:998::...
但是在容器中,您不会在/etc/passwd
中看到它们。
这是预期的行为,只要您不将/etc/passwd
文件装入容器内部(并且从安全性的角度考虑,不要这样做),主机和容器就会完全分开。 />
现在,如果您在Dockerfile中指定了默认用户,则--user
运算符将覆盖USER
指令,因此您在容器内没有用户名称,但是请请注意,指定uid:gid
选项意味着容器在主机中具有与用户相同的uid
值的用户权限。
现在请求您不要在Dockerfile中指定用户-这应该不成问题。只要uid
与主机上的现有用户uid
匹配,就可以像在运行时一样进行设置。
如果必须以特权模式运行某些容器-请考虑使用user namespace。