我在Docker中使用一个简单的Linux机器.在Linux中使用它,我克隆我的dev存储库并将repo作为卷安装在Docker中.然后,当我进入Docker容器时,卷中的文件属于组1000中的用户1000(一切都很好,因为Docker正确保留了所有文件所有者).现在我试图在macOS中做同样的事情,但在我的macOS机器上,我的uid是501而我的gid是20.但是当我去容器时,我意识到里面的文件有gid和uid 0,同样的作为根.如何在Docker中保留文件所有权?
Dan*_*owe 21
osxfs驱动程序假装文件由USER
容器运行的文件所有.如果您看到挂载的文件由root拥有,则您的容器可能设置为以root身份运行.
macOS上的osxfs驱动程序对所有权有点谎言.以下是文档的相关部分(强调我的):
所有权
最初,任何请求对象的所有权元数据的容器化进程都被告知它
uid
并gid
拥有该对象.当任何容器化进程更改共享文件系统对象的所有权时(例如,使用)chown
,新的所有权信息将保留在com.docker.owner
对象的扩展属性中.对所有权元数据的后续请求将返回先前设置的值.基于所有权的权限仅在OS X文件系统级别强制执行,所有访问进程的行为与运行Docker的用户相同.如果用户没有权限读取对象的扩展属性(例如,当该对象的权限是0000
),osxfs
则将尝试添加允许用户读取和写入扩展属性的访问控制列表(ACL)条目.如果此尝试失败,则该对象将显示为访问它的进程所拥有,直到再次读取扩展属性为止.
换一种说法,
在容器内部,osxfs驱动程序假装在容器中运行的任何uid/gid也是拥有已安装文件的uid/gid.
如果你将文件(在容器中)chown到其他东西,则不会对真实文件执行chown; 此所有者信息存储在扩展文件属性中,该值由容器使用(并由macOS忽略).
真实文件由容器外的macOS拥有者拥有.访问控制是使用那些真实的文件所有权以及运行Docker应用程序的用户的uid/gid(可能是Mac上的登录用户)来确定的.
我将在Mac上使用容器作为示例.我构建了这个容器,这是它的Dockerfile的一部分:
FROM ubuntu:16.04
RUN useradd -d /planner -m planner
WORKDIR /planner
USER planner
Run Code Online (Sandbox Code Playgroud)
如您所见,此容器作为用户"planner"运行.在Ubuntu中是典型的,作为第一个添加到这个新系统的用户,它的uid为1000,gid为1000.
外面,在我的Mac上,我的uid和gid也很典型(501,20),但与我的容器中的"planner"用户不同.
我运行这个容器,安装了一个外部目录,其中包含我的代码.这样我就可以在开发期间重新加载应用程序而无需重建容器(一个常见的用例).
version: '2'
services:
uwsgi:
image: planner:latest
build: ./uwsgi
volumes:
- ./uwsgi/planner:/planner
Run Code Online (Sandbox Code Playgroud)
如果我查看./uwsgi/planner
Mac 上的源目录(),文件归我所有(uid 501,gid 20).
-rw-r--r-- 1 dan staff 3103 Oct 24 23:28 README.md
drwxr-xr-x 4 dan staff 136 Sep 14 2016 doc
-rwxr-xr-x 1 dan staff 260 Sep 14 2016 manage.py
drwxr-xr-x 7 dan staff 238 Jan 11 00:00 site_planner
drwxr-xr-x 4 dan staff 136 Jan 10 19:07 node_modules
drwxr-xr-x 12 dan staff 408 Mar 30 12:30 planner
-rw-r--r-- 1 dan staff 112 Oct 5 10:28 requirements.txt
Run Code Online (Sandbox Code Playgroud)
但是查看容器内的挂载目录,您可以看到虽然路径,日期和大小相同,但是osxfs已经屏蔽了所有者并告诉容器操作系统这些文件实际上是由"planner"拥有的.用户的实际名称和uid在这里并不重要.osxfs驱动程序只是使用当前用户.如果你有一个名为"joe"的uid 1005用户,那么你就会看到它.
-rw-r--r-- 1 planner planner 3103 Oct 25 03:28 README.md
drwxr-xr-x 4 planner planner 136 Sep 14 2016 doc
-rwxr-xr-x 1 planner planner 260 Sep 14 2016 manage.py
drwxr-xr-x 7 planner planner 238 Jan 11 05:00 site_planner
drwxr-xr-x 4 planner planner 136 Jan 11 00:07 node_modules
drwxr-xr-x 12 planner planner 408 Mar 30 16:30 planner
-rw-r--r-- 1 planner planner 112 Oct 5 14:28 requirements.txt
Run Code Online (Sandbox Code Playgroud)
现在,这只是Mac上的osxfs驱动程序.它是以简单的名义完成的 - 在Mac上你可能正在进行开发工作,文件权限的细微差别只是你必须解决的痛苦.此外,请注意,如果不使用sudo或其他工具来提升您的权限,则无法在Mac上执行此类chown.
$ chown 1000 manage.py
chown: manage.py: Operation not permitted
Run Code Online (Sandbox Code Playgroud)
这很重要,因为除了vmnetd之外,Mac上运行的所有Docker进程都以您的身份运行,而不是以root身份运行.(包括osxfs进程,如此截图所示.)
在Linux服务器上,它的工作方式更像您期望它的工作方式.例如,作为我在我的示例中使用的相同服务的一部分,我有一个postgres容器,它使用外部目录作为其数据存储.在我的Mac上,该目录中充满了我拥有的文件(但容器认为它们归用户"postgres"所有).但是,在服务器上,真实的uid保留在外部文件系统上.
$ ls -ln pgdata
total 120
drwx------. 6 999 999 4096 Oct 31 21:06 base
drwx------. 2 999 999 4096 Mar 8 19:22 global
drwx------. 2 999 999 4096 Oct 31 21:06 pg_clog
drwx------. 2 999 999 4096 Oct 31 21:06 pg_commit_ts
drwx------. 2 999 999 4096 Oct 31 21:06 pg_dynshmem
drwx------. 4 999 999 4096 Oct 31 21:06 pg_logical
drwx------. 4 999 999 4096 Oct 31 21:06 pg_multixact
drwx------. 2 999 999 4096 Mar 8 19:22 pg_notify
drwx------. 2 999 999 4096 Oct 31 21:06 pg_replslot
drwx------. 2 999 999 4096 Oct 31 21:06 pg_serial
drwx------. 2 999 999 4096 Oct 31 21:06 pg_snapshots
drwx------. 2 999 999 4096 Mar 8 19:22 pg_stat
drwx------. 2 999 999 4096 Apr 4 17:08 pg_stat_tmp
drwx------. 2 999 999 4096 Mar 20 15:36 pg_subtrans
drwx------. 2 999 999 4096 Oct 31 21:06 pg_tblspc
drwx------. 2 999 999 4096 Oct 31 21:06 pg_twophase
drwx------. 3 999 999 4096 Mar 17 18:30 pg_xlog
-rw-------. 1 999 999 4 Oct 31 21:06 PG_VERSION
-rw-------. 1 999 999 4496 Oct 31 21:06 pg_hba.conf
-rw-------. 1 999 999 1636 Oct 31 21:06 pg_ident.conf
-rw-------. 1 999 999 88 Oct 31 21:06 postgresql.auto.conf
-rw-------. 1 999 999 22233 Oct 31 21:06 postgresql.conf
-rw-------. 1 999 999 37 Mar 8 19:22 postmaster.opts
-rw-------. 1 999 999 68 Mar 8 19:22 postmaster.pid
Run Code Online (Sandbox Code Playgroud)
这里的文件由uid 999,gid 999拥有.这不是我的uid(在这个特定的服务器上是5046).
999是容器内的 postgres的uid ,它在文件权限中从外部公开.
换句话说,您遇到的问题是特定于Mac的,在生产中使用Linux时不应该有同样的问题.
归档时间: |
|
查看次数: |
2848 次 |
最近记录: |