Docker pull下来的镜像文件、创建出来的容器文件都存在本地的什么地方了?

已邀请:

DockOne - DockOne官方账号

赞同来自: 李颖杰 shlallen 田浩浩 wangzi19870227 Nego_Wang 执贱长老更多 »


非常好的问题,正好之前看到过一篇翻译的文章,我把其中的相关内容贴一下:

我们首先来看看 /var/lib/docker/这个文件夹下的内容。打开这个文件夹下的 repositories 文件,你将会看到类似下面这样的JSON 文件:
$ sudo cat /var/lib/docker/repositories | python -mjson.tool
{
“Repositories”: {
“ubuntu”: {
“12.04″: “8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c”,
“12.10″: “b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc”,
“latest”: “8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c”,
“precise”: “8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c”,
“quantal”: “b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc”
}
}
}

看看,是不是正好和docker images的内容一致呢。
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu              12.04               8dbd9e392a96        8 months ago        131.3 MB (virtual 131.3 MB)
ubuntu              latest              8dbd9e392a96        8 months ago        131.3 MB (virtual 131.3 MB)
ubuntu              precise             8dbd9e392a96        8 months ago        131.3 MB (virtual 131.3 MB)
ubuntu              12.10               b750fe79269d        8 months ago        24.65 kB (virtual 179.7 MB)
ubuntu              quantal             b750fe79269d        8 months ago        24.65 kB (virtual 179.7 MB)

接着,我们再来看看 /var/lib/docker/graph/这个文件夹:
$ sudo ls -al /var/lib/docker/graph
total 24
drwx—— 6 root root 4096 Nov 22 06:52 .
drwx—— 5 root root 4096 Dec 13 04:25 ..
drwxr-xr-x 3 root root 4096 Dec 13 04:26 27cf784147099545
drwxr-xr-x 3 root root 4096 Nov 22 06:52 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c
drwxr-xr-x 3 root root 4096 Nov 22 06:52 b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc
drwx—— 3 root root 4096 Nov 22 06:52 _tmp

这些输出结果可能有点晦涩(Not terribly friendly),但是从中我们可以看出Docker是使用repositories JSON文件来记述镜像信息的,此JSON文件包含了仓库名、标签、以及标签对应的镜像ID。
我们有两个来自ubuntu仓库的镜像,这其中标签为12.04,precise和latest都指向的是同一个镜像,其ID为 8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c (这个ID长度为64位,但是我们可以使用其12位的简短模式,比如8dbd9e392a96)。

那么这些以镜像ID命名的文件夹下面又保存了什么东西呢?
$ sudo ls -al /var/lib/docker/graph/8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c
total 20
drwxr-xr-x  3 root root 4096 Nov 22 06:52 .
drwx——  6 root root 4096 Nov 22 06:52 ..
-rw——-  1 root root  437 Nov 22 06:51 json
drwxr-xr-x 22 root root 4096 Apr 11  2013 layer
-rw——-  1 root root    9 Nov 22 06:52 layersize

这个文件夹下的内容如下:
  • json -保存着关于这个镜像的元数据
  • layersize – 一个整数,表示layer的大小。
  • layer/ – 子文件夹,保存着rootfs该容器的镜像


$ sudo cat /var/lib/docker/graph/8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c/json | python -mjson.tool
{
“comment”: “Imported from -“,
“container_config”: {
“AttachStderr”: false,
“AttachStdin”: false,
“AttachStdout”: false,
“Cmd”: null,
“Env”: null,
“Hostname”: “”,
“Image”: “”,
“Memory”: 0,
“MemorySwap”: 0,
“OpenStdin”: false,
“PortSpecs”: null,
“StdinOnce”: false,
“Tty”: false,
“User”: “”
},
“created”: “2013-04-11T14:13:15.57812-07:00″,
“docker_version”: “0.1.4″,
“id”: “8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c”
}

$ sudo cat /var/lib/docker/graph/8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c/layersize
131301903

$ sudo ls -al /var/lib/docker/graph/8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c/layer
total 88
drwxr-xr-x 22 root root 4096 Apr 11  2013 .
drwxr-xr-x  3 root root 4096 Nov 22 06:52 ..
drwxr-xr-x  2 root root 4096 Apr 11  2013 bin
drwxr-xr-x  2 root root 4096 Apr 19  2012 boot
drwxr-xr-x  4 root root 4096 Nov 22 06:51 dev
drwxr-xr-x 41 root root 4096 Nov 22 06:51 etc
drwxr-xr-x  2 root root 4096 Apr 19  2012 home
drwxr-xr-x 11 root root 4096 Nov 22 06:51 lib
drwxr-xr-x  2 root root 4096 Nov 22 06:51 lib64
drwxr-xr-x  2 root root 4096 Apr 11  2013 media
drwxr-xr-x  2 root root 4096 Apr 19  2012 mnt
drwxr-xr-x  2 root root 4096 Apr 11  2013 opt
drwxr-xr-x  2 root root 4096 Apr 19  2012 proc
drwx——  2 root root 4096 Nov 22 06:51 root
drwxr-xr-x  4 root root 4096 Nov 22 06:51 run
drwxr-xr-x  2 root root 4096 Nov 22 06:51 sbin
drwxr-xr-x  2 root root 4096 Mar  5  2012 selinux
drwxr-xr-x  2 root root 4096 Apr 11  2013 srv
drwxr-xr-x  2 root root 4096 Apr 14  2012 sys
drwxrwxrwt  2 root root 4096 Apr 11  2013 tmp
drwxr-xr-x 10 root root 4096 Nov 22 06:51 usr
drwxr-xr-x 11 root root 4096 Nov 22 06:51 var

