docker cp之后的文件所有权 [英] File ownership after docker cp

查看:74
本文介绍了docker cp之后的文件所有权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I control which user owns the files I copy in and out of a container?

docker cp 命令关于文件所有权的说法:

The docker cp command says this about file ownership:

cp 命令的行为类似于Unix cp -a 命令,因为目录被递归复制,并在可能的情况下保留了权限.所有权设置为目的地的用户和主要组.例如,使用根用户的 UID:GID 创建复制到容器的文件.复制到本地计算机上的文件是使用调用 docker cp 命令的用户的 UID:GID 创建的.但是,如果指定 -a 选项,则 docker cp 会将所有权设置为源用户和主要组.

The cp command behaves like the Unix cp -a command in that directories are copied recursively with permissions preserved if possible. Ownership is set to the user and primary group at the destination. For example, files copied to a container are created with UID:GID of the root user. Files copied to the local machine are created with the UID:GID of the user which invoked the docker cp command. However, if you specify the -a option, docker cp sets the ownership to the user and primary group at the source.

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

It says that files copied to a container are created as the root user, but that's not what I see. I create two files owned by user id 1005 and 1006. Those owners are translated into the container's user namespace. The -a option seems to make no difference when I copy the file into a container.

$ 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 选项似乎什么也没做.

When I copy files out of the container, they are always owned by me. Again, the -a option seems to do nothing.

$ 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
$ 

推荐答案

为了完全控制文件所有权,我使用了

In order to get complete control of file ownership, I used the tar stream feature of docker cp:

如果为 SRC_PATH DEST_PATH 指定了-,则还可以从 STDIN 或 STDOUT .

If - is specified for either the SRC_PATH or DEST_PATH, you can also stream a tar archive from STDIN or to STDOUT.

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

I launch the docker cp process, then stream a tar file to or from the process. As the tar entries go past, I can adjust the ownership and permissions however I like.

这是Python中的一个简单示例,该示例将 sandbox1 容器中/outputs 中的所有文件复制到当前目录,不包括当前目录,因此其权限不进行更改,并强制所有文件对用户具有读/写权限.

Here's a simple example in Python that copies all the files from /outputs in the sandbox1 container to the current directory, excludes the current directory so its permissions don't get changed, and forces all the files to have read/write permissions for the user.

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

这篇关于docker cp之后的文件所有权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