我试图充分了解 docker 的功能,以便对我安全地使用它产生合理的信心。对此的一个建议是始终使用 USER
Dockerfile 中的语句。在试图理解这一点的影响时,我遇到了一些麻烦。
具体问题:
testuser
但不允许 ls
什么时候在目录? testuser
? 此问题底部的版本信息。
设置
我有以下 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
我用
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
的用户和组ID在主机。在这种情况下 testuser
有 uid 和 gid 1000。还
/ $ cd test-home
sh: cd: can't cd to test-home
运行 2:仅删除标记为
##sometimes removed
的第二行在 Dockerfile 中。/ $ 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(尽管一个在容器中,另一个在主机上)。为什么我可以cd
,但不是 ls
?运行 3:删除标记为
##sometimes removed
的任何一行在 Dockerfile 中。/ $ 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
不同.但 list 显示它为 testuser,但 cd
命令失败。版本信息
操作系统版本(在 VirtualBox 中的 VM 上运行)
[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-run
Labeling systems like SELinux require that proper labels are placed on volume content mounted into a container. Without a label, the security system might prevent the processes running inside the container from using the content. By default, Docker does not change the labels set by the OS. To change a label in the container context, you can add either of two suffixes :z or :Z to the volume mount. These suffixes tell Docker to relabel file objects on the shared volumes. The z option tells Docker that two containers share the volume content. As a result, Docker labels the content with a shared content label. Shared volume labels allow all containers to read/write content. The Z option tells Docker to label the content with a private unshared label. Only the current container can use a private volume.
所以,你可以试试,而不是禁用 SELinux
docker run -ti -v /home/kasterma/test-user/:/test-home:Z kasterma/testuser:1
见 Using Volumes with Docker can Cause Problems with SELinux更多细节。
我在我的盒子上尝试了你的用例(没有 SELinux 并且有 Docker 版本 1.12.5):我总是获得正确的“testuser”所有权,我能够更改目录并列出其内容(我的本地 uid 是 1000,我没有没有更多的用户在它之上)。因此,您的问题可能是由于较旧的 Docker 版本造成的。
如果与 SELinux 和旧 Docker 版本无关,则您描述的行为似乎与 有关。用户命名空间 .
检查您主机的内核是否启用了用户命名空间(CentOS 7,这似乎是您正在使用的发行版,默认情况下不启用它。
看 Using User Namespaces on Docker描述了如何在 CentOS 7 上启用用户命名空间以及如何检查正确的行为。
关于用户命名空间的详细信息,请查看以下几个站点:
Introduction to User Namespaces in Docker Engine
Docker Security
User namespaces have arrived in Docker!
Docker for your users - Introducing user namespace
您可以在 Deni Bertovic blog - Handling Permissions with Docker Volumes 上找到关于在引入用户命名空间之前(Docker 1.10 之前)之前 Docker 卷中权限的明确描述。 .
希望能帮助到你。
关于Docker 用户进出容器 : what is the correspondence (UID/GID), 看到我不明白的效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41397809/