Docker 用户进出容器 : what is the correspondence (UID/GID), 看到我不明白的效果

标签 docker

我试图充分了解 docker 的功能,以便对我安全地使用它产生合理的信心。对此的一个建议是始终使用 USER Dockerfile 中的语句。在试图理解这一点的影响时,我遇到了一些麻烦。

具体问题:

  • 什么机制可以让宿主机内核处理只存在于容器中的用户?
  • 为什么下面的run2显示目录属于testuser但不允许 ls什么时候在目录?
  • 为什么下面的run3显示目录属于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
    

    现在 testuserkasterma具有相同的 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/

    相关文章:

    docker - Apache NIFI请求包含无效的主机头

    docker - 如何重新启动 Docker 容器/镜像/机器?

    mysql - 如何避免 optaweb-employee-rostering 在服务器重新启动时重建持久数据

    docker - 运行netcore-react应用时出现docker-compose错误

    docker - .env的Docker-Compose传递命令args

    同一主机上运行的多个容器的日志记录解决方案

    node.js - 如何在azure devops管道中为node js构建作业设置环境变量

    docker - 在 Docker 容器中运行 Docker : Cannot connect to the Docker daemon

    docker build question没有读取权限

    node.js - 在 Amazon ECS 上的 Docker 中运行 Node API 的最佳方式是什么?