看到这里你应该有些顿悟了吧,这就是我们为什么即使我们不和远程索引或者注册表交互也能通过仓库名来使用一个镜像的原理了。因为一旦你将镜像从远程下载到本地,Docker可以通过仓库名称来使用它们。当你创建自己的Dockerfile的时候也不例外。

[已注销]

赞同来自: wangzi19870227


@DockerOne 文章是去年3月份的,引用之前最好与现在版本对一下变动.其次,讨论存储最好说明底层的driver时什么

我这边对devicemapper了解不多,主要说说aufs的

镜像的存储结构主要分两部分,一是镜像ID之间的关联,一是镜像ID与镜像名称之间的关联,前者的结构体叫Graph,后者叫TagStore.
  1. /var/lib/graph/<image id>
    下面没有layer目录,只有每个镜像的json描述文件和layersize大小
  2. /var/lib/docker/repositories-aufs
    TagStore的存储地方,里面有image id与reponame ,tag之间的映射关系. aufs是driver名
  3. /var/lib/docker/aufs/diff/<image id or container id>
    每层layer与其父layer之间的文件差异,有的为空,有的有一些文件(镜像实际存储的地方)
  4. /var/lib/docker/aufs/layers/<image id or container id>
    每层layer一个文件,记录其父layer一直到根layer之间的ID,每个ID一行。大部分文件的最后一行都一样,表示继承自同一个layer.
  5. /var/lib/docker/aufs/mnt/<image id or container id>
    有容器运行时里面有数据(容器数据实际存储的地方,包含整个文件系统数据),退出时里面为空

shlallen - DaoCloud软件工程师,合伙人

赞同来自:


回答的好详细啊,要赞

wangzi19870227 - sina攻城狮,docker爱好者

赞同来自:


我的/var/lib/docker/graph/${image_id}目录下貌似只有json和layersize两个文件,没有layer这个目录?
[root@haichuan-vm docker]# ls graph/* -R
graph/511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158:
json  layersize

graph/53f858aaaf03033e088d357df23e311d71aa93ac578ef39aa8230580ea95076f:
json  layersize

graph/5b12ef8fd57065237a6833039acc0e7f68e363c15d8abb5cacce7143a1f7de8a:
json  layersize


我的环境:centos7 docker1.3.2

另外,发现/var/lib/docker/devicemapper/devicemapper下有两个大文件:
[root@haichuan-vm devicemapper]# ll /var/lib/docker/devicemapper/devicemapper/
total 881852
-rw-------. 1 root root 107374182400 Feb  9 10:46 data
-rw-------. 1 root root   2147483648 Feb  9 10:46 metadata


这两个文件都是hole文件,实际占用磁盘空间大小和local images大小总和基本一致:
[root@haichuan-vm devicemapper]# du -h /var/lib/docker/devicemapper/devicemapper/*
860M    /var/lib/docker/devicemapper/devicemapper/data
2.1M    /var/lib/docker/devicemapper/devicemapper/metadata


并且这两个文件大小会随着image pull、rmi操作而相应的增大、减小。so,我推测这两个文件就是docker pull ${image}之后,image的layers真正存储的地方。如果确实如此,不知为何docker不把image的layer保存为"透明的二进制"文件?或是像上面@DockerOne 所表述的那样保存为一个layer目录(这种方案不好的地方是不太安全,but应该还有其它考虑吧?)

另外,还是没有发现实际存放container的地方。如下:
containers/15947d012cf84e88a726a7fb76e74c783461e7c5eb6cbf59968f1ff9bde9ce89/15947d012cf84e88a726a7fb76e74c783461e7c5eb6cbf59968f1ff9bde9ce89-json.log
containers/15947d012cf84e88a726a7fb76e74c783461e7c5eb6cbf59968f1ff9bde9ce89/config.json
containers/15947d012cf84e88a726a7fb76e74c783461e7c5eb6cbf59968f1ff9bde9ce89/hostconfig.json
containers/15947d012cf84e88a726a7fb76e74c783461e7c5eb6cbf59968f1ff9bde9ce89/hostname
containers/15947d012cf84e88a726a7fb76e74c783461e7c5eb6cbf59968f1ff9bde9ce89/hosts
containers/15947d012cf84e88a726a7fb76e74c783461e7c5eb6cbf59968f1ff9bde9ce89/resolv.conf
containers/15947d012cf84e88a726a7fb76e74c783461e7c5eb6cbf59968f1ff9bde9ce89/secrets:


把问题总结一下:
1)实际存放images的地方是否是/var/lib/docker/devicemapper/devicemapper目录下的metadata和data两个文件?
2)如果是上面两个文件,为什么要这么存储?而不是存为"透明二进制"或"layer目录"?
3)实际存放container的地方在哪?

wangzi19870227 - sina攻城狮,docker爱好者

赞同来自:


看了近期开放的Docker镜像构建机制,实际存放images和container的地方就是/var/lib/docker/devicemapper/devicemapper目录下的metadata和data两个文件。

但第二个问题还是不明白,为什么要这么存储?而不是存为一个个的"透明二进制"或"layer目录"(安全考虑?)?

要回复问题请先登录注册