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

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

问题描述

在 docker 中,在容器内创建的文件在从主机检查它们时往往具有不可预测的所有权.默认情况下,卷上文件的所有者是 root (uid 0),但是一旦容器中涉及非 root 用户帐户并写入文件系统,从主机的角度来看,所有者或多或少变得随机.

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.

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

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.

典型的解决方法是

  • 在创建时在 Dockerfiles 中强制用户使用 uID(不可移植)
  • 将主机用户的 UID 作为环境变量传递给 docker run 命令,然后在入口点脚本中的卷上运行一些 chown 命令.
  • 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.

我希望用户命名空间是这个问题的最终解决方案.我已经使用最近发布的 1.10 版和 --userns-remap 设置为我的桌面帐户运行了一些测试.但是,我不确定它是否可以使挂载卷上的文件所有权更容易处理,恐怕实际上可能恰恰相反.

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

这个数字'100000'是我的宿主用户的子UID,但由于它不对应我用户的UID,我仍然无法在没有权限的情况下编辑test.txt.这个子用户似乎与我在 docker 之外的实际普通用户没有任何关系.它没有映射回来.

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.

本文前面提到的包括在主机和容器之间对齐 UID 的解决方法不再起作用,因为 UID->sub-UID 映射发生在命名空间中.

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.

那么,有没有办法在启用用户命名空间的情况下运行 docker(为了提高安全性),同时仍然可以让运行 docker 的主机用户拥有在卷上生成的文件?

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?

推荐答案

如果你可以预先安排用户和组,那么就可以通过这种特定的方式分配 UID 和 GID,以便主机用户对应于容器内的命名空间用户.

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.

这是一个示例(Ubuntu 14.04,Docker 1.10):

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

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

  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

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

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

    ns1:500000:65536
    

    (注意 ns1-rootns1-user1 由于 MAX_UIDMAX_GID 没有记录/etc/login.defs)

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

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

    Enable user namespaces in /etc/default/docker:

    DOCKER_OPTS="--userns-remap=ns1"
    

    重启守护进程service docker restart,确保/var/lib/docker/500000.500000目录已经创建.

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

    现在,在容器内你有 rootuser1,在主机上——ns1-rootns1-user1,具有匹配的 ID

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

    更新: 为保证非 root 用户在容器中具有固定 ID(例如 user1 1000:1000),请在映像构建期间显式创建它们.

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

    试驾:

    1. 准备一个卷目录

    1. Prepare a volume directory

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

  • 从容器中尝试

  • Try it from a container

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

  • 从主机尝试

  • 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天全站免登陆