全网讲的最详细的Docker镜像分层存储原理

先说结论,容器镜像分层存储图示
在这里插入图片描述
欢迎关注
在这里插入图片描述

实验环境准备

当前实验docker版本24.0.7如下,当前docker版本使用overlay2机制存储镜像

Client: Docker Engine - Community
 Version:           24.0.7
 API version:       1.43
 Go version:        go1.20.10
 Git commit:        afdd53b
 Built:             Thu Oct 26 09:07:41 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.7
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.10
  Git commit:       311b9ff
  Built:            Thu Oct 26 09:07:41 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.25
  GitCommit:        d8f198a4ed8892c764191ef7b3b06d8a2eeb5c7f
 runc:
  Version:          1.1.10
  GitCommit:        v1.1.10-0-g18a0cb0
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
$ sudo docker pull httpd
Using default tag: latest
latest: Pulling from library/httpd
1f7ce2fa46ab: Pull complete 
424de2a10000: Pull complete 
6d9a0131505f: Pull complete 
5728e491734b: Pull complete 
20d3235e84ad: Pull complete 
Digest: sha256:04551bc91cc03314eaab20d23609339aebe2ae694fc2e337d0afad429ec22c5a
Status: Downloaded newer image for httpd:latest
docker.io/library/httpd:latest
# sudo docker image inspect httpd
		"Id": "sha256:a6ca7b52a41549f13f7de6aeac4ab6ffebd41585fbf2273f00fd6e82bb721949",
        "RepoTags": [
            "httpd:latest"
        ],
        "RepoDigests": [
            "httpd@sha256:04551bc91cc03314eaab20d23609339aebe2ae694fc2e337d0afad429ec22c5a"
        ],
		"GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/766833b310bfa8245d270ce831a9e73ab27e5e0f61525d108ef519e4868f9cfb/diff:/var/lib/docker/overlay2/76c5547a9f06e06ba12ae92f54211a9c4397bc6c002e3a81aa4a4d7903f451c2/diff:/var/lib/docker/overlay2/aab89c771d1be31e61bce7d83df529043b1b0cd4283ed1d9275a97617c114743/diff:/var/lib/docker/overlay2/32b5b0acbd61d9bbfb362d26d450e6412bfa6749677acf0694f32930e82432b2/diff",
                "MergedDir": "/var/lib/docker/overlay2/88aaff0c6f4e196d1a79386b30b9460a2603824b6ebb9efacdfd1fd11000477f/merged",
                "UpperDir": "/var/lib/docker/overlay2/88aaff0c6f4e196d1a79386b30b9460a2603824b6ebb9efacdfd1fd11000477f/diff",
                "WorkDir": "/var/lib/docker/overlay2/88aaff0c6f4e196d1a79386b30b9460a2603824b6ebb9efacdfd1fd11000477f/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:92770f546e065c4942829b1f0d7d1f02c2eb1e6acf0d1bc08ef0bf6be4972839",
                "sha256:fad7e2250d8fefbd8524054837403921b468448b6bae1ee439bb793e254b6725",
                "sha256:27496babc700a08c0a14777dd4bb818273e8cc9f77d526fcb4554043cff291d9",
                "sha256:28f18e7dc61c56a068f00ec92dde62cf9de21cbce0eb9a8395c6617e2fef9463",
                "sha256:b9bf93af811f6900f445158ab648fd4868b69b770908142b897772e6bb8c2a2f"
            ]
        }

overlay2文件系统

overlayfs通过三个目录来实现:lower目录、upper目录、以及work目录。三种目录合并出来的目录称为merged目录

  • lower目录:可以是多个,是处于最底层的目录,作为只读层
  • upper目录:只有一个,作为读写层
  • work目录:为工作基础目录,挂载后内容会被清空,且在使用过程中其内容用户不可见
  • merged目录:为最后联合挂载完成给用户呈现的统一视图,也就是说merged目录里面本身并没有任何实体文件,给我们展示的只是参与联合挂载的目录里面文件而已,真正的文件还是在lower和upper中。所以,在merged目录下编辑文件,或者直接编辑lower或upper目录里面的文件都会影响到merged里面的视图展示。

docker image inspect httpd的结果中LowerDir的值是实际存储文件系统数据的目录

MergedDir,UpperDir,WorkDir也都是放在/var/lib/docker/overlay2/目录下

