首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >文件所有权在docker cp之后

文件所有权在docker cp之后
EN

Stack Overflow用户
提问于 2017-10-06 20:13:11
回答 4查看 25K关注 0票数 21

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

命令说这是关于文件所有权的:

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

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

代码语言:javascript
运行
复制
$ 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选项似乎什么也做不了。

代码语言:javascript
运行
复制
$ 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
$ 
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-10-12 21:34:30

为了完全控制文件所有权,我使用了焦油流docker cp特性。

如果为-DEST_PATH指定了tar,则还可以将tar存档从STDINSTDOUT流到STDOUT

我启动docker cp进程,然后向进程或从进程中流一个tar文件。随着tar条目的过去,我可以随意调整所有权和权限。

下面是Python中的一个简单示例,它将/outputs容器中的所有文件复制到当前目录,排除当前目录,使其权限不会被更改,并强制所有文件都具有用户的读/写权限。

代码语言:javascript
运行
复制
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()
票数 4
EN

Stack Overflow用户

发布于 2020-12-08 09:12:56

还可以通过以root用户身份登录到容器中来更改所有权:

代码语言:javascript
运行
复制
docker exec -it --user root <container-id> /bin/bash
chown -R <username>:<groupname> <folder/file>
票数 23
EN

Stack Overflow用户

发布于 2018-09-21 14:57:50

除了@Don Kirkby的回答之外,让我在bash/shell脚本中提供一个类似的示例,用于在应用与原始文件不同的所有权和权限的同时,将某些内容复制到容器中。

让我们从一个小映像中创建一个新容器,它将保持自身运行:

代码语言:javascript
运行
复制
docker run -d --name nginx nginx:alpine

现在,我们将创建一个由当前用户拥有并具有默认权限的新文件:

代码语言:javascript
运行
复制
touch foo.bar
ls -ahl foo.bar
>> -rw-rw-r-- 1 my-user my-group 0 Sep 21 16:45 foo.bar

将此文件复制到容器中将将所有权和组设置为我的用户的UID,并保留权限:

代码语言:javascript
运行
复制
docker cp foo.bar nginx:/foo.bar
docker exec nginx sh -c 'ls -ahl /foo.bar'
>> -rw-rw-r--    1 4098     4098           0 Sep 21 14:45 /foo.bar

但是,使用少量的tar工作,我可以更改容器内部应用的所有权和权限。

代码语言:javascript
运行
复制
tar -cf - foo.bar --mode u=+r,g=-rwx,o=-rwx --owner root --group root | docker cp - nginx:/
docker exec nginx sh -c 'ls -ahl /foo.bar'
>> -r--------    1 root     root           0 Sep 21 14:45 /foo.bar

tar选项解释如下:

  • c创建一个新的存档,而不是解压一个。
  • f -将写入stdout而不是文件。
  • foo.bar是要打包的输入文件。
  • --mode指定目标的权限。类似于chown,它们可以用符号表示法或八进制数表示。
  • --owner设置文件的新所有者。
  • --group设置文件的新组。

docker cp -读取要从stdin复制到容器中的文件。

当文件需要在文件启动前复制到创建的容器中时,这种方法非常有用,因此docker exec不是一个选项(只能对运行的容器进行操作)。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46613326

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档