考虑以下琐碎的DOCKFILE:

FROM debian:testing
RUN  adduser --disabled-password --gecos '' docker
RUN  adduser --disabled-password --gecos '' bob 

在工作目录中,没有其他内容.打造docker形象:

docker build -t test .

然后在容器上运行bash脚本,将工作目录链接到bob主目录上的新子目录:

docker run --rm -it -v $(pwd):/home/bob/subdir test 

谁拥有容器里subdir个东西?在容器上,运行:

cd /home/bob/subdir
ls -l

广告我们看到:

-rw-rw-r-- 1 docker docker 120 Oct 22 03:47 Dockerfile

天哪,烟!docker拥有这些内容!回到容器外的主机上,我们看到原来的用户仍然拥有Dockerfile.让我们try 修复bob主目录的所有权.在容器上,运行:

chown -R bob:bob /home/bob
ls -l 

我们看到:

-rw-rw-r-- 1 bob bob 120 Oct 22 03:47 Dockerfile

但是等等!在容器外,我们现在运行ls -l

-rw-rw-r-- 1 1001 1001 120 Oct 21 20:47 Dockerfile

我们不再拥有自己的文件.坏消息!


如果我们在上面的例子中只添加了一个用户,那么一切都会更加顺利.出于某种原因,Docker似乎正在创建它遇到的first个非根用户所拥有的任何主目录(即使该用户在早期图像中声明).同样,这first个用户与我家用户的所有权权限相同.

Question 1对吗?有人能给我指一下这方面的文件吗?我只是根据上面的实验进行推测.

Question 2:也许这只是因为它们在内核上都有相同的数值,如果我在一个我的家庭用户不是id 1000的系统上测试,那么权限在任何情况下都会改变?

Question 3:当然,真正的问题是,‘我该怎么办?’如果bob在给定的主机上以bob的身份登录,他应该能够以bob的身份运行容器,并且不会在他的主机帐户下更改文件权限.目前,他实际上需要以用户docker的身份运行容器,以避免其帐户被更改.

我听到你在问Why do I have such a weird Dockerfile anyway?.有时我也很好奇.我正在为一个webapp(RStudio服务器)编写一个容器,它允许不同的用户登录,只需使用来自linux机器的用户名和凭据作为有效用户名.这给我带来了想要创建多个用户的可能不同寻常的动机.我可以通过只在运行时创建用户来解决这个问题,一切都很好.然而,我使用了一个基本映像,它添加了一个docker用户,这样就可以在不以root用户身份运行的情况下交互使用它(根据最佳实践).这会 destruct 一切,因为该用户成为first用户并最终拥有一切,因此在其他用户失败时try 登录(应用程序无法启动,因为它缺乏写入权限).让启动脚本运行chown首先解决了这个问题,但代价是链接卷更改权限(显然只有在链接卷时才有问题).

推荐答案

对吗?有人能给我指一下这方面的文件吗?我只是根据上面的实验进行推测.

也许这只是因为它们在内核上都有相同的数值,如果我在一个我的家庭用户没有id 1000的系统上进行测试,那么在任何情况下权限都会改变?

阅读info coreutils 'chown invocation',这可能会让你更好地了解文件权限/所有权是如何工作的.

不过,基本上,机器上的每个文件都有一组附加的位,用于定义其权限和所有权.当你创建一个文件时,你只需要设置这些位.

当您使用用户名或组名将文件发送给特定用户/组时,chown将在/etc/passwd中查找用户名,在/etc/group中查找组以try 将名称映射到ID.如果这些文件中不存在用户名/组名,chown将失败.

root@dc3070f25a13:/test# touch test
root@dc3070f25a13:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 root root    0 Oct 22 18:15 test
root@dc3070f25a13:/test# chown test:test test
chown: invalid user: 'test:test'

但是,无论您的计算机上是否存在具有这些ID的用户/组,您都可以使用ID将文件发送到任何您想要的位置(当然,在某些正整数上限内).

root@dc3070f25a13:/test# chown 5000:5000 test
root@dc3070f25a13:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 5000 5000    0 Oct 22 18:15 test

UID和GID位是在文件本身上设置的,因此当您在docker容器中装载这些文件时,文件的所有者/组UID与主机上的相同,但现在已映射到容器中的/etc/passwd,除非它属于root用户(UID 0),否则它可能是另一个用户.

当然,真正的问题是,‘我该怎么办?’如果bob在给定的主机上以bob的身份登录,他应该能够以bob的身份运行容器,并且不会在他的主机帐户下更改文件权限.目前,他实际上需要以用户docker的身份运行容器,以避免其帐户被更改.

看起来,根据您当前的设置,您需要确保您的UID>;主机上/etc/passwd个用户名与UID匹配>;如果您希望与登录到主机的同一用户的挂载用户目录进行交互,则容器中的用户名为/etc/passwd.

您可以创建一个特定用户id为useradd -u xxxx的用户.Buuuut,这看起来确实是一个混乱的解决方案...

你可能必须想出一个解决方案,不挂载主机用户主目录.

Linux相关问答推荐

在Bluez/Linux中,周期性与连续蓝牙设备发现的已知缺陷是什么?

在正在运行的进程的输出周围添加自定义字符串

x64 NASM 汇编程序在程序开始时显示分段错误

使用 ansible 验证 firewalld 配置

我需要制作一个 awk 脚本来解析文件中的文本.我不确定我是否做得正确

有没有办法定义自定义隐式 GNU Make 规则?

bash 更有效的方法来转换奇数日期格式以被 linux 日期识别

使用 bash 中的数字对 RPM 内核字符串进行版本排序返回不正确的结果

仅显示 tcsh 或 bash 中作为符号链接的文件和文件夹

如何/在哪里可以找到要修复的 Linux 内核错误?

在 Python 上模拟鼠标点击

如何将文件从 Vagrant 机器复制到 localhost

将 bash 脚本添加到路径

如何通过 ssh 判断 ubuntu 服务器上是否存在 php 和 apache

为什么 JVM 报告的已提交内存比 linux 进程驻留集大小更多?

Supervisord - 将进程标准输出重定向到控制台

Linux上C中的标准输出线程安全?

Anaconda:禁用提示更改

bash中变量名后的2个逗号是什么意思?

是否有git sed或类似功能?