Docker和--userns-remap,如何管理卷权限以在主机和容器之间共享数据? [英] Docker and --userns-remap, how to manage volume permissions to share data between host and container?

查看:1827
本文介绍了Docker和--userns-remap,如何管理卷权限以在主机和容器之间共享数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在docker中,容器内部创建的文件在从主机检查时容易产生不可预测的所有权。默认情况下,卷上的文件所有者为root(uid 0),但是一旦非root用户帐户涉及到容器并写入文件系统,所有者从主机的角度就会变得更加随机。 / p>

当您需要使用正在调用docker命令的同一用户帐户访问主机中的卷数据时,这是一个问题。



典型的解决方法是在Dockerfiles中强制用户uID(在Dockerfiles的创建时间)(不包括


    <将 b $ b
  • 将主机用户的UID作为环境变量传递给 docker运行命令,然后运行一些 chown 命令在entrypoint脚本中的卷。



这两种解决方案都可以控制容器外的实际权限。



我预计用户名空间是此问题的最终解决方案。我已经运行一些测试与最近发布的版本1.10和--userns-remap设置到我的桌面帐户。但是,我不确定它可以使装载卷上的文件所有权更容易处理,我恐怕实际上可能是相反的。



假设我开始基本容器

  docker run -ti -v / data debian:jessie / bin / bash 
echo'hello'> ; /data/test.txt
exit

然后从主机检查内容: / p>

  ls -lh /var/lib/docker/100000.100000/volumes/<some-id>/_data/ 

-rw-r - r-- 1 100000 100000 6二月8 19:43 test.txt

这个数字'100000'是我的主机用户的一个子UID,但由于它不符合我用户的UID,我仍然无法编辑没有权限的test.txt。这个子用户似乎与我的实际常规用户没有任何亲和力。它没有被映射回来。



这篇文章中提到的解决方法包括主机和容器之间的UID对齐,因为 UID-> sub-UID 映射发生在命名空间中。



然后,是否有一种方法来运行启用了用户名空间的docker (为了提高安全性),同时仍然可以使运行docker的主机用户拥有卷上生成的文件?

解决方案

如果您可以提前预定义用户和组,那么可以以特定的方式分配UID和GID,以便主机用户对应于容器内的命名空间用户。



这里有一个例子(Ubuntu 14.04,Docker 1.10):


  1. 创建一些具有固定数字ID的用户:

      useradd -u 5000 ns1 

    groupadd -g 500000 ns1-root
    groupadd -g 501000 ns1-user1

    useradd -u 500000 -g ns1-root ns1-root
    useradd -u 501000 -g ns1-user1 ns1-user1 -m


  2. 手动编辑自动生成的从属ID范围在 / etc / subuid / etc / subgid 文件:

      ns1:500000:65536 

    (注意有因为 ns1-root ns1-user1 由于 MAX_UID MAX_GID 限制在 /etc/login.defs


  3. / etc / default / docker 中启用用户名空间:

      DOCKER_OPTS = -  userns-remap = ns1

    重新启动守护程序 service docker restart ,确保 /var/lib/docker/500000.500000 目录是创建。



    现在,在容器内部,您有 user1 ,在主机上 - ns1-root ns1-user1 ,具有匹配的ID



    更新:以确保非root用户在容器中具有固定的ID(例如user1 1000:1000),在构建映像期间明确创建它们。


测试驱动器:


  1. 准备卷目录

      mkdir / vol1 
    chown ns1-root:ns1-root / vol1


  2. 从容器尝试



    Docker运行--rm -ti -v / vol1:/ vol1 busybox sh
    echo从容器开始> / vol1 / file
    exit


  3. 从主机尝试

      passwd ns1-root 
    login ns1-root
    cat / vol1 / file
    echocan write> ;> / vol1 / file


不可移植,看起来像一个黑客,但工作。


In docker, files created inside containers tend to have unpredictable ownership while inspecting them from the host. The owner of the files on a volume is root (uid 0) by default, but as soon as non-root user accounts are involved in the container and writing to the file system, owners become more or less random from the host perspective.

It is a problem when you need to access volume data from the host using the same user account which is calling the docker commands.

Typical workarounds are

  • forcing users uIDs at creation time in Dockerfiles (non portable)
  • passing the UID of the host user to the docker run command as an environment variable and then running some chown commands on the volumes in an entrypoint script.

Both these solutions can give some control over the actual permissions outside the container.

I expected user namespaces to be the final solution to this problem. I have run some tests with the recently released version 1.10 and --userns-remap set to my desktop account. However, I am not sure that it can make file ownership on mounted volumes easier to deal with, I am afraid that it could actually be the opposite.

Suppose I start this basic container

docker run -ti -v /data debian:jessie /bin/bash
echo 'hello' > /data/test.txt
exit

And then inspect the content from the host :

ls -lh /var/lib/docker/100000.100000/volumes/<some-id>/_data/

-rw-r--r-- 1 100000 100000 6 Feb  8 19:43 test.txt

This number '100000' is a sub-UID of my host user, but since it does not correspond to my user's UID, I still can't edit test.txt without privileges. This sub-user does not seem to have any affinity with my actual regular user outside of docker. It's not mapped back.

The workarounds mentioned earlier in this post which consisted of aligning UIDs between the host and the container do not work anymore due to the UID->sub-UID mapping that occurs in the namespace.

Then, is there a way to run docker with user namespace enabled (for improved security), while still making it possible for the host user running docker to own the files generated on volumes?

解决方案

If you can prearrange users and groups in advance, then it's possible to assign UIDs and GIDs in such specific way so that host users correspond to namespaced users inside containers.

Here's an example (Ubuntu 14.04, Docker 1.10):

  1. Create some users with fixed numeric IDs:

    useradd -u 5000 ns1
    
    groupadd -g 500000 ns1-root
    groupadd -g 501000 ns1-user1
    
    useradd -u 500000 -g ns1-root ns1-root
    useradd -u 501000 -g ns1-user1 ns1-user1 -m
    

  2. Manually edit auto-generated subordinate ID ranges in /etc/subuid and /etc/subgid files:

    ns1:500000:65536
    

    (note there are no records for ns1-root and ns1-user1 due to MAX_UID and MAX_GID limits in /etc/login.defs)

  3. Enable user namespaces in /etc/default/docker:

    DOCKER_OPTS="--userns-remap=ns1"
    

    Restart daemon service docker restart, ensure /var/lib/docker/500000.500000 directory is created.

    Now, inside containers you have root and user1, and on the host -- ns1-root and ns1-user1, with matching IDs

    UPDATE: to guarantee that non-root users have fixed IDs in containers (e.g. user1 1000:1000), create them explicitly during image build.

Test-drive:

  1. Prepare a volume directory

    mkdir /vol1
    chown ns1-root:ns1-root /vol1
    

  2. Try it from a container

    docker run --rm -ti -v /vol1:/vol1 busybox sh
    echo "Hello from container" > /vol1/file
    exit
    

  3. Try from the host

    passwd ns1-root
    login ns1-root
    cat /vol1/file
    echo "can write" >> /vol1/file
    

Not portable and looks like a hack, but works.

这篇关于Docker和--userns-remap,如何管理卷权限以在主机和容器之间共享数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