了解docker中的用户文件所有权:如何避免更改链接卷的权限
- 2024-10-25 08:42:00
- admin 原创
- 97
问题描述:
考虑以下简单的 Dockerfile:
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
。让我们尝试修复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 似乎将其遇到的第一个非 root 用户拥有的任何主目录(即使该用户在早期映像上声明过)。同样,这个第一个用户与我的家庭用户具有相同的所有权权限。
问题 1正确吗?有人能给我指出这方面的文献吗?我只是根据上述实验进行推测。
问题 2:也许这只是因为它们在内核上具有相同的数值,并且如果我在家庭用户不是 id 的系统上进行测试,1000
那么权限在每种情况下都会发生变化?
问题 3:真正的问题当然是“我该怎么办?”如果以bob
身份登录到bob
给定的主机,他应该能够以 身份运行容器bob
,而不会更改其主机帐户下的文件权限。目前,他实际上需要以用户身份运行容器,docker
以避免更改其帐户。
我听到你在问为什么我的 Dockerfile 这么奇怪?有时我也很想知道。我正在为一个允许不同用户登录的 web 应用程序(RStudio-server)编写容器,它只是使用来自 linux 机器的用户名和凭据作为有效用户名。这给我带来了想要创建多个用户的不寻常的动机。我可以通过只在运行时创建用户来解决这个问题,一切都很好。但是,我使用了一个添加了单个docker
用户的基本映像,这样就可以在不以 root 身份运行的情况下以交互方式使用它(按照最佳实践)。这会毁了一切,因为该用户成为第一个用户并最终拥有所有内容,因此尝试以其他用户身份登录会失败(应用程序无法启动,因为它缺乏写权限)。首先运行启动脚本可以chown
解决这个问题,但代价是链接卷会改变权限(显然只有在我们链接卷时才会出现问题)。
解决方案 1:
我发现了两个选项:
完成工作后,清理所有东西
我已经完成docker run -v
pwd/shared:/shared image
,容器中创建的文件pwd/shared
归 docker 进程所有。但是,/shared
仍然归我所有。因此,在 docker 进程中,我执行
chown -R
stat -c "%u:%g" /shared /shared
stat -c "%u:%g" /shared
`1000:1000在我的情况下,返回的是
uid:gid我的用户的。即使 docker conatainer 中没有用户
1000,id 也在那里(
stat /shared`如果您询问用户名,它只会显示“未知”)。
无论如何,chown
乖乖地将 内容的所有权转让/shared
给1000:1000
(就它而言,它并不存在,但在容器之外,它属于我)。所以我现在拥有所有文件。容器仍然可以根据需要修改内容,因为从它的角度来看,它是root
。
世界一切安好。
docker run -u
因此创建的所有文件都会自动拥有正确的所有者
另一种方法是-u
使用 docker run 上的标志。
docker run -v
pwd/shared:/shared -u
stat -c "%u:%g" /shared ubuntu bash
这样容器里面的docker用户就是了youruid:yourgid
。
但是:这意味着放弃容器内的 root 权限(apt-get install
等等)。除非您使用该新 uid 创建用户并将其添加到root
组中。
解决方案 2:
对吗?有人能给我指出这方面的文献吗?我只是根据上述实验进行推测。
也许这只是因为它们在内核上具有相同的数值,并且如果我在家庭用户 ID 不是 1000 的系统上进行测试,那么权限在每种情况下都会发生变化?
阅读一下info coreutils 'chown invocation'
,这可能会让您更好地了解文件权限/所有权的工作原理。
但基本上,您机器上的每个文件都附加了一组位,用于定义其权限和所有权。当您访问chown
文件时,您只需设置这些位。
当您chown
使用用户名或组名将文件发送给特定用户/组时,chown
将查找/etc/passwd
用户名和/etc/group
组以尝试将名称映射到 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'
但是,你可以chown
使用任何你想要的 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 身份运行容器,以避免更改其帐户。
看起来,使用您当前的设置,如果您想以登录主机的同一用户身份与已挂载的用户目录进行交互,则需要确保/etc/passwd
主机上的 UID > 用户名与容器中的 UID > 用户名匹配/etc/passwd
。
您可以使用 创建具有特定用户 ID 的用户useradd -u xxxx
。但是,这似乎是一个混乱的解决方案……
您可能必须想出一个不挂载主机用户主目录的解决方案。
解决方案 3:
因此,我在这篇文章中最终研究了如何将以 root 身份运行的 docker 容器中产生的所有文件(由 root 拥有)的所有权恢复到主机上的非特权用户。
我需要容器内的进程以 root 身份运行,所以我不能在 docker run 上使用 -u。
我对我所做的事情并不感到自豪,但在我的 bash 脚本末尾,我添加了以下内容:
docker run --rm -it \n --entrypoint /bin/sh \n -e HOST_UID=`id -u` \n -v ${HOST_FOLDER_OWNED_BY_ROOT}:/tmp \n alpine:latest \n -c 'chown -R ${HOST_UID}:${HOST_UID} /tmp/'
让我们分解一下其中的一些内容:
在容器内运行/bin/sh:
--入口点/bin/sh
将当前用户的 uid 作为环境变量传递给容器:
-e HOST_UID=
id -u
将您想要重新拥有的任何文件夹挂载回您的用户(填充了 root 拥有的文件,由以 root 身份运行的先前容器输出),在此新容器下
/tmp
:
-v ${HOST_FOLDER_OWNED_BY_ROOT}:/tmp
chown
使用主机用户的 uid 对目标目录(挂载在容器内)进行递归运行/tmp
:
-c'chown-R ${HOST_UID}:${HOST_UID}/tmp/'
因此,通过这个,我将文件所有权交还给我当前用户,而无需“升级”权限到 root 或 sudo。
虽然很脏,但还是有用。希望我帮到了你。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件