分层存储
因为镜像包含操作系统完整的root
文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
为了给大家更好的说明docker分层,我简单的画了个图:这样是不是就更容易明白。
接下来我们通过查看已经使用过的镜像,看看建立了多少层。
[root@docker01 kod]# docker image history kod:v1
IMAGE CREATED CREATED BY SIZE COMMENT
0cb8570501c2 4 hours ago /bin/sh -c #(nop) CMD ["/bin/bash" "/init.s… 0B
b3c16a974832 4 hours ago /bin/sh -c #(nop) EXPOSE 80 0B
3accb1a39dec 4 hours ago /bin/sh -c #(nop) ADD file:d2eb5832a79974baa… 71B
b2da41f6de39 4 hours ago /bin/sh -c chmod -R 777 /var/www/html 46.4MB
3fafe7686735 4 hours ago /bin/sh -c unzip kodexplorer.zip 32.5MB
0f2e23c07571 4 hours ago /bin/sh -c #(nop) COPY file:1c1d7e056dad265c… 13.9MB
2d82050d0c64 4 hours ago /bin/sh -c #(nop) WORKDIR /var/www/html 0B
258d58cc840e 4 hours ago /bin/sh -c yum install httpd php php-cli unz… 137MB
2199b8eb8390 4 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 4 months ago /bin/sh -c #(nop) LABEL name=CentOS Base Im… 0B
<missing> 4 months ago /bin/sh -c #(nop) ADD file:0e6d175401c5b4260… 195MB
[root@docker01 kod]#
上面是我们在前面做的可道云网盘,可以看见有6次数据变动(size >0B,即为数据变动),因此可以判定该镜像kod已经有6曾,为了更好的证实,我们直接去看看镜像的层数。
进入/var/lib/docker/image/overlay2(docker镜像存储默认位置)执行tree命令,在执行tree命令之前,我们需要先将额外的镜像都删掉,否则tree出来就会有很多层级,不容易找到我们想要的kod镜像的信息。
[root@docker01 overlay2]# pwd
/var/lib/docker/image/overlay2
[root@docker01 overlay2]# tree
.
├── distribution
.
.
.
├── imagedb
.
.
.
├── layerdb
│ ├── mounts
│ ├── sha256
│ │ ├── 3ef205072ac5db56ae4cd548637ba87140ea3a19e20b2b47ab1e0af81b1ad2dc
│ │ │ ├── cache-id
│ │ │ ├── diff
│ │ │ ├── parent
│ │ │ ├── size
│ │ │ └── tar-split.json.gz
│ │ ├── 6547e4ebf8b9004b4ad7f111d2934c02b29ac1022f641dcf0bcbe8994731daae
│ │ │ ├── cache-id
│ │ │ ├── diff
│ │ │ ├── parent
│ │ │ ├── size
│ │ │ └── tar-split.json.gz
│ │ ├── 65a634b751557cd918a27361fe5c24737df737c6d96cfd1b159b188d0531dd5d
│ │ │ ├── cache-id
│ │ │ ├── diff
│ │ │ ├── parent
│ │ │ ├── size
│ │ │ └── tar-split.json.gz
│ │ ├── 6f01adb2c832d8faeb45b06a17bf5f1dfe125c64c7807cd398bf4f7ef4ad7d26
│ │ │ ├── cache-id
│ │ │ ├── diff
│ │ │ ├── parent
│ │ │ ├── size
│ │ │ └── tar-split.json.gz
│ │ ├── aaa5621d7c0157cae5916c9cca66dd8fc2fb4bdb74813ed463b73d5b58cccfdf
│ │ │ ├── cache-id
│ │ │ ├── diff
│ │ │ ├── size
│ │ │ └── tar-split.json.gz
│ │ └── f90436d76d1b9e69bf3ac779703209988e1f4d9c88195ec819b69fc732fd11f7
│ │ ├── cache-id
│ │ ├── diff
│ │ ├── parent
│ │ ├── size
│ │ └── tar-split.json.gz
│ └── tmp
└── repositories.json
28 directories, 62 files
[root@docker01 overlay2]#
可以看见在layerdb-sha256,有6个分层。
docker为什么要分层呢?
分层的好处:共享资源,节省资源 有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。
其实这一章我将的并不太好,希望大家下手轻点,骂我可以,别骂我家人,啊哈哈哈。