Docker和–userns-remap,如何管理卷权限以在主机和容器之间共享数据?

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

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

典型的解决方法是

>强制用户在创建时的uids在Dockerfiles(非便携式)
>将主机用户的UID作为环境变量传递给docker run命令,然后在entrypoint脚本中的卷上运行一些chown命令。

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

我期望用户命名空间是这个问题的最终解决方案。我已经运行一些测试与最近发布的版本1.10和–userns-remap设置为我的桌面帐户。然而,我不知道它可以使安装卷上的文件所有权更容易处理,恐怕它可能实际上是相反的。

假设我启动这个基本容器

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

然后检查主机的内容:

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之外的任何亲和。它没有映射回来。

由于在命名空间中发生UID>子UID映射,在本文前面提到的解决方案(包括对齐主机和容器之间的UID)不再工作。

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

最佳答案
如果您可以预先安排用户和组,那么可以以这种特定方式分配UID和GID,以便主机用户与容器内的命名空间用户对应。

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

>创建一些固定数字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

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

ns1:500000:65536

(注意,由于/etc/login.defs中的MAX_UID和MAX_GID限制,ns1-root和ns1-user1没有记录)
>在/ etc / default / docker中启用用户命名空间:

DOCKER_OPTS="--userns-remap=ns1"

重新启动守护程序服务docker重新启动,确保创建了/var/lib/docker/500000.500000目录。

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

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

试驾:

>准备卷目录

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

>从容器中尝试

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

>尝试从主机

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

不便携,看起来像一个黑客,但工程。

转载注明原文:Docker和–userns-remap,如何管理卷权限以在主机和容器之间共享数据? - 代码日志