亲宝软件园·资讯

展开

Docker加载分层commit镜像

把苹果咬哭的测试笔记 人气:0

Docker容器的加载原理、分层原理、commit镜像

一、什么是镜像

如何得到镜像:

二、docker镜像加载原理

1. 联合文件系统UnionFS

UnionFS是一种分层、轻量级并且高性能的文件系统。支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。这个在我们下载镜像的时候,就可以看到这样的效果。

比如有涉及到相同的文件,那么就可以共用了,极大节省资源。

UnionFS是docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以
制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

2. 镜像加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级文件系统就是上述的UnionFS。接着,在内部又分为2部分:

rootfs就是各种不同的操作系统发行版,比如Ubuntu、Centos等等。

如图所示:

图中以debian系统为例,从左到右,分为3个过程:

说明了docker的镜像实际上是由层一层的文件系统组成的。对于不同的的linux发行版本,bootfs基本是一致的,rootfs会有差别,所以不同的发行版可以共用bootfs。

另外,在docker上的操作系统通常都是精简版的,在VM上安装个centos镜像大小1个G多,而在docker上的centos镜像只有200M大小。

因为底层直接用主机的内核,自己只需要提供rootfs就行了,所以rootfs可以很小,只需要包含最基本的命令、工具和程序库即可。

这样一来,启动速度也快了,因为最浪费时间的引导加载过程没了。

三、分层原理

知道了镜像的加载原理,不妨再回头看下镜像分层的原理。之前提过,镜像下载的时候是分层下载的,有些层如果已经存在了,就无需再次下载。

比如我下载一个redis的镜像。

这种方式最大的好处就在于资源共享。比如有多个镜像都从相同的BASE镜像构建来的,那么宿主机只需要在磁盘上保留1分BASE镜像,同时内存中也只需要加载一份BASE镜像,这样所有的容器都可以使用。另外,镜像的每一层都是可以共享的。

可以通过docker image inspect来查看镜像的分层,比如查看刚才下载的redis镜像:

docker image inspect redis:latest

所有的docker镜像都起始于一个基础镜像层,当进行修改或者增加新的内容时,就会在当前镜像层之上,创建新的镜像层。

比如:

我现在要制作一个镜像。

要注意的是:

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,如下图:

这里每个镜像层包含了3个文件,而镜像则是包含了来自2个镜像层的6个文件。

现在,如果第二层中的 文件5 需要升级版本。这时候上层镜像中的文件会覆盖底层镜像中对应的文件,使得文件里更新版本作为一个新镜像层添加到镜像当中。

docker 通过存储引擎的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

四、commit镜像

通过上面的了解,现在已经知道镜像的结构原理,那么我们自己就可以制作一个镜像来。

比如,现在pull一个tomcat镜像作为基础层,我启动这个镜像后,在容器里做了一些我自己的改动,我觉得我的这些改动很好,镜像变得更好用了。那么我需要来保存这个容器的状态,通过commit命令,提交镜像。

docker commit -m="提交描述信息" -a="作者" 容器id 目标镜像名称:版本标签

运行tomcat后,进入到webapps下,发现是没有项目的,因为是阉割版。

现在我把webapps.dist下的所有内容copy到webapps下。

现在我用ip:8080就可以访问到项目了。

现在我提交这个改动过后的容器。

docker commit -m="pingguo first commit image" -a="pingguo" 03844ff66434 tomcatpingguo:1.0

提交成功后,docker images查看镜像,发现已经保存在本地。

通过自己的提交镜像操作,再回过来体会下镜像的分层,是不是理解更深刻了些?

加载全部内容

相关教程
猜你喜欢
用户评论