在 Docker 中,在容器内创建的文件在从主机检查它们时往往具有不可预测的所有权。默认情况下,卷上文件的所有者是 root (uid 0),但一旦非 root 用户帐户参与容器并写入文件系统,从主机的角度来看,所有者或多或少会变得随机。
当您需要使用调用 docker 命令的同一用户帐户从主机访问卷数据时,这是一个问题。
典型的解决方法是
- 在 Dockerfiles 中创建时强制用户 uID(不可移植)
- 将主机用户的 UID 传递给
docker run
命令作为环境变量,然后运行一些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->sub-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
-
手动编辑自动生成的从属 ID 范围/etc/subuid
and /etc/subgid
files:
ns1:500000:65536
(注意没有记录ns1-root
and ns1-user1
due to MAX_UID
and MAX_GID
限制在/etc/login.defs
)
-
启用用户命名空间/etc/default/docker
:
DOCKER_OPTS="--userns-remap=ns1"
重新启动守护进程service docker restart
, 确保/var/lib/docker/500000.500000
目录已创建。
现在,在容器内你有root
and user1
,并在主机上--ns1-root
and ns1-user1
,具有匹配的 ID
UPDATE:为了保证非 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
不便携,看起来像黑客,但可以工作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)