【Docker】7. 镜像-加载原理、分层原理、commit镜像
一、什么是镜像
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件。
它包含运行某个软件所需的所有内容,包括代码、运行时环境、库、环境变量和配置文件。
所有的应用,直接打包成docker镜像,就可以直接跑起来。
如何得到镜像:
- 从远程仓库下载
- 从其他地方copy
- 自己制作一个镜像 DockerFile
二、docker镜像加载原理
1. 联合文件系统UnionFS
UnionFS是一种分层、轻量级并且高性能的文件系统。支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录
挂载到同一个虚拟文件系统下。这个在我们下载镜像的时候,就可以看到这样的效果。

比如有涉及到相同的文件,那么就可以共用了,极大节省资源。
UnionFS是docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以
制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会
包含所有底层的文件和目录。
2. 镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级文件系统就是上述的UnionFS。接着,在内部又分为2部分:
bootfs(boot file system):docker镜像的最底层是bootfs,主要包含bootloader(加载器)和kernel(内核)。
bootloader主要是引导加载kernel,linux刚启动时会加载bootfs文件系统。这一层与典型的linux/Unix系统一样,包含bootloader和kernel。
当boot加载完成后,整个内核就在内存中了,此时内存的使用权已由bootfs转交给了内核,此时系统也会卸载bootfs。
这里的加载,可以理解为,我们windows电脑开机时候,从黑屏到进入操作系统的过程。rootfs(root file system):在bootfs之上,包含的就是典型linux系统中的
/dev、/proc、/bin、/etc等标准目录和文件。
rootfs就是各种不同的操作系统发行版,比如Ubuntu、Centos等等。
如图所示:

图中以debian系统为例,从左到右,分为3个过程:
- 图1,开始的状态,下载了一个debian系统。
- 图2,安装了一个emacs,这时候可以看到在图1基础上,加了一层Image。
- 图3,又装了一个Apache,此时在图2的基础上再加了一层Image。
说明了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镜像都起始于一个基础镜像层,当进行修改或者增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
比如:

我现在要制作一个镜像。
- 这个镜像基于Ubuntu linux 16.04,这也是镜像的第一层。
- 继续还要安装python包,就会在第一层之上创建第二个镜像层。
- 继续打补丁的话,还会再创建第三个镜像层。
要注意的是:
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,如下图:

这里每个镜像层包含了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查看镜像,发现已经保存在本地。

通过自己的提交镜像操作,再回过来体会下镜像的分层,是不是理解更深刻了些?
【Docker】7. 镜像-加载原理、分层原理、commit镜像的更多相关文章
- paip.gui控件tabs控件加载内容的原理以及easyui最佳实现
paip.gui控件tabs控件加载内容的原理以及easyui最佳实现 //////////////tabs控件的加载 同form窗体一样,俩个方式 两个方式:一个是url,简单的文本可以使用这个,不 ...
- 滚动加载图片(懒加载)实现原理(这是旧实现,仅做为获取元素宽高api的参考)
https://www.cnblogs.com/flyromance/p/5042187.html 本文主要通过以下几方面来说明懒加载技术的原理,个人前端小菜,有错误请多多指出 一.什么是图片滚动加载 ...
- Springboot默认加载application.yml原理以及扩展
Springboot默认加载application.yml原理以及扩展 SpringApplication.run(...)默认会加载classpath下的application.yml或applic ...
- java的加载与执行原理剖析
到目前为止,我们接触过的重点术语,总结一下: Java体系的技术被划分为三大块: JavaSE:标准版 JavaEE:企业版 JavaME:微型版 安装JDK之后: JDK:java开发工具箱 JRE ...
- k8s-记一次安全软件导致镜像加载失败
近期在现场项目中遇到了一个镜像加载失败的问题,相关报错如下: Error processing tar file(exit status 1): symlink . /usr/bin/X11: per ...
- nopCommerce 3.9 大波浪系列 之 网页加载Widgets插件原理
一.插件简介 插件用于扩展nopCommerce的功能.nopCommerce有几种类型的插件如:支付.税率.配送方式.小部件等(接口如下图),更多插件可以访问nopCommerce官网. 我们看下后 ...
- java类什么时候加载?,加载类的原理机制是怎么样的?
java类什么时候加载?,加载原理机制是怎么样的? 答: 很多人都不是很清楚java的class类什么时候加载在运行内存中,其实类加载的时间是发生在一下几种情况: 1.实例化对象时,就像sprin ...
- docker 保存镜像 加载镜像
1.保存镜像 docker save -o 保存的文件名 来源镜像 2.加载镜像 docker load -i 保存的文件名
- seajs模块加载与执行原理小记
本文仅讨论具名模块的情况,即通过spm打包出来的模块. 想起ID与路径统一原则,详见https://github.com/seajs/seajs/issues/930 今天又研究了下seajs源码,源 ...
随机推荐
- js_笔记_8月7日记录_活动对象_作用域链_按值传递
活动对象:简单说就是这个函数的参数和显示声明的变量或函数. 函数内接受的参数实际是创建了一个局部变量:[形参名] = [传进来的值],js的函数传参只传值. 作用域链:执行流进入一个函数,会先创建出作 ...
- 《C++反汇编与逆向分析技术揭秘》--数据类型
浮点数类型 IEEE标准从逻辑上采用一个三元组{S, E, M}来表示一个数N,它规定基数为2,符号位S用0和1分别表示正和负,尾数M用原码表示,阶码E用移码表示.根据浮点数的规格化方法,尾数域的 ...
- 【linux】系统编程-3-system-V IPC 信号量
目录 前言 5. 信号量 5.1 概念 5.2 工作原理 5.3 操作函数 5.3.1 semget() 5.3.2 semop() 5.3.3 semctl() 5.4 例程 参考: 前言 原文链接 ...
- windows一些知识
宽字节 1.什么是ASCII码? 一张存储了字母大小写与一些符号的表,用一个字节表示,最高位不使用,最多只能存储128个符号或字母,但世界上有很多种语言,这远远不够 2.什么是扩展ASCII码? 把最 ...
- IndexError: list index out of range Python常见错误
引用超过list最大索引,此错误非常常见,注意列表的元素个数 ----------------------------------------------
- 动图:删除链表的倒数第 N 个结点
本文主要介绍一道面试中常考链表删除相关的题目,即 leetcode 19. 删除链表的倒数第 N 个结点.采用 双指针 + 动图 的方式进行剖析,供大家参考,希望对大家有所帮组. 19. 删除链表的倒 ...
- Dynamics CRM9.0更新了Chrome后菜单按钮变形
前段时间Chorme更新后Dynamics CRM9.0的系统菜单样式变的很难看 具体修改方法如下: 找到Dynamics CRM安装目录C:\Program Files\Microsoft Dyna ...
- BUAA_2021_SE_Pair_Work_#3_Review
结对项目第三阶段博客 项目 内容 这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 结对项目-第三阶段 我在这个课程的目标是 通过课程学习,完成第一个可以称之为 ...
- (十六)Struts2的标签库
一.简介 Struts2的标签库使用OGNL为基础,大大简化了数据的输出,也提供了大量标签来生成页面效果,功能非常强大. 在早期的web应用开发中,jsp页面主要使用jsp脚本来控制输出.jsp页面嵌 ...
- Leedcode算法专题训练(数学)
204. 计数质数 难度简单523 统计所有小于非负整数 n 的质数的数量. class Solution { public int countPrimes(int n) { boolean[] is ...