当前位置: 首页 > news >正文

基础 4 —— Docker 镜像的底层原理

4.1 Docker 镜像是分层的文件系统

首先我们需要明白 Docker 镜像是什么?以我们的 pull 为例,在下载的过程中我们可以看到 Docker 的镜像好像是在一层一层的在下载。

这种分层的镜像就好像分层的蛋糕。每个分层的镜像都有单独的功能,然后汇聚成一起对外暴露成一个整体的镜像。这种分层的镜像我们又称为联合文件系统 (UnionFS)。

联合文件系统 (UnionFS) 是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下 (unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(类似于 JAVA 中的 Object 类),可以制作各种具体的应用镜像。

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

4.2 Docker镜像的加载原理

bootfs (boot file system) 主要包含 bootloader 和 kernel, bootloader 主要是引导加载 kernel, Linux 刚启动时会加载 bootfs,在 Docker 镜像的最底层是引导文件系统 bootfs。这一层与我们典型的 Linux / Unix 系统是一样的,包含 boot 加载器和内核。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs。

rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs 就是各种不同的操作系统发行版,比如 Ubuntu,Centos 等等。

bootfs:包含 bootloader(引导加载程序)和 kernel(内核) 。
rootfs:root 文件系统,包含的就是典型 Linux 系统中的 /dev,/proc,/bin,/etc 等标准目录和文件。

那为什么 Docker 镜像要设计成这种分层的镜像呢?

其实就是为了复用!做到资源共享!比如我们安装 nginx 也需要 jdk 镜像。如果我们之前下载过 tomcat,tomcat 下载是需要 jdk 镜像 的。由于 jdk 镜像之前已经下载过,所以下载 nginx 镜像就不要再下载 jdk 了。

需要注意的是:Docker 镜像层都是只读的,容器层是可写的。当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

所以,所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。

4.3 Docker 镜像 commit 操作案例

基于上面的结论,我们可以对正在运行的容器进行修改,自定义一些功能,然后我们再打成新的镜像。这样新的镜像就有新的功能了。

我们运行一个 Ubuntu 镜像,我们发现在镜像里面无法使用 vim 命令,因为这个 Ubuntu 镜像只是包括了其最基本的内核命令。

[root@shjava101 ~]# docker run -it 575629a1394b /bin/bashroot@6fad0baadb12:/# vim a.txtbash: vim:commandnot found

此时我们就想给这个正在运行的容器添加 vim 功能。那应该怎么办呢?我们现在 Ubuntu 容器里面安装 vim 编辑器。

root@6fad0baadb12:/# apt-get updateroot@6fad0baadb12:/# apt-get -y install vim

安装完成以后,我们就可以在容器里面使用 vim 编辑器进行文件的编辑了。

root@6fad0baadb12:/# vim a.txtroot@6fad0baadb12:/# cat a.txthellodocker

接下来我们需要将这个运行的容器重新制作成一个带有 vim 功能的 Ubuntu 镜像。

我们使用 docker commit 命令实现。docker commit 命令的作用就是提交容器副本使之成为一个新的镜像。

语法格式:docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

我们 Ctrl + P + Q 快捷键退出到容器外部,执行命令:

[root@shjava101 ~]# docker commit -m="add vim" -a="krisswen" 6fad0baadb12 linux1:1.0

我们发现我们的镜像制作成功,并且相对于原来的 Ubuntu 镜像,大了不少,为什么?因为我们加了 vim 功能,相当于又加了一层新的镜像,所以变大了。

接下来我们运行我们自己做的镜像:

[root@shjava101 ~]# docker run -it a31aabe9e714 /bin/bashroot@c4b8c5a059f9:/# lsa.txt bin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var root@c4b8c5a059f9:/# vim b.txt

我们发现我们自己制作的镜像确实带有 vim 功能了。

总结:Docker 中的镜像分层,支持通过扩展现有镜像,创建新的镜像。类似 Java 继承于一个 Base 基础类,自己再按需扩展。

新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

http://www.jsqmd.com/news/1179397/

相关文章:

  • 遗传算法工程实战:从早熟停滞到工业部署的参数调优指南
  • 如何在Windows PC上快速配置Switch手柄:BetterJoy终极指南
  • Docker容器化实战:从零构建Web应用镜像与部署指南
  • 2026年7月最新沈阳百达翡丽官方售后客户服务热线与维修网点地址汇总 - 百达翡丽官方售后中心
  • 亲身探访杭州天梭官方售后服务中心|地址与24小时服务电话(2026年7月最新) - 天梭服务中心
  • 现代Windows C++开发实战:从Visual Studio配置到部署全流程解析
  • 打卡信奥刷题(3443)用C++实现信奥题 P10389 [蓝桥杯 2024 省 A] 成绩统计
  • 深度学习模型工作原理:从数据流动到数学直觉与工程实践
  • ET框架12条黄金法则:构建工业级Unity项目的架构与工程实践
  • 如何免费解锁网易云音乐NCM格式:3步快速转换为MP3的完整指南
  • Linux系统基础11:iptables 基本原理 新手超详细详解
  • 每日极客日报 · 2026年07月12日
  • JavaScript 时间与数学魔法:Date 与 Math 对象全攻略
  • Windows 10/11 ping 报“一般故障”:5步定位法与 3 类根因排查指南
  • 营销战略是一种实践|案例分享
  • Windows 11 LTSC企业版:老电脑焕新与系统优化全攻略
  • C/C++ HTTP服务器开发:从请求解析到高并发epoll实现
  • 劳力士中国官方售后服务中心|地址与客户服务热线权威信息声明(2026年7月最新) - 劳力士服务中心
  • 浪琴中国官方售后服务中心|服务电话与网点地址权威信息通知(2026年7月更新) - 浪琴服务中心
  • 小红书内容采集终极指南:XHS-Downloader 完整使用手册
  • kspack-rust实战教程:构建高性能网络通信数据序列化方案
  • 成都成华区跳蹬河街道亨得利官方名表服务中心电话公示(2026年7月最新) - 亨得利官方博客
  • Java 23 种设计模式:从踩坑到精通 | 状态模式 —— if-else 满天飞?让状态自己决定行为
  • 机器人学导论(第4版)核心概念精讲:从位姿描述到雅可比矩阵的5个关键公式
  • Blender3mfFormat:免费开源插件,在Blender中完整处理3MF格式的终极指南
  • 【RPA实战】我用RPA自动化半导体报表:每天2小时手工活变5分钟
  • 百达翡丽官方售后服务中心维修地址与24小时服务电话实地考察报告_多信源验证(2026年7月更新) - 百达翡丽服务中心
  • 2026海口冰块厂家Top3评测!工业降温冰块复购谁更优? - 热点咨讯
  • Windows C++轻量集成OpenAI聊天API:ChatAI-Cpp实战指南
  • pandas多维聚合实战:滚动计算与业务可解释性设计