上面inspect命令结果中"Id": "sha256:a6ca7b52a41549f13f7de6aeac4ab6ffebd41585fbf2273f00fd6e82bb721949",,这一部分其实就是repository元数据,用于找到镜像image元数据/var/lib/docker/image/overlay2/imagedb/content/sha256(Id值)/

上面inspect命令结果中RootFSLayerslayer元数据,其中的每个sha256的值就是diff_id

docker镜像分层存储原理

docker镜像的元数据分为repository,image,layer三部分

由于docker镜像分层存储,所以repositoryimage没有对应的物理镜像文件,而每个layer元数据都有具体的物理镜像层文件与之对应,

并且layer元数据和镜像文件分开存储,二者基于内容寻址(即基于文件内容索引镜像和镜像层)存储机制进行关联

repository元数据

repository是某个镜像所有迭代版本的集合,它在本地的持久化信息就存储在/var/lib/docker/image/overlay2/repositories.json中,其中记录了所有repository的名字以及每个repository中所有版本镜像的名字。

这里的sh256的值和docker pull时的sha256值一样

root@ubuntu20:/var/lib/docker/image/overlay2# cat repositories.json 
{"Repositories":{
    "httpd":{
        "httpd:latest":"sha256:a6ca7b52a41549f13f7de6aeac4ab6ffebd41585fbf2273f00fd6e82bb721949",
        "httpd@sha256:04551bc91cc03314eaab20d23609339aebe2ae694fc2e337d0afad429ec22c5a":"sha256:a6ca7b52a41549f13f7de6aeac4ab6ffebd41585fbf2273f00fd6e82bb721949"
    }
}}

image元数据

image元数据的本地文件位于/var/lib/docker/image/overlay2/imagedb/content/sha256/,包括以下信息:镜像架构、操作系统、镜像配置、Docker版本和镜像层信息rootfs。

其中rootfs包含该镜像所有镜像层的id,即diff_id。其中的diff_ids从上到下依次为nginx镜像底层到顶层的diff_id

镜像层的id为diff_id

# cat /var/lib/docker/image/overlay2/imagedb/content/sha256/a6ca7b52a41549f13f7de6aeac4ab6ffebd41585fbf2273f00fd6e82bb721949
.....
"rootfs":{
    "type":"layers","diff_ids":[
        "sha256:92770f546e065c4942829b1f0d7d1f02c2eb1e6acf0d1bc08ef0bf6be4972839",
        "sha256:fad7e2250d8fefbd8524054837403921b468448b6bae1ee439bb793e254b6725",
        "sha256:27496babc700a08c0a14777dd4bb818273e8cc9f77d526fcb4554043cff291d9",
        "sha256:28f18e7dc61c56a068f00ec92dde62cf9de21cbce0eb9a8395c6617e2fef9463",
        "sha256:b9bf93af811f6900f445158ab648fd4868b69b770908142b897772e6bb8c2a2f"
    ]
}

layer元数据

用户拉取了某个镜像层后,Docker会基于该镜像层的文件和image元数据生成layer元数据,

主要包括该镜像层的diff_id(diff),如果该镜像层没有父镜像层,那么该层的diff_id就是chain_id

父镜像层的chain_id(parent)

该镜像层的大小(size)、

镜像层文件的索引(cache-id)等,

这些元数据存储在 /var/lib/docker/image/overlay2/layerdb/sha256/路径下

root@ubuntu20:/var/lib/docker/image/overlay2/layerdb/sha256# tree -L 2
.   
├── 16d494768121f45ba050ad50a669400818478131cb930bb0c8b5d2f908057142
│   ├── cache-id
│   ├── diff
│   ├── parent
│   ├── size
│   └── tar-split.json.gz
├── 29b181ca372e770053cc03410789236d7a96171f1f77110741d0f3f068a29c67
│   ├── cache-id
│   ├── diff
│   ├── parent
│   ├── size
│   └── tar-split.json.gz
├── 92770f546e065c4942829b1f0d7d1f02c2eb1e6acf0d1bc08ef0bf6be4972839
│   ├── cache-id
│   ├── diff
│   ├── size
│   └── tar-split.json.gz
├── cdfabdae5172d05eb5141bb77aaa300a195570b0befd780b6e2fc7bd20ea2cd5
│   ├── cache-id
│   ├── diff
│   ├── parent
│   ├── size
│   └── tar-split.json.gz
└── e8254408730a345e2ccf863e19c850e7ee78b59dfd9e4aa265b0107dd4301be5
    ├── cache-id
    ├── diff
    ├── parent
    ├── size
    └── tar-split.json.gz   

