Docker 底层原理- 镜像分层和联合文件系统(了解)

文章目录

  • [1. 镜像分层设计](#1. 镜像分层设计)
  • [2. 联合文件系统](#2. 联合文件系统)
  • 3.容器,镜像,命名空间串联:
    • [Docker 镜像成为容器的根文件系统步骤:](#Docker 镜像成为容器的根文件系统步骤:)
    • 过程分解
      • [1️⃣ 镜像本身是"只读层"的堆叠](#1️⃣ 镜像本身是“只读层”的堆叠)
      • [2️⃣ 创建容器时,Docker 构建"联合挂载"](#2️⃣ 创建容器时,Docker 构建“联合挂载”)
      • [3️⃣ 通过 Mount Namespace 隔离这个挂载视图](#3️⃣ 通过 Mount Namespace 隔离这个挂载视图)
      • 示意图:
    • 【小记】
  • 总结

✨✨✨学习的道路很枯燥,希望我们能并肩走下来!

编程真是一件很奇妙的东西。你只是浅尝辄止,那么只会觉得枯燥乏味,像对待任务似的应付它。但你如果深入探索,就会发现其中的奇妙,了解许多所不知道的原理。知识的力量让你沉醉,甘愿深陷其中并发现宝藏。



本文开始

1. 镜像分层设计

分层设计:每个镜像都是由多个只读层组成的,每一层都可以复用。

分层设计作用:编写 docker 时可以利用分层缓存的特点加速镜像开发的过程。

  1. Docker镜像都起始于一个基础镜像层,新镜像是从 base 镜像一层一层叠加生成的。
  2. 当进行修改或增加新的内容时,就会在当前镜像层上,创建新的镜像层。

示例:在dockerfile中修改RUN指令

下述每个RUN指令都相当于一层,除了第一次运行外,以后每次运行创建镜像命令都会复用缓存;

创建镜像命令:

bash 复制代码
# 运行下述指令,相当于创建一个tmp镜像,
# 会在当前dockerfile目录下执行dockerfile文件中的命令
# 相当于执行dockerfile这个脚本
docker build -t tmp:v1.0 .

指令少时(7-8个):考虑每个RUN指令指定yum 命令

指令多时:需要考虑一个RUN指令组合多个命令

组合方式: 每个命令使用 / && 连接

bash 复制代码
# 一行RUN命令,包含多个
RUN yum install -y wget vim \
	&& yum install -y vim wget \
	&& yum install -y wget vim git \
	&& tar xvf apache-xx-bin.tar.gz \
	&& ssh xxxx \
	&& chomd 600 xxx 

缓存复用设计

指令有缓存,在docekrfile文件中体现就是:

每个RUN 指令就是一层

除了第一次运行,每次运行会判断指令是否是之前有的,有就会复用之前的缓存;

2. 联合文件系统

视图层:用户登录后看到的,可以看到多个目录,也就是容器和多个镜像;

容器层:赋予读写权限

镜像层:只有只读权限

联合文件系统只会给-容器层赋予-读写权限,其他目录-镜像层-赋予只读权限

【注】

1.在视图层修改容器层东西,会在容器中同样修改

2.在视图层修改镜像层东西,会在容器层中保存对某个镜像操作的记录,不会真的在镜像中体现;(如:B更改xx)

3.容器,镜像,命名空间串联:

Docker 利用 Linux 的 Mount Namespace + 联合文件系统(如 overlay2),将镜像的多层只读文件系统与一个可写层组合,挂载为容器的根目录 / 。

Docker 镜像成为容器的根文件系统步骤:

  1. 使用 联合文件系统(如 overlay2) 将镜像只读层 + 容器可写层合并;
  2. 在新建的 Mount Namespace (命名空间)中,将这个合并后的文件系统 挂载到 / -根目录;
  3. 容器进程在这个隔离的命名空间中运行,看到的就是完整的、可写的根目录

过程分解

1️⃣ 镜像本身是"只读层"的堆叠

  • Docker 镜像由多个 只读层(layers) 组成(例如:基础 OS 层 + Python 层 + 应用代码层)。
  • 这些层存储在宿主机的 /var/lib/docker/overlay2/... 目录中

2️⃣ 创建容器时,Docker 构建"联合挂载"

  • 启动容器时,Docker 会
    • 创建一个新的 可写层(container layer)(也叫 upper layer)
    • 使用 联合文件系统(UnionFS)(如 overlay2)将:
      • 所有镜像只读层(lower layers)
      • 容器可写层(upper layer)
    • 合并挂载成一个统一的视图。

3️⃣ 通过 Mount Namespace 隔离这个挂载视图

创建新的命名空间,在新的命名空间中会将镜像只读层和容器可写层合并挂载到容器根目录 / 上;

结果:容器内的进程看到的 / 就是这个由镜像 + 可写层组成的文件系统,与宿主机和其他容器完全隔离。

示意图:

html 复制代码
宿主机文件系统
│
├── /var/lib/docker/overlay2/(多层镜像)
│   ├── abc... (镜像层1: ubuntu)
│   ├── def... (镜像层2: python)
│   └── xyz... (镜像层3: app code)  ← 只读
│
└── 容器启动时:
     ├── 创建可写层: container-writable/
     └── 使用 overlay2 联合挂载:
          lowerdir(只读层)=abc:def:xyz
          upperdir(可写层)=container-writable
          merged → 挂载为容器的 / (根目录)

【小记】

1.docker镜像是一堆目录和文件
2.容器就是不同命名空间的进程
3.镜像会通过Mount namespace(命名空间)挂载到容器上rootfs上


总结

✨✨✨各位读友,本篇分享到内容是否更好的帮助你理解,如果对你有帮助给个👍赞鼓励一下吧!!
🎉🎉🎉世上没有绝望的处境,只有对处境绝望的人。
🎉🎉🎉一遇挫折就灰心丧气的人,永远是个失败者。而一向努力奋斗,坚韧不拔的人会走向成功。
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!

相关推荐
i建模2 小时前
在 Rocky Linux 上安装轻量级的 XFCE 桌面
linux·运维·服务器
Data_Journal3 小时前
Scrapy vs. Crawlee —— 哪个更好?!
运维·人工智能·爬虫·媒体·社媒营销
3 小时前
java关于内部类
java·开发语言
好好沉淀3 小时前
Java 项目中的 .idea 与 target 文件夹
java·开发语言·intellij-idea
gusijin3 小时前
解决idea启动报错java: OutOfMemoryError: insufficient memory
java·ide·intellij-idea
To Be Clean Coder3 小时前
【Spring源码】createBean如何寻找构造器(二)——单参数构造器的场景
java·后端·spring
吨~吨~吨~3 小时前
解决 IntelliJ IDEA 运行时“命令行过长”问题:使用 JAR
java·ide·intellij-idea
你才是臭弟弟3 小时前
SpringBoot 集成MinIo(根据上传文件.后缀自动归类)
java·spring boot·后端
短剑重铸之日3 小时前
《设计模式》第二篇:单例模式
java·单例模式·设计模式·懒汉式·恶汉式
YMWM_3 小时前
不同局域网下登录ubuntu主机
linux·运维·ubuntu