`docker cp`命令如何工作

时间:2017-07-23 17:19:30

标签: docker centos cp device-mapper

命令docker cp用于将文件从主机复制到容器,反之亦然。即使容器处于停止状态或退出,此命令也可以工作。 Docker使用分层方法来存储图像,当我们使用这个图像运行容器时,它会在它上面创建一个可写层,它负责容器内完成的所有更改。一旦我们从容器中退出,这个可写层就消失了。在这里,我无法找到,即使在容器退出之后,docker也会存储可用于docker cp命令的容器数据。我搜索了/var/lib/docker目录,但没有运气。我正在使用带有devicemapper存储驱动程序的centos7.2 for docker。有没有人有任何想法?

2 个答案:

答案 0 :(得分:2)

首先,容器有3件事

1)cgroups 2)名称空间 3)文件系统

从映像生成的每个容器都由所有这三个东西组成,这意味着每个容器都有自己的文件系统。

命令docker cp用于将文件从主机复制到容器,反之亦然。即使容器处于停止状态或退出,此命令也可以工作。 Docker使用分层方法来存储图像,当我们使用这个图像运行容器时,它会在它上面创建一个可写层,它负责容器内完成的所有更改。同意。

我们将可写层称为容器层。一旦你从容器中退出,这个可写层就会消失,这意味着你没有提交更改,或者没有新的内容写入这个可写层。如果您已完成提交,您将获得带有新创建的图像的附加可写层的新docker镜像。删除容器时,将删除写入容器中未存储在数据卷中的任何数据以及容器。

docker cp命令即使在退出容器状态时也能工作,这意味着它确实存储在主机上的某个位置。现在,另一点不是数据卷,它是我们可以直接挂载到容器中的目录或文件系统。因此,容器内的数据由存储驱动程序管理。在CentOS中,存储图像和图层的devicemapper包含在thinpool中,并通过将它们安装在/var/lib/docker/devicemapper/的子目录下将它们暴露给容器。 /var/lib/devicemapper/mnt/目录包含存在的每个图像和容器层的安装点。图像层安装点为空,但容器的安装点显示容器的文件系统,因为它显示在容器内。它使用快照机制,其中每个图像层是它下面的图层的快照。

数据驻留在我们请求cp命令的容器的父映像的块级别。由于容器是图像的快照,它没有块,但它有一个指向最近的父图像上的块的指针,它存在,并从那里读取相应的块并复制它将可用于我们的docker cp命令。并且,如果退出容器,请求将直接转到相应父图像的块以及可用于复制的文件的块。

希望您理解术语。现在,您可以通过试验图层和容器来测试它。一切都好。

答案 1 :(得分:0)

除非您使用--rm option,否则退出时不会删除泊坞窗容器。相反,您可以使用docker cp在文件退出后将文件复制到容器中或从容器中复制文件:

$ docker run --name run1 alpine sh -c "date > /tmp/test.txt"
$ docker cp run1:/tmp/test.txt test.txt
$ cat test.txt
Fri Oct  6 19:23:09 UTC 2017

您询问了这些文件的存储位置,因此我们需要进行一些挖掘。所有的docker数据文件似乎都在/var/lib/docker下,所以我环顾四周,在overlay2文件夹下找到了一些东西。

$ sudo ls -lt /var/lib/docker/100000.100000/overlay2
total 180
drwx------ 5 100000 100000 4096 Oct  6 12:23 bda6a77ed8fad218f738f32a149d4f9f9e46b103675b8b8f990f48e3339fd315
drwx------ 2 100000 100000 4096 Oct  6 12:23 l
drwx------ 5 100000 100000 4096 Oct  6 12:23 bda6a77ed8fad218f738f32a149d4f9f9e46b103675b8b8f990f48e3339fd315-init
drwx------ 3 100000 100000 4096 Oct  6 10:30 9c2aa6553beac112794143531e7760add2c94733898ae0674c5da30c3feb9451
...

那里有更多的文件夹,但最近的文件夹可能有我们正在寻找的东西。 diff文件夹似乎包含图像和容器之间更改的所有文件。如果我查看那里,我会找到我创建的文件。

$ sudo ls -l /var/lib/docker/100000.100000/overlay2/bda6a77ed8fad218f738f32a149d4f9f9e46b103675b8b8f990f48e3339fd315/diff
total 4
drwxrwxrwt 2 100000 100000 4096 Oct  6 12:23 tmp
$ sudo ls -l /var/lib/docker/100000.100000/overlay2/bda6a77ed8fad218f738f32a149d4f9f9e46b103675b8b8f990f48e3339fd315/diff/tmp
total 4
-rw-r--r-- 1 100000 100000 29 Oct  6 12:23 test.txt
$ sudo cat /var/lib/docker/100000.100000/overlay2/bda6a77ed8fad218f738f32a149d4f9f9e46b103675b8b8f990f48e3339fd315/diff/tmp/test.txt
Fri Oct  6 19:23:09 UTC 2017
$ 

docker cp只是为我挖掘所有东西。更容易。我正在使用docker 17.09.0-ce,如果这个内部结构从版本变为版本,我不会感到惊讶。