cache-id是Docker随机生成的UUID,用于标识和索引具体的镜像文件;

chainIDimage元数据与layer元数据关联的索引ID,根据当前层的diffID和父镜像层的chainID得来,具体计算方法如下:

  • 如果该镜像层是最底层(没有父镜像层),该层的 diff_id 便是 chain_id。
  • 该镜像层的 chain_id 计算公式为 chainID=sha256(父层chain_id+" "+本层diff_id),也就是根据父镜像层的 chain_id 加上一个空格和当前层的 diff_id,再计算 SHA256 校验码。

镜像文件存储目录

镜像层元数据与镜像层文件分开存储,并通过cache-id(overlay2目录下的文件夹的名字)进行关联。具体的镜像层文件存储在/var/lib/docker/overlay2文件夹下

root@ubuntu20:/var/lib/docker/overlay2# tree -L 2
.
├── 32b5b0acbd61d9bbfb362d26d450e6412bfa6749677acf0694f32930e82432b2
│   ├── committed
│   ├── diff
│   └── link
├── 766833b310bfa8245d270ce831a9e73ab27e5e0f61525d108ef519e4868f9cfb
│   ├── committed
│   ├── diff
│   ├── link
│   ├── lower
│   └── work
├── 76c5547a9f06e06ba12ae92f54211a9c4397bc6c002e3a81aa4a4d7903f451c2
│   ├── committed
│   ├── diff
│   ├── link
│   ├── lower
│   └── work
├── 88aaff0c6f4e196d1a79386b30b9460a2603824b6ebb9efacdfd1fd11000477f
│   ├── diff
│   ├── link
│   ├── lower
│   └── work
├── aab89c771d1be31e61bce7d83df529043b1b0cd4283ed1d9275a97617c114743
│   ├── committed
│   ├── diff
│   ├── link
│   ├── lower
│   └── work
└── l
    ├── J6BYBF6ADSYX4HKH65NQSXLNAD -> ../76c5547a9f06e06ba12ae92f54211a9c4397bc6c002e3a81aa4a4d7903f451c2/diff
    ├── L2DROY4Y7V2ZGUIOFOLSARZO3T -> ../aab89c771d1be31e61bce7d83df529043b1b0cd4283ed1d9275a97617c114743/diff
    ├── U2HWCDVI7VIS6QKAUANBZSIC4L -> ../32b5b0acbd61d9bbfb362d26d450e6412bfa6749677acf0694f32930e82432b2/diff
    ├── V2RW2JJO2BYNGIFOMQJ74TF5C3 -> ../766833b310bfa8245d270ce831a9e73ab27e5e0f61525d108ef519e4868f9cfb/diff
    └── WUF77DAMALFDYBOPZYWKS7WOIG -> ../88aaff0c6f4e196d1a79386b30b9460a2603824b6ebb9efacdfd1fd11000477f/diff

子目录l记录了很多长26位的软连接,指向本地缓存目录下的diff目录。(容器运行时会用到,具体参见文章开头的链接)

其他7个子目录是镜像层的目录,代表Nginx镜像共有7个镜像层,每个镜像层目录都由一串UUID命名,这个UUID即layer元数据部分介绍的cache-id,用于将镜像元数据和镜像文件关联起来。

其中diff目录保存了镜像层的实际内容;

link保存了当前镜像层的短ID,与 l目录互为引用;

lower目录保存了当前镜像层的所有父镜像层的短ID集合,用于挂载时直接读取;

work目录为overlay2驱动的写时复制目录。

镜像索引关系

repositories.json文件存储了repository元数据,其中包括imageID

imageID可以索引到image元数据,其中包括该镜像每层的 ID,即 diff_id

根据当前层diff_id和父镜像层的chainID可以计算出当前层的chainID,就可以索引到当前层的layer元数据;

当前层的layer元数据文件夹下包括cacheID,从而索引到存储在/var/lib/docker/overlay2路径下的镜像文件存储数据。

