泊坞窗和--userns重新映射,如何管理权限卷共享主机和容器之间的数据?泊坞窗和--userns重

2019-05-13 06:33发布

在码头工人,货柜内创建的文件往往有不可预知的所有权,同时从主机检查它们。 一个卷上的文件的所有者是根默认(UID 0),但只要非根用户帐户都参与了容器和写入文件系统,拥有者成为从主机的角度或多或少随机的。

这是一个问题,当你需要使用它调用泊坞窗命令相同的用户帐户的主机访问量数据。

典型的变通办法

  • 迫使用户的UID在创建时在Dockerfiles(非便携式)
  • 使所述主机用户的UID到docker run命令作为环境变量,然后运行一些chown在一个入口点脚本的卷上的命令。

这两种解决方案可以给在容器外面的实际权限一些控制。

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

假设我开始这个基本的容器

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。 该子用户似乎并不与泊坞窗的外面我的实际经常用户的任何亲和力。 这不是映射回。

早在这个帖子里面包括主机和容器之间对准的UID提到的解决方法不要再因工作UID->sub-UID发生在命名空间映射。

那么,有没有一种方式来运行启用了(为了提高安全性)用户的命名空间泊坞窗,同时还使其能够运行搬运工人把自己卷上生成的文件主机用户?

Answer 1:

如果你能提前酝酿的用户和组,那么它可能使主机用户对应于集装箱内命名空间的用户分配UID和GID在这种特定的方式。

下面是一个例子(Ubuntu的14.04,多克尔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-rootns1-user1由于MAX_UIDMAX_GID在限制/etc/login.defs

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

     DOCKER_OPTS="--userns-remap=ns1" 

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

    现在,容器里面你有rootuser1 ,并在主机上- ns1-rootns1-user1 ,与之相配的ID

    UPDATE:保证非root用户有固定的容器中的ID(如USER1 1000:1000),图像生成过程中明确创建它们。

试驾:

  1. 准备卷目录

     mkdir /vol1 chown ns1-root:ns1-root /vol1 
  2. 从容器试试吧

     docker run --rm -ti -v /vol1:/vol1 busybox sh echo "Hello from container" > /vol1/file exit 
  3. 从主机尝试

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

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



Answer 2:

您可以通过使用避免权限问题docker cp命令 。

所有权被设置为用户和主要组的目的地。 例如,复制到一个容器文件与创建UID:GID根用户。 复制到本地机文件与创建UID:GID其调用用户的docker cp命令。

这里就是你们的榜样切换到使用docker cp

$ docker run -ti -v /data debian:jessie /bin/bash
root@e33bb735a70f:/# echo 'hello' > /data/test.txt
root@e33bb735a70f:/# exit
exit
$ docker volume ls
DRIVER              VOLUME NAME
local               f073d0e001fb8a95ad8d919a5680e72b21a457f62a40d671b63c62ae0827bf93
$ sudo ls -l /var/lib/docker/100000.100000/volumes/f073d0e001fb8a95ad8d919a5680e72b21a457f62a40d671b63c62ae0827bf93/_data
total 4
-rw-r--r-- 1 100000 100000 6 Oct  6 10:34 test.txt
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                          PORTS               NAMES
e33bb735a70f        debian:jessie       "/bin/bash"         About a minute ago   Exited (0) About a minute ago                       determined_hypatia
$ docker cp determined_hypatia:/data/test.txt .
$ ls -l test.txt 
-rw-r--r-- 1 don don 6 Oct  6 10:34 test.txt
$ cat test.txt
hello
$ 

不过,如果你只想读出一个容器的文件,你不需要指定的音量。 此示例使用一个名为容器,而不是一个名为量:

$ docker run -ti --name sandbox1 debian:jessie /bin/bash
root@93d098233cf3:/# echo 'howdy' > /tmp/test.txt
root@93d098233cf3:/# exit
exit
$ docker cp sandbox1:/tmp/test.txt .
$ ls -l test.txt
-rw-r--r-- 1 don don 6 Oct  6 10:52 test.txt
$ cat test.txt
howdy
$ 

我发现一个名为卷有用的,当我想将文件复制到一个容器中,如描述的这个问题 。



Answer 3:

一个解决办法是动态分配的编译时间用户的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
# ...

然后建立如下:

docker build --build-arg UID=$UID -t mycontainer .

并且运行:

docker run mycontainer

如果你现有的容器,创建具有以下的包装容器Dockerfile

FROM someexistingcontainer
ARG UID=1000
USER root
# This assumes you've the existing user ubuntu.
RUN usermod -u $UID ubuntu
USER ubuntu

这可以被包裹在docker-compose.yml喜欢:

version: '3.4'
services:
  myservice:
    command: id
    image: myservice
    build:
      context: .
    volumes:
    - /data:/data:rw

然后建立和运行:

docker-compose build --build-arg UID=$UID myservice; docker-compose run myservice


文章来源: Docker and --userns-remap, how to manage volume permissions to share data between host and container?
标签: docker