Docker--镜像分层与镜像摘要

镜像分层

Docker 镜像由一些松耦合得只读镜像层组成,Docker Daemon 负责堆叠这些镜像层,并将他们管理为一个整体,对外表现出得是一个独立得对象。

docker pull 拉取镜像时,每个pull complete 行就代表下载了一个镜像层,比如:

无标题

无2标题

为什么分层

分层得优势有:

  1. 每个分层只读,对分层得修改都是以新分层得形式出现,不会破坏原分层内容
  2. 每个分层只记录变更内容,所以节省空间
  3. 不同镜像间实现资源共享,即不同镜像对相同下层镜像得复用。

docker pull 在拉取之前会先获取要拉取镜像的所有imageID,然后再本地查找这些分层。如果存在,不再拉取,而是共享本地的分层,节省了空间和网络带宽。提高了拉取效率。

镜像层构成

每个镜像层由两部分构成:镜像文件系统和镜像json文件。他们具有相同的imageID。

镜像文件系统:拥有镜像所有镜像层的数据内容。

镜像json文件:描述镜像相关属性的集合,通过docker inspect 【镜像】可以查看。

镜像FS构成

docker镜像文件系统FS 由多个只读的镜像层组成,每层都有特定的功能。

这些只读镜像层根据位置与功能不同可分为两类:基础镜像层和扩展镜像层

无标3题

基础镜像层

所有镜像的最下层都有一个看得到的基础镜像层Base Image,基础镜像层的文件系统称为根文件系统rootfs。

而rootfs 是建立在Linux中“看不到的”引导文件系统bootfs 之上。

扩展镜像层

在基础镜像层之上的镜像层称为扩展镜像层,是对基础镜像层功能的扩展。

在Dockerfile 中。每条指令都是用于完成特定功能,而每个指令都会生产一个扩展镜像层。

容器层

无标4题

镜像运行起来就成了容器,而容器也具有文件系统。

容器的文件系统在docker镜像最外层之上增加了一个可读写的容器层

对文件的任何更改只存在于容器层,因此不会影响镜像本身。

容器要修改某个文件,会从容器层开始向下一层层的查找,直到找到为止,对文件的操作都会记录在容器层。

比如:要修改某个文件,容器层会在镜像层找到文件并copy到容器层,然后再进行修改。删除文件也只会将容器层中的文件副本删除。

可以看出,Docker容器就是一个叠加后的文件系统,这个容器层称为Union FIle System 联合文件系统。

Linux OS 启动过程

无标5题

微内核架构分为内核(Server)和服务模块(Client)。

LInux 的bootfs 由两部分组成:bootloader 和kernel

各个容器中的rootfs 就是由宿主机的kernel驱动的。

无6标题

镜像摘要(digest)

每个镜像都有一个长度为64位的16禁止字符串作为其摘要digest。

#查看摘要 方式一
docker inspect zookeeper:latest
# 查看摘要方式二
docker images zookeeper --digest

摘要是什么

摘要(digest) 是镜像内容的一Hash值,即所谓的Content Hash,只要镜像内容发生变化,其内容散列值就会改变。

默认的Hash算法是sha256

摘要的作用

区分相同<repository>:<tag>的不同镜像。

比如:镜像xxx:2.8 在运行中发现bug,然后进行了修复,然后使用原标签将其push回仓库,原镜像被覆盖。

但是生产环境中海油运行中未修复的镜像容器。此时标签无法区分镜像是修复前还是修复后,这时就只能查看digest 。

分发散列值

在push或pull时,都会对镜像进行压缩以减少网络带宽。但压缩会改变镜像内容,导致传输后与digest不符合。

为了解决这个问题,Docker 为镜像配置了Distribution Hash(分发散列值)。在镜像压缩后计算分发散列值,然后随镜像一同发生。接受方拿到后,立即计算压缩后镜像的分发散列值,与携带的分发散列值对比。如果相同,则传输没问题。

多架构镜像

Multi-architecture Image 多架构镜像,是某个镜像针对不同操作系统/系统架构 的不同镜像实现。

即镜像的<repository>:<tag>是相同的,但是针对的操作系统/系统架构不同。

多架构镜像原理

无论用户使用的是什么操作系统,通过docker pull 拉去到的一定是针对该操作系统的镜像,用户无需考虑操作系统问题。

Docker Hub能根据pull请求自动选择对应的镜像。

无7标题

镜像的多架构信息保存在Mainifest 文件中。

拉取镜像时,pull命令将OS与架构信息一并提交给Docker Hub。

Docker Hub根据<repository>:<tag>查找Manifest。如果不存在,直接查找并返回镜像。

如果存在。会根据Manifest 中记录的地址找到该镜像的位置。

posted @ 2026-05-27 08:46  NE_STOP  阅读(67)  评论(0)    收藏  举报