我有一个容器,它创建了一个默认用户,其UID为1000。
在我的Dockerfile中,我正在创建用户:
RUN groupadd sudo && useradd -G sudo -u 1000 -U ${RUST_USER}
现在,当我运行容器时,除非我的当前用户具有完全UID 1000,否则批量权限将被搞砸:
docker run -it --rm naftulikay/circleci-lambda-rust:latest \
-v $PWD:/home/circleci/project \
.local/bin/build
在运行时:
error: failed to write /home/circleci/project/Cargo.lock
Caused by:
failed to open: /home/circleci/project/Cargo.lock
Caused by:
Permission denied (os error 13)
Exited with code 101
这是因为容器中的用户具有UID 1000,容器外的用户具有UID 1001.
我想,由于这已经是内核命名空间的所有虚拟映射,因此可以将内部UID映射到容器中的外部UID。
是否有命令行选项允许我根据需要动态重新映射UID?
答案 0 :(得分:1)
已请求在容器和主机之间动态映射UID,但我认为它需要实现内核和文件系统更改。在那之前,您有几个选择:
使主机与容器匹配。使用主机卷,这并不容易。但是对于命名卷,docker会将卷初始化为映像的内容,包括目录和文件权限,使其相当无缝。您需要调整工作流程,以便不再直接访问卷中的数据,而是使用容器来访问数据。
将容器作为主机uid运行。您可以将/ etc / passwd作为主机卷挂载到容器中,并且可以像任何uid一样启动容器(在撰写文件中使用docker run -u
或user
条目)。唯一的缺点是图像中的文件可能已经由用于构建图像的uid拥有,因此它们需要是世界可读的(可能是可写的)或移动到卷。
我已经知道以root身份启动我的容器,其入口点可根据卷装入的文件权限更正uid / gid不匹配。然后,我的入口点的最后一步是删除新uid的权限并执行容器应用程序。有关执行此操作的入口点的示例,请参阅我的jenkins in docker示例,其中jenkins gid与从主机挂载的docker套接字匹配。
答案 1 :(得分:0)
像BMitch所说,根据系统的不同,您有很多选择,但是请记住,您可能必须重新启动运行的进程(例如php-fpm)
一些有关如何实现此目的的示例:(您可以使用docker container exec ...在容器外部运行命令)
usermod -g 1007 www-data
它将用户www-data的uid更新为1007
deluser www-data
adduser -u 1007 -D -S -G www-data www-data
它将删除用户www-data并使用uid 1007重新创建
要重新启动正在运行的进程,例如php-fpm,您可以这样做:
首先使用以下命令之一获取pid:
pidof php-fpm
ps -ef | grep -v grep | grep php-fpm | awk '{print $2}'
find /proc -mindepth 2 -maxdepth 2 -name exe -lname '*/php-fpm' -printf %h\\n 2>/dev/null | sed s+^/proc/++
然后使用之前获得的pid重新启动进程(如果进程支持USR2信号):
kill -USR2 pid
<-用之前的数字替换pid
我发现最简单的方法是在知道正确的pid的情况下更新主机或构建容器(如果您在不同的环境中工作,则并非总是可行的)