2017-10-06 94 views
0

如何控制哪个用户拥有我从容器中复制的文件?docker cp后的文件所有权

docker cp command说这有关文件的所有权:

在该目录中的cp命令的行为像Unix cp -a命令与可能的话保存权限递归复制。所有权设置为目标用户和主要组。例如,复制到容器的文件是使用root用户的UID:GID创建的。复制到本地机器的文件是使用调用docker cp命令的用户的UID:GID创建的。但是,如果您指定-a选项,则docker cp会将所有权设置为源用户和主组。

它说复制到容器的文件是作为root用户创建的,但这不是我所看到的。我创建了由用户标识1005和1006拥有的两个文件。这些所有者被转换为容器的用户名称空间。当我将文件复制到容器中时,-a选项似乎没有任何区别。

$ sudo chown 1005:1005 test.txt 
$ ls -l test.txt 
-rw-r--r-- 1 1005 1005 29 Oct 6 12:43 test.txt 
$ docker volume create sandbox1 
sandbox1 
$ docker run --name run1 -vsandbox1:/data alpine echo OK 
OK 
$ docker cp test.txt run1:/data/test1005.txt 
$ docker cp -a test.txt run1:/data/test1005a.txt 
$ sudo chown 1006:1006 test.txt 
$ docker cp test.txt run1:/data/test1006.txt 
$ docker cp -a test.txt run1:/data/test1006a.txt 
$ docker run --rm -vsandbox1:/data alpine ls -l /data 
total 16 
-rw-r--r-- 1 1005  1005   29 Oct 6 19:43 test1005.txt 
-rw-r--r-- 1 1005  1005   29 Oct 6 19:43 test1005a.txt 
-rw-r--r-- 1 1006  1006   29 Oct 6 19:43 test1006.txt 
-rw-r--r-- 1 1006  1006   29 Oct 6 19:43 test1006a.txt 

当我将文件从容器中复制出来时,它们总是归我所有。再次,-a选项似乎什么都不做。

$ docker run --rm -vsandbox1:/data alpine cp /data/test1006.txt /data/test1007.txt 
$ docker run --rm -vsandbox1:/data alpine chown 1007:1007 /data/test1007.txt 
$ docker cp run1:/data/test1006.txt . 
$ docker cp run1:/data/test1007.txt . 
$ docker cp -a run1:/data/test1006.txt test1006a.txt 
$ docker cp -a run1:/data/test1007.txt test1007a.txt 
$ ls -l test*.txt 
-rw-r--r-- 1 don don 29 Oct 6 12:43 test1006a.txt 
-rw-r--r-- 1 don don 29 Oct 6 12:43 test1006.txt 
-rw-r--r-- 1 don don 29 Oct 6 12:47 test1007a.txt 
-rw-r--r-- 1 don don 29 Oct 6 12:47 test1007.txt 
-rw-r--r-- 1 1006 1006 29 Oct 6 12:43 test.txt 
$ 

回答

0

为了获得文件所有权的完全控制权,我用的docker cptar stream功能:

如果任SRC_PATHDEST_PATH指定-,你也可以流从一个tar归档STDINSTDOUT

我启动docker cp过程,然后流tar文件或从过程。随着焦油条目的过去,我可以调整所有权和权限,但我喜欢。

下面是Python的一个简单的例子,所有副本的sandbox1容器到当前目录下的从/outputs文件,不包括当前目录,以便它的权限没有得到改变,并强制所有文件具有读/写权限为用户。

from subprocess import Popen, PIPE, CalledProcessError 
import tarfile 

def main(): 
    export_args = ['sudo', 'docker', 'cp', 'sandbox1:/outputs/.', '-'] 
    exporter = Popen(export_args, stdout=PIPE) 
    tar_file = tarfile.open(fileobj=exporter.stdout, mode='r|') 
    tar_file.extractall('.', members=exclude_root(tar_file)) 
    exporter.wait() 
    if exporter.returncode: 
     raise CalledProcessError(exporter.returncode, export_args) 

def exclude_root(tarinfos): 
    print('\nOutputs:') 
    for tarinfo in tarinfos: 
     if tarinfo.name != '.': 
      assert tarinfo.name.startswith('./'), tarinfo.name 
      print(tarinfo.name[2:]) 
      tarinfo.mode |= 0o600 
      yield tarinfo 

main()