在docker中,在容器内创建的文件在从主机检查时往往具有不可预测的所有权.默认情况下,卷上文件的所有者是root(uid 0),但只要非root用户帐户涉及容器并写入文件系统,所有者就会从主机角度变得或多或少随机.
当您需要使用调用docker命令的同一用户帐户从主机访问卷数据时,这是一个问题.
典型的解决方法是
docker run作为环境变量传递给命令,然后chown在入口点脚本中的卷上运行某些命令.这两种解决方案都可以控制容器外的实际权限.
我希望用户命名空间是这个问题的最终解决方案.我已经使用最近发布的版本1.10和--userns-remap设置到我的桌面帐户运行了一些测试.但是,我不确定它是否可以使安装卷上的文件所有权更容易处理,我担心它实际上可能正好相反.
假设我启动这个基本容器
docker run -ti -v /data debian:jessie /bin/bash
echo 'hello' > /data/test.txt
exit
Run Code Online (Sandbox Code Playgroud)
然后检查来自主机的内容:
ls -lh /var/lib/docker/100000.100000/volumes/<some-id>/_data/
-rw-r--r-- 1 100000 100000 6 Feb 8 19:43 test.txt
Run Code Online (Sandbox Code Playgroud)
这个数字'100000'是我的主机用户的子UID,但由于它与我的用户的UID不对应,我仍然无法在没有权限的情况下编辑test.txt.此子用户似乎与docker之外的实际常规用户没有任何关联.它没有映射回来.
由于UID->sub-UID名称空间中发生的映射,本文前面提到的由主机和容器之间的UID对齐组成的变通方法不再起作用.
那么,有没有办法在启用用户命名空间的情况下运行docker(为了提高安全性),同时仍然可以让运行docker的主机用户拥有在卷上生成的文件?
ama*_*nov 40
如果您可以提前预先安排用户和组,则可以以特定方式分配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
Run Code Online (Sandbox Code Playgroud)在/etc/subuid和/etc/subgid文件中手动编辑自动生成的从属ID范围:
ns1:500000:65536
Run Code Online (Sandbox Code Playgroud)
(注意没有记录ns1-root,ns1-user1由于MAX_UID和MAX_GID限制/etc/login.defs)
启用用户名称空间/etc/default/docker:
DOCKER_OPTS="--userns-remap=ns1"
Run Code Online (Sandbox Code Playgroud)
重启守护进程service docker restart,确保/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
Run Code Online (Sandbox Code Playgroud)从容器中试试
docker run --rm -ti -v /vol1:/vol1 busybox sh
echo "Hello from container" > /vol1/file
exit
Run Code Online (Sandbox Code Playgroud)试试主持人
passwd ns1-root
login ns1-root
cat /vol1/file
echo "can write" >> /vol1/file
Run Code Online (Sandbox Code Playgroud)不便携,看起来像黑客,但有效.
一种解决方法是在构建时动态分配用户的 uid 以匹配主机。
例子Dockerfile:
FROM ubuntu
# Defines argument which can be passed during build time.
ARG UID=1000
# Create a user with given UID.
RUN useradd -d /home/ubuntu -ms /bin/bash -g root -G sudo -u $UID ubuntu
# Switch to ubuntu user by default.
USER ubuntu
# Check the current uid of the user.
RUN id
# ...
Run Code Online (Sandbox Code Playgroud)
然后构建为:
docker build --build-arg UID=$UID -t mycontainer .
Run Code Online (Sandbox Code Playgroud)
并运行为:
docker run mycontainer
Run Code Online (Sandbox Code Playgroud)
如果您已有容器,请使用以下内容创建一个包装容器Dockerfile:
FROM someexistingcontainer
ARG UID=1000
USER root
# This assumes you've the existing user ubuntu.
RUN usermod -u $UID ubuntu
USER ubuntu
Run Code Online (Sandbox Code Playgroud)
这可以包含在docker-compose.yml如下内容中:
version: '3.4'
services:
myservice:
command: id
image: myservice
build:
context: .
volumes:
- /data:/data:rw
Run Code Online (Sandbox Code Playgroud)
然后构建并运行为:
docker-compose build --build-arg UID=$UID myservice; docker-compose run myservice
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26248 次 |
| 最近记录: |