2017-10-06 1966 views
0

如何控制哪個用戶擁有我從容器中複製的文件?docker cp後的文件所有權

docker cp command說這有關文件的所有權:

在該目錄中的cp命令的行爲像Unix cp -a命令與可能的話保存權限遞歸複製。所有權設置爲目標用戶和主要組。例如,複製到容器的文件是使用root用戶的UID:GID創建的。複製到本地機器的文件是使用調用docker cp命令的用戶的UID:GID創建的。但是,如果您指定-a選項,則docker cp會將所有權設置爲源用戶和主組。

它說複製到容器的文件是作爲root用戶創建的,但這不是我所看到的。我創建了由用戶標識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 
$ 

回答

0

爲了獲得文件所有權的完全控制權,我用的docker cptar stream功能:

如果任SRC_PATHDEST_PATH指定-,你也可以流從一個tar歸檔STDINSTDOUT

我啓動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()