镜像是什么
镜像就是一种轻量级的、可执行的独立软件包,用于打包软件运行环境和基于运行环境运行的软件,它包含某个软件所需要的全部内容,包括代码、库、环境变量和配置文件,所有的文件直接打包成docker'镜像就可以直接跑起来。
如何得到镜像
- 从远程仓库下载
- 朋友给予
- 自己制作镜像Dockerfile
Docker镜像加载原理
UnionFS(联合文件系统),我们下载的时候看到的一层层的就是这个。
UnionFS(联合文件系统):Union文件系统是一种分层、轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看来只会看到一个文件系统,联合加载会把各层文件叠加起来,这样最终的文件系统会包含所底层的文件和目录。
Docker镜像加载原理
Docker的镜像实际上是由一层一层的文件系统组成,这种层级的文件系统叫UnionFS
bootfs主要包括bootloader和kernel,bootloader主要是引导加载kernel,linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs,这一层与我们典型的linux系统一样,包含boot加载器和内核,当boot加载完成之后内核就都在内存中了,此时内存的使用权由bootfs转角个内核,系统也会卸载bootfs
rootfs在bootfs指向,包含的就是典型linux系统中的/dev、/proc、/bin、/etc等标准目录和文件,rootfs就是各种不同的操作系统发行版,不如ubuntu、centos等
对于一个精简的容器,rootfs可以很小,只需要包含最基本的命令、工具和库就可以了,因为底层直接用的主机的kernal,自己只需要提供 rootfs就可以了。由此可见对于不同版本的linux,bootfs基本是一致的,而rootfs是有差别的。
分层理解
分层镜像
当你下载一个镜像的时候,注意观察下载的日志输出,会发现是一层一层的在下载。
思考:为什么Docker镜像要采用这种分层的结构呢?
最大的好处就是资源共享了!比如有多个镜像都是基于相同的base构建的,那么宿主机只需要在磁盘上保留一份base镜像,同时内存中也只要加载一份base镜像就可以为所有容器服务了,而且镜像的每一层都可以被共享。
查看镜像的指令用docker inspect 容器id
理解
所有的Docker镜像都是起始于一个基础镜像层,当进行修改或者增加新的内容时,就会在当前镜像上增加新的镜像层。举一个简单的例子,假如基于ubuntu16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加python包,就会在基础镜像层上创建第二个镜像层;继续添加补丁就会继续添加层。 如下图所示:
在添加额外的镜像层的同时,镜像始终是保持当前所有镜像的组合,理解这一点非常重要,下图举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了两个镜像层的6个文件。
上图中的镜像层跟之前的略有区别,主要是为了展示文件。下图中有三层镜像层,外部看来只有6个文件,因为文件7是文件5的更新版本。
这种情况下,上层镜像层的文件覆盖了下层的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像中。Docker通过存储引擎(新版采用快照机制)方式实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。 Linux上可用的存储引擎AUFS、Overlay2、Device Mapper、Brifs以及zfs等。每种存储引擎 都基于Linux中对应的文件系统或者块设备技术。Docker在windows上仅支持windowsfilter一种存储引擎。下图展示了与系统显示相同的三层镜像,所有镜像层堆叠并合并,对外提供统一的视图。
特点
Docker镜像都是只读的,当容器启动时一个新的可写层 被加载到镜像的顶部!这一层就是我们通常说的容器层容器层之下的叫镜像层:
commit镜像
docker commit 容器 提交容器作为一个新的镜像
docker commit -m=’提交的描述信息‘ -a=’作者‘ 容器id 目标镜像名:tag
实战测试
1.启动一个默认的tomcat。
2.发现这个默认的tomcat是没有 webapps的应用的,镜像的原因,官方镜像默认webapps中没有文件。
3.自己拷贝进去基本的文件:cp -r webapps.dist/* webapps。
4.将我们操作过的容器commit提交为一个镜像,我们以后用自己的镜像就可以了。