/var/lib/docker/
				/overlay2/	# 存放实际的镜像或容器文件
 			/image/overlay2/
     						distribution/
         					imagedb/		# image元数据
             						content/sha256/	# image元数据
                 					metadata/	
             				layerdb/		# layer元数据
                 					mounts/	# 运行的容器的挂载元数据
                     				sha256/	# layer元数据
                 			repositories.json	# repository元数据

在这里插入图片描述

容器启动

⼀个容器完整的层应由三个部分组成

  • 镜像层:也称为rootfs,提供容器启动的⽂件系统。镜像层属于roLayer
  • init层:⽤于修改容器中⼀些⽂件如/etc/hostname,/etc/hosts,/etc/resolv.conf等。init层属于mountedLayer
  • 容器层:使⽤联合挂载统⼀给⽤⼾提供的可读写⽬录。容器层属于mountedLayer

启动容器时会在/var/lib/docker/image/overlay2/layerdb/mounts/下创建container_id文件夹,其中包括

  • mount-id:存储在/var/lib/docker/overlay2/(镜像文件存储目录)的⽬录名称。(容器层,联合挂载⽽来,mount到docker/overlay2/⽬录下)
  • init-id:initID是在mountID后加了⼀个-init,同时initID就是存储 在/var/lib/docker/overlay2/的⽬录名称。
  • parent:容器所基于的镜像的最上层的chain_id。

多架构下的镜像信息

可以使用 docker manifest inspect $image 命令来查看,manifest为docker的体验特性,在Linux系统下开启

最好的方式为开启docker daemon的特性,修改 /etc/docker/daemon.json 文件

{
  "experimental": true
}

配置镜像加速时配置阿里镜像地址也是通过这个文件来做的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/651616.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8+PyQt5西红柿成熟度检测系统完整资源集合(yolov8模型,从图像、视频和摄像头三种路径识别检测,包含登陆页面、注册页面和检测页面)

西红柿成熟度检测(https://mbd.pub/o/bread/mbd-ZpWbk5ly)_哔哩哔哩_bilibili 资源包含可视化的西红柿成熟度检测系统,基于最新的YOLOv8训练的西红柿成熟度检测模型,和基于PyQt5制作的可视化西红柿成熟度检测系统,包含…

系统思考—战略沙盘推演咨询服务

今日与JSTO团队一起学习了《战略沙盘推演咨询服务》。通过沙盘体验,我深刻感受到组织与战略就像一张皮的正反两面。在转型过程中,即使战略非常明确,团队成员由于恐惧和顾虑,往往不愿意挑战新的业务,从而难以实现战略目…

创新实训2024.05.28日志:记忆化机制、基于MTPE与CoT技术的混合LLM对话机制

1. 带有记忆的会话 1.1. 查询会话历史记录 在利用大模型自身能力进行对话与解答时,最好对用户当前会话的历史记录进行还原,大模型能够更好地联系上下文进行解答。 在langchain chat chat的chat函数中,通过实现langchain框架提供的ChatMemo…

虚拟化技术 分布式资源调度

一、实验内容 实现分布式资源调度 二、实验主要仪器设备及材料 安装有64位Windows操作系统的台式电脑或笔记本电脑,建议4C8G或以上配置已安装VMware Workstation Pro已安装Windows Server 2008 R2 x64已安装vCenter Server 三、实验步骤 将主机esxi1和esxi2加入…

【找出缺失的观测数据】python

思路: 主要在于分配剩余的部分分配问题 代码: class Solution:def missingRolls(self, rolls: List[int], mean: int, n: int) -> List[int]:m len(rolls)total_sum (n m) * meantoset total_sum - sum(rolls)# 检查 toset 是否在可能的范围内i…

R可视化:可发表的prism点图

介绍 可发表的prism点图 加载R包 knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE) library(tidyverse) library(ggpubr) library(ggprism)rm(list = ls()) options(stringsAsFactors = F)导入数据 data("iris")head(iris)处理数据 plotd…

git stash 命令

线上版本出现了bug,我们应该放下手头上的开发工作先将线上的bug修复,这个时候dev分支下的改动怎么处理? 是向分支行上提交代码还是直接切换到master分支下? 首先我们的开发工作还未完成,就把代码提交到分支上&#xf…

安装ROS 2 Jazzy Jalisco

