簡體   English   中英

docker cp 后的文件所有權

[英]File ownership after docker cp

如何控制哪個用戶擁有我復制進和復制出容器的文件?

docker cp命令說明了文件所有權:

cp命令的行為類似於 Unix cp -a命令,因為目錄被遞歸復制,並盡可能保留權限。 所有權設置為目的地的用戶和主要組。 例如,復制到容器的文件是使用 root 用戶的UID:GID創建的。 復制到本地機器的文件是使用調用docker cp命令的用戶的UID:GID創建的。 但是,如果您指定-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
$ 

除了@Don Kirkby 的回答之外,讓我在 bash/shell 腳本中提供一個類似的示例,用於將某些內容復制到容器中,同時應用與原始文件不同的所有權和權限的情況。

讓我們從一個小鏡像創建一個新的容器,它會繼續自己運行:

docker run -d --name nginx nginx:alpine

現在我們將創建一個由當前用戶擁有並具有默認權限的新文件:

touch foo.bar
ls -ahl foo.bar
>> -rw-rw-r-- 1 my-user my-group 0 Sep 21 16:45 foo.bar

將此文件復制到容器中會將所有權和組設置為我的用戶的UID並保留權限:

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變通方法,我可以更改應用於容器內部的所有權和權限。

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不是一個選項(只能對正在運行的容器進行操作)。

您還可以通過以 root 用戶身份登錄容器來更改所有權:

docker exec -it --user root <container-id> /bin/bash
chown -R <username>:<groupname> <folder/file>

為了完全控制文件所有權,我使用了docker cptar 流功能:

如果為SRC_PATHDEST_PATH指定了- ,您還可以將 tar 存檔從STDIN流式傳輸到STDOUT

我啟動docker cp進程,然后將 tar 文件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()

只是一個單行(類似於@ramu 的回答),使用root撥打電話:

docker exec -u 0 -it <container-id> chown node:node /home/node/myfile

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM