在研究docker overlay时候碰到一个很有趣的问题。
也就是docker images时候显示image的大小。docker是怎么知道image大小的?
众所周知,dockers是分层存储image的。不同的image可以share同一层。那么他们是怎么share同一层layer的?
问题的答案首先要从docker inspect开始,这里我们只关注RootFS:
root@mcong-Virtual-Machine:/var/lib/docker# docker image inspect --format "{{ json .RootFS.Layers }}" 7698f282e524 | python -m json.tool
[
"sha256:02571d034293cb241c078d7ecbf7a84b83a5df2508f11a91de26ec38eb6122f1",
"sha256:270f934787edf0135132b6780cead0f12ca11690c5d6a5d395e44d290912100a",
"sha256:8d267010480fed7e616b9b7861854042aad4ef5e55f8771f2c738061640d2cb0"
]
这里我们得到了一堆数字。但是这个数字代表什么呢?在哪?
这些文件在这个目录:
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb# tree
.
├── mounts
├── sha256
│ ├── 02571d034293cb241c078d7ecbf7a84b83a5df2508f11a91de26ec38eb6122f1
│ │ ├── cache-id
│ │ ├── diff
│ │ ├── size
│ │ └── tar-split.json.gz
│ ├── 027b23fdf3957673017df55aa29d754121aee8a7ed5cc2898856f898e9220d2c
│ │ ├── cache-id
│ │ ├── diff
│ │ ├── parent
│ │ ├── size
│ │ └── tar-split.json.gz
│ └── 0dfbdc7dee936a74958b05bc62776d5310abb129cfde4302b7bcdf0392561496
│ ├── cache-id
│ ├── diff
│ ├── parent
│ ├── size
│ └── tar-split.json.gz
└── tmp
可以看出, 有两个文件没有parent。我们先看有parent的目录。
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb/sha256/0dfbdc7dee936a74958b05bc62776d5310abb129cfde4302b7bcdf0392561496# cat parent
sha256:02571d034293cb241c078d7ecbf7a84b83a5df2508f11a91de26ec38eb6122f1
这个是不是似曾相识?这个就是代表它的parent是02571d034293cb241c078d7ecbf7a84b83a5df2508f11a91de26ec38eb6122f1这个目录。
我们在看看cache-id这个文件。
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb/sha256/0dfbdc7dee936a74958b05bc62776d5310abb129cfde4302b7bcdf0392561496# cat cache-id
071bf84e3c225f0b81340d225832100b04bb015b0a3dcd0fb376e0d88e97f8f3
这一串数字是啥嘞?想想一一篇文章说的overlay?对就是它。
root@mcong-Virtual-Machine:/var/lib/docker/overlay2# ls
071bf84e3c225f0b81340d225832100b04bb015b0a3dcd0fb376e0d88e97f8f3 8ea06311f7fa82211f09765c9880b1bf1b947ac21bb98b99f6a573ce69b55859
0aa86c675bb91414fe320abbe7d04ef1f916f17caaca16f4d3d5ff65f8a3e7d1 l
这样我们就串起来了。
我们在看看size这个文件。
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb/sha256/0dfbdc7dee936a74958b05bc62776d5310abb129cfde4302b7bcdf0392561496# cat size
745
这个就是这一层的大小。docker image的大小就是这几层size相加。
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb/sha256/0dfbdc7dee936a74958b05bc62776d5310abb129cfde4302b7bcdf0392561496# cat size
745
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb/sha256/02571d034293cb241c078d7ecbf7a84b83a5df2508f11a91de26ec38eb6122f1# cat size
69858350
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb/sha256/027b23fdf3957673017df55aa29d754121aee8a7ed5cc2898856f898e9220d2c# cat size
7
total size 69859102约等于69.9Mb(1000 = 1k)
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 7698f282e524 2 months ago 69.9MB
我们先起一个container:
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb# docker run -ti ubuntu bash
root@ca27d3f2a38e:/#
我们会发现多了一个mount信息:
root@mcong-Virtual-Machine:/var/lib/docker/overlay2# mount |grep overlay
overlay on /var/lib/docker/overlay2/d3dddf2495b5b656a4af86402e433e8207eb33872712ae831bb9fbb84e09ea51/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/22QH5EXSYEVBQSOP3FP66EDCOY:/var/lib/docker/overlay2/l/IVKI5UJXVI6PDDFG772SYUG5BF:/var/lib/docker/overlay2/l/2AKHZHYWB6NVU54RID3EVEOJRL:/var/lib/docker/overlay2/l/V445NSA64ILRIBFUP5D4NVHC5I,upperdir=/var/lib/docker/overlay2/d3dddf2495b5b656a4af86402e433e8207eb33872712ae831bb9fbb84e09ea51/diff,workdir=/var/lib/docker/overlay2/d3dddf2495b5b656a4af86402e433e8207eb33872712ae831bb9fbb84e09ea51/work,xino=off)
这个就是我们之前讲的:把所有相关的layer mount到 /var/lib/docker/overlay2/d3dddf2495b5b656a4af86402e433e8207eb33872712ae831bb9fbb84e09ea51/merged。
我们还会发现 多了一个mount目录:
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb# tree
.
├── mounts
│ └── ca27d3f2a38e00646408f8ed28478febbe421625b6d3d4d813adfd421787b448
│ ├── init-id
│ ├── mount-id
│ └── parent
├── sha256
│ ├── 02571d034293cb241c078d7ecbf7a84b83a5df2508f11a91de26ec38eb6122f1
│ │ ├── cache-id
│ │ ├── diff
│ │ ├── size
│ │ └── tar-split.json.gz
│ ├── 027b23fdf3957673017df55aa29d754121aee8a7ed5cc2898856f898e9220d2c
│ │ ├── cache-id
│ │ ├── diff
│ │ ├── parent
│ │ ├── size
│ │ └── tar-split.json.gz
│ └── 0dfbdc7dee936a74958b05bc62776d5310abb129cfde4302b7bcdf0392561496
│ ├── cache-id
│ ├── diff
│ ├── parent
│ ├── size
│ └── tar-split.json.gz
└── tmp
这也解释了上篇文章。
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb# cat mounts/ca27d3f2a38e00646408f8ed28478febbe421625b6d3d4d813adfd421787b448//init-id
d3dddf2495b5b656a4af86402e433e8207eb33872712ae831bb9fbb84e09ea51-init
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb# cat mounts/ca27d3f2a38e00646408f8ed28478febbe421625b6d3d4d813adfd421787b448//mount-id
d3dddf2495b5b656a4af86402e433e8207eb33872712ae831bb9fbb84e09ea51
root@mcong-Virtual-Machine:/var/lib/docker/image/overlay2/layerdb# cat mounts/ca27d3f2a38e00646408f8ed28478febbe421625b6d3d4d813adfd421787b448/parent
sha256:027b23fdf3957673017df55aa29d754121aee8a7ed5cc2898856f898e9220d2c
parent 也就是刚才分析的image的最底层。
mount-id也就是container的最重要的层,
init-id也就是上篇文章讲的内容。