docker cp后的文件所有权
我如何控制哪个用户拥有我从容器中复制的文件?
docker cp
命令对文件所有权进行了说明:
cp
命令的行为与Unixcp -a
命令的行为相同,即在可能的情况下保留权限,recursion复制该目录。 所有权设置为目标用户和主要组。 例如,复制到容器的文件是使用根用户的UID:GID
创build的。 复制到本地机器的文件是使用调用docker cp
命令的用户的UID:GID
创build的。 但是,如果指定-a
选项,则docker cp
将所有权设置为源用户和主组。
它说复制到容器的文件是以root用户身份创build的,但这不是我所看到的。 我创build了由用户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 $
为了完全控制文件所有权,我使用了docker cp
的tarstream特性:
如果为
SRC_PATH
或DEST_PATH
指定了-
也可以从STDIN
或STDOUT
stream式传输tar归档文件。
我启动docker cp
进程,然后将tar文件docker cp
进程。 随着tar条目的过去,我可以调整所有权和权限,但是我喜欢。
以下是Python中的一个简单示例, sandbox1
容器中的所有文件/outputs
sandbox1
到当前目录,排除当前目录,使其权限不被更改,并强制所有文件对用户具有读/写权限。
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()