Warm tip: This article is reproduced from serverfault.com, please click

其他-docker cp之后的文件所有权

(其他 - File ownership after docker cp)

发布于 2017-10-06 20:13:11

如何控制哪个用户拥有我要复制到容器中或从容器中复制的文件?

docker cp命令说明有关文件所有权的信息:

cp命令的行为类似于Unixcp -a命令,因为如果可能,将以递归方式复制目录并保留权限。所有权设置为目的地的用户和主要组。例如,复制到容器的文件是使用UID:GIDroot用户创建的。复制到本地计算机上的文件是使用UID:GID调用该docker cp命令的用户的创建但是,如果指定该-a选项,docker cp则将所有权设置为源的用户和主要组。

它说复制到容器的文件是作为root用户创建的,但这不是我看到的。我创建了两个文件,分别由用户ID 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
$ 
Questioner
Don Kirkby
Viewed
0
Don Kirkby 2017-10-13 05:34:30

为了完全控制文件所有权,我使用了tar流功能docker cp

如果-SRC_PATH指定了DEST_PATH,则还可以从STDIN或向传送tar存档STDOUT

我启动该docker cp过程,然后将tar文件流传输至该过程或从该过程中流式传输。随着tar条目的通过,我可以随意调整所有权和权限。

这是Python中的一个简单示例,该示例/outputssandbox1容器中的所有文件复制到当前目录,排除当前目录,以免更改其权限,并强制所有文件具有用户的读/写权限。

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()