Docker用户进出容器:什么是通信(UID / GID),看不到效果
我想了解docker的运行情况,以确保我能够安全地使用它。 一个build议是在Dockerfile中总是使用USER
语句。 为了理解这个效果,我遇到了一些麻烦。
具体问题:
- 什么机制允许主机内核处理只存在于容器中的用户?
- 为什么下面的run2显示目录属于
testuser
但不允许ls
在目录中? - 为什么下面的run3显示属于
testuser
的目录?
版本信息在这个问题的底部。
build立
我有以下的Dockerfile
FROM alpine@sha256:1354db23ff5478120c980eca1611a51c9f2b88b61f24283ee8200bf9a54f2e5c LABEL version 2.0 LABEL description "Test image for setting user" RUN adduser -D testuser1 ## sometimes removed RUN adduser -D testuser2 ## sometimes removed RUN adduser -D testuser USER testuser CMD sh
我用这个来构build它
docker build -t kasterma/testuser:1 .
然后运行
docker run -ti -v /home/kasterma/test-user/:/test-home kasterma/testuser:1
目录/home/kasterma/test-user/
是包含Dockerfile的目录。
运行1:删除标记为“ ##sometimes removed
在Dockerfile中删除”的两行。
[root@datalocal01 test-user]# docker run -ti -v /home/kasterma/test-user/:/test-home kasterma/testuser:1 / $ ls -lh ... drwx------ 2 1001 1001 40 Dec 30 14:08 test-home ...
这里显示的用户和组都是1001; 这是主机中的kasterma
的用户和groupid。 在这种情况下testuser
有uid和gid 1000。
也
/ $ cd test-home sh: cd: can't cd to test-home
运行2:只删除标记为##sometimes removed
的第二行, ##sometimes removed
在Dockerfile中##sometimes removed
。
/ $ ls -lh ... drwx------ 2 testuser testuser 40 Dec 30 14:12 test-home ...
和
/ $ cd test-home /test-home $ ls ls: can't open '.': Permission denied
现在testuser
和kasterma
具有相同的uid和gid(尽pipe它们在容器中,另一个在主机上)。 为什么我可以cd
,但不是ls
?
运行3:删除在Dockerfile中##sometimes removed
标记为“ ##sometimes removed
的行。
/ $ ls -lh ... drwx------ 2 testuser testuser 40 Dec 30 14:15 test-home ...
和
/ $ cd test-home sh: cd: can't cd to test-home
现在testuser
有uid和gid 1002,所以和kasterma
不一样。 但是列表显示为testuser,但是cd
命令失败。
版本信息
操作系统版本(在VirtualBox中的虚拟机上运行)
[root@datalocal01 test-user]# uname -a Linux datalocal01 3.10.0-514.2.2.el7.x86_64 #1 SMP Tue Dec 6 23:06:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
和docker工人
[root@datalocal01 test-user]# docker version Client: Version: 1.10.3 API version: 1.22 Package version: docker-common-1.10.3-59.el7.centos.x86_64 Go version: go1.6.3 Git commit: 3999ccb-unsupported Built: Thu Dec 15 17:24:43 2016 OS/Arch: linux/amd64 Server: Version: 1.10.3 API version: 1.22 Package version: docker-common-1.10.3-59.el7.centos.x86_64 Go version: go1.6.3 Git commit: 3999ccb-unsupported Built: Thu Dec 15 17:24:43 2016 OS/Arch: linux/amd64
当主机运行SELinux时,如果文件系统没有标记,则可能无法访问文件系统内容。 从男子docker运行
像SELinux这样的标签系统要求在安装到容器中的卷内容上放置正确的标签。 如果没有标签,安全系统可能会阻止容器内运行的进程使用内容。 默认情况下,Docker不会更改OS设置的标签。 要更改容器上下文中的标签,可以将两个后缀之一:z或:Z添加到卷装载。 这些后缀告诉Docker重新标记共享卷上的文件对象。 z选项告诉Docker两个容器共享卷内容。 因此,Docker使用共享内容标签来标记内容。 共享卷标允许所有容器读取/写入内容。 Z选项告诉Docker用私有的非共享标签来标记内容。 只有当前容器可以使用私人卷。
所以,而不是禁用SELinux,你可以尝试
docker run -ti -v /home/kasterma/test-user/:/test-home:Z kasterma/testuser:1
有关更多详细信息,请参阅使用Docker中的卷可能会导致SELinux出现问题 。
我在我的盒子上试过你的用例(没有SELinux和Docker版本1.12.5):我总是得到正确的“testuser”所有权,我可以改变目录并列出它的内容(我的本地uid是1000,上面有更多的用户)。 所以,可能你的问题是由于较老的Docker版本造成的。
如果不涉及到SELinux既不是旧的Docker版本,你描述的行为似乎与用户命名空间有关 。
检查您的主机的内核是否启用用户命名空间(CentOS 7,似乎您正在使用的发行版,默认情况下不启用它。
在Docker上使用User Namespaces来描述如何在CentOS 7上启用User namespaces,以及如何检查正确的行为。
关于用户命名空间的详细信息,看看几个网站,如:
Docker引擎中的用户命名空间简介
Docker安全
用户命名空间已经到达Docker!
你的用户的Docker – 引入用户命名空间
在Deni Bertovic博客介绍User Namespaces(在Docker 1.10之前)之前,您可以在Docker卷中find有关权限的明确说明- 处理Docker卷的权限 。
希望能帮助到你。