参考: https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debians.html 先要安装一个ubuntu,对老旧硬件最友好的版本Lubuntu: 安装Lubuntu24.04-CSDN博客 过程: 按文档一步步走下去: 遇到问题查找通用案…

(三)MobaXterm、VSCode、Pycharm ssh连接服务器并使用

背景:根据前两篇文章操作完成后, 手把手教学,一站式安装ubuntu及配置服务器-CSDN博客 手把手教学,一站式教你实现服务器(Ubuntu)Anaconda多用户共享-CSDN博客 课题组成员每人都有自己的帐号了&#xff0…

linux文件编程api: creat

1.基本信息 功能 创建新文件 头文件 #include<fcntl.h> 函数形式 int creat(const char *pathname, mode_t mode); 返回值 如果成功&#xff0c;则返回文件描述符号 如果失败&#xff0c;则返回-1 参数 pathname: 创建的文件名 mode: 新建文件时&#xff0c;文件权限…

企业微信hook接口协议,ipad协议http,已读消息

已读消息 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信send_userid是long要发送的人idisRoom是bool是否是群消息 请求示例 {"uuid":"1753cdff-0501-42fe-bb5a-2a4b9629f7fb","send_userid":788130255…

C++入门3——类与对象(2)

1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。可是空类中真的什么都没有吗&#xff1f; 其实并不是的&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&#xf…

《Java数据结构》--单链表详解

一.单链表的概念 1.概念 单链表是一种物理存储结构是非连续&#xff0c;非线性的但是在逻辑结构上是连续且线性的&#xff0c;链表是通过一个个结点来实现的&#xff0c;使每个相邻结点之间存在一定关系来将所有结点串起来&#xff0c;在物理存储上像是一条链子。 2.链表的原…

《Ai企业知识库》-rasa X安装使用

背景&#xff1a; Rasa X 是一个为构建、改进和管理对话式AI助手而设计的工具。它是Rasa开源机器学习框架的一个扩展&#xff0c;旨在实现“对话驱动开发”&#xff08;Conversation-Driven Development&#xff09;。Rasa X 主要特点包括&#xff1a; 交互式学习&#xff1a;…

二叉树的实现(递归实现)

前言&#xff1a;本文讲解通过递归的方式实现二叉树的一些基本接口。 目录 通过左右子树的方式实现二叉树&#xff1a; 二叉树的遍历&#xff1a; 求二叉树结点的个数&#xff1a; 二叉树所有节点的个数&#xff1a; 二叉树叶子节点的个数&#xff1a; 求第k层节点的节点…

传输层安全性 (TLS)

传输层安全 (TLS) 旨在提供传输层的安全性。TLS 源自称为安全套接字层 (SSL)的安全协议。 TLS 确保任何第三方都无法窃听或篡改任何消息。 TLS 有几个好处&#xff1a; ● 加密&#xff1a; TLS/SSL 可以帮助使用加密来保护传输的数据。 ● 互操作性&#xff1a; TLS/S…

PHP框架 Laravel

现在因为公司需求&#xff0c;需要新开一个Laravel框架的项目&#xff0c;毫无疑问&#xff0c;我又被借调过去了&#xff0c;最近老是被借调&#xff0c;有点阴郁&#xff0c;不过反观来看&#xff0c;这也是好事&#xff0c;又可以复习和巩固一下自己的知识点&#xff0c;接下…

第八大奇迹

目录 题目描述 输入描述 输出描述 输入输出样例 示例 输入 输出 运行限制 原题链接 代码思路 题目描述 在一条 R 河流域&#xff0c;繁衍着一个古老的名族 Z。他们世代沿河而居&#xff0c;也在河边发展出了璀璨的文明。 Z 族在 R 河沿岸修建了很多建筑&#xff0c…

[Algorithm][动态规划][简单多状态DP问题][买卖股票的最佳时机 III][买卖股票的最佳时机 Ⅳ]详细讲解

目录 1.买卖股票的最佳时机 III1.题目链接2.算法原理详解3.代码实现 2.买卖股票的最佳时机 IV1.题目链接2.算法原理详解3.代码实现 1.买卖股票的最佳时机 III 1.题目链接 买卖股票的最佳时机 III 2.算法原理详解 注意&#xff1a;本题为了便于初始化&#xff0c;有较多细节服…

Java之Writer类:探索Java中的输出流

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…