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

Docker存储驱动之- overlay2

docker支持多种graphDriver,包括vfs、devicemapper、overlay、overlay2、aufs等等,其中最常用的就是aufs了,但随着linux内核3.18把overlay纳入其中,overlay的地位变得更重,最近也在自己的虚拟机上用overlay2作为docker存储驱动实验了一番,下面来做一个简单的笔记和总结。

docker默认的存储目录是/var/lib/docker,下面我们简单打印一下这个目录:

drwx------.  2 root root   24 Mar 28 07:13 builder
drwx------.  4 root root   92 Mar 28 07:13 buildkit
drwx------.  6 root root 4096 Mar 29 10:25 containers
drwx------.  3 root root   22 Mar 28 07:13 image
drwxr-x---.  3 root root   19 Mar 28 07:13 network
drwx------. 17 root root 4096 Mar 30 14:32 overlay2
drwx------.  4 root root   32 Mar 28 07:13 plugins
drwx------.  2 root root    6 Mar 30 14:32 runtimes
drwx------.  2 root root    6 Mar 28 07:13 swarm
drwx------.  2 root root    6 Mar 30 14:32 tmp
drwx------.  2 root root    6 Mar 28 07:13 trust
drwx------.  2 root root   25 Mar 28 07:13 volumes

在这里,我们只关心imageoverlay2就足够了。做这个实验之前,我们应该先启动一个容器,在这里使用nginx作为实验:

[root@10 docker]# docker run -d nginx
86b5733e54c7de5ef20cfb5574adedea6cbe11334517309badfbe7d313631310
[root@10 docker]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
86b5733e54c7        nginx               "nginx -g 'daemon of…"   4 seconds ago       Up 3 seconds        80/tcp              practical_vaughan

可以看到新启动的nginx容器的id是86b5733e54c7,我们继续往下看。

上面说了,我们只需要关心/var/lib/docker/image/var/lib/docker/overlay2,可以先到/var/lib/docker/image打印一下:

[root@10 image]# ll
total 0
drwx------. 5 root root 81 Mar 28 10:00 overlay2

我们只能看到overlay2这个目录,想必聪明的你也猜到了,docker在/var/lib/docker/image目录下按每个存储驱动的名字创建一个目录,如这里的overlay2。接下来,使用tree命令浏览一下这个目录:

[root@10 image]# tree -L 2 overlay2/
overlay2/
|-- distribution
|   |-- diffid-by-digest
|   `-- v2metadata-by-diffid
|-- imagedb
|   |-- content
|   `-- metadata
|-- layerdb
|   |-- mounts
|   |-- sha256
|   `-- tmp
`-- repositories.json

这里的关键地方是imagedblayerdb目录,看这个目录名字,很明显就是专门用来存储元数据的地方,那为什么区分image和layer呢?因为在docker中,image是由多个layer组合而成的,换句话就是layer是一个共享的层,可能有多个image会指向某个layer。

那如何才能确认image包含了哪些layer呢?答案就在imagedb这个目录中去找。比如上面启动的nginx容器,我们可以先找到这个容器对应的镜像:

[root@10 sha256]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
...
nginx               latest              2bcb04bdb83f        3 days ago          109MB
...

可以看到,imageID是2bcb04bdb83f,再次记住这个id,我们打印/var/lib/docker/image/overlay2/imagedb/content/sha256这个目录: 

[root@10 sha256]# ll
total 20
-rw-------. 1 root root 6025 Mar 28 09:01 2bcb04bdb83f7c5dc30f0edaca1609a716bda1c7d2244d4f5fbbdfef33da366c
-rw-------. 1 root root 1512 Mar 28 10:00 6d1ef012b5674ad8a127ecfa9b5e6f5178d171b90ee462846974177fd9bdd39f
-rw-------. 1 root root 1497 Mar 28 08:51 d8233ab899d419c58cf3634c0df54ff5d8acc28f8173f09c21df4a07229e1205
-rw-------. 1 root root 1686 Mar 28 10:00 eb426204290971fb3c7cfbf25e34308233b75080b6b3735ba5295056d915a998

第一行的2bcb04bdb83f7c5dc30f0edaca1609a716bda1c7d2244d4f5fbbdfef33da366c正是记录我们nginx镜像元数据的文件,接下来cat一下这个文件,得到一个长长的json:

......
"rootfs":{"type":"layers","diff_ids":
[
"sha256:5dacd731af1b0386ead06c8b1feff9f65d9e0bdfec032d2cd0bc03690698feda",
"sha256:dd0338cdfab32cdddd6c30efe8c89d0229d9f939e2bb736fbb0a52f27c2b0ee9",
"sha256:7e274c0effe81c48f9337879b058c729c33bd0199e28e2c55093d79398f5e8c0"
]
}}
......

只展示最关键的一部分,也就是rootfs可以看到rootfs的diff_ids是一个包含了3个元素的数组,其实这3个元素正是组成nginx镜像的3个layerID,从上往下看,就是底层到顶层,也就是说5dacd731af1b0386ead06c8b...是image的最底层。既然得到了组成这个image的所有layerID,那么我们就可以带着这些layerID去寻找对应的layer了。

接下来,我们返回到上一层的layerdb中,先打印一下这个目录:

[root@10 layerdb]# ll
total 4
drwxr-xr-x. 3 root root   78 Mar 30 14:55 mounts
drwxr-xr-x. 8 root root 4096 Mar 28 10:00 sha256
drwxr-xr-x. 2 root root    6 Mar 28 10:00 tmp

在这里我们只管mountssha256两个目录,再打印一下sha256目录:  

[root@10 sha256]# ll /var/lib/docker/image/overlay2/layerdb/sha256/
total 0
drwx------. 2 root root 85 Mar 28 09:01 166d13b0f0cb542034a2aef1c034ee2271e1d6aaee4490f749e72d1c04449c5b
drwx------. 2 root root 71 Mar 28 10:00 3fc64803ca2de7279269048fe2b8b3c73d4536448c87c32375b2639ac168a48b
drwx------. 2 root root 71 Mar 28 09:01 5dacd731af1b0386ead06c8b1feff9f65d9e0bdfec032d2cd0bc03690698feda
drwx------. 2 root root 85 Mar 28 10:00 95c536e393c4ffb38d29829c8ed21ae788832580a77436f15907bf646fe13387
drwx------. 2 root root 71 Mar 28 08:51 adab5d09ba79ecf30d3a5af58394b23a447eda7ffffe16c500ddc5ccb4c0222f
drwx------. 2 root root 85 Mar 28 09:01 dfce9ec5eeabad339cf90fce93b20f179926d5819359141e49e0006a52c066ca

在这里,我们仅仅发现5dacd731af1b038..这个最底层的layer,那么剩余两个layer为什么会没有呢?那是因为docker使用了chainID的方式去保存这些layer,简单来说就是chainID=sha256sum(H(chainID) diffid),也就是5dacd731af1b038..的上一层的sha256 id是:

echo -n "sha256:5dacd731af1b0386ead06c8b1feff9f65d9e0bdfec032d2cd0bc03690698feda sha256:dd0338cdfab32cdddd6c30efe8c89d0229d9f939e2bb736fbb0a52f27c2b0ee9" | sha256sum -
166d13b0f0cb542034a2aef1c034ee2271e1d6aaee4490f749e72d1c04449c5b  -

这个时候,你能看到166d13b...这个layer层的目录了吧?依次类推,我们就能找出所有的layerID的组合。

但是上面我们也说了,/var/lib/docker/image/overlay2/layerdb存的只是元数据,那么真实的rootfs到底存在哪里呢?其中cache-id就是我们关键所在了。我们打印一下/var/lib/docker/image/overlay2/layerdb/sha256/5dacd731af1b0386ead06c8b1feff9f65d9e0bdfec032d2cd0bc03690698feda/cache-id:

[root@10 5dacd731af1b0386ead06c8b1feff9f65d9e0bdfec032d2cd0bc03690698feda]# cat cache-id
dffe31c1db6055910b3cd49366a2989d9cd2f3460844437b2190de44807095fa[

没错,这个id就是对应/var/lib/docker/overlay2/dffe31c1db6055910b3cd49366a2989d9cd2f3460844437b2190de44807095fa。因此,以此类推,更高一层的layer对应的cache-id也能找到对应的rootfs,当这些rootfs的diff目录通过联合挂载的方式挂载到某个目录,就能完整整个容器需要的rootfs了。

 


 

 

 

 

 

 

相关文章:

Docker存储驱动之- overlay2

docker支持多种graphDriver,包括vfs、devicemapper、overlay、overlay2、aufs等等,其中最常用的就是aufs了,但随着linux内核3.18把overlay纳入其中,overlay的地位变得更重,最近也在自己的虚拟机上用overlay2作为docker…...

Vue3 shallowRef 和 shallowReactive

一、shallowRef 使用shallowRef之前需要进行引入: import { shallowRef } from vue; 使用方法和ref 的使用方法一致,以下是二者的区别: 1. 如果ref 和 shallowRef 都传入的是普通数据类型的数据,那么他们的效果是一样的&#x…...

Python数据分析实战① Python实现数据可视化

文章目录 一、数据可视化介绍二、matplotlib和pandas画图1.matplotlib简介和简单使用2.matplotlib常见作图类型3.使用pandas画图4.pandas中绘图与matplotlib结合使用 三、订单数据分析展示四、Titanic灾难数据分析显示 一、数据可视化介绍 数据可视化是指将数据放在可视环境中…...

ASP.NET 开发几个知识点

1、 皮肤设定&#xff1a; 项目右键&#xff0c;建立皮肤 app_themes 文件夹&#xff0c;右键 建立 web from 皮肤文件&#xff0c; 设定皮肤样式。全局使用皮肤 web.config 增加 <pages styleSheetTheme"Skin1" /> &#xff0c;或在 具体页面 头 增加 sty…...

企业微信H5开发遇到的坑

企业微信官方推荐wx.agentConfig引用<script src"https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>是没有效果的 必须引用以下代码才有效果&#xff0c;这也是我看了社区的回答才有所收获&#xff0c;是一个坑 且VUE引用在线的…...

mysql使用--分组查询

1.分组数据 _1.复杂的数据统计 如&#xff1a;SELECT AVG(score) FROM student_score WHERE subject ‘Mysql是怎样运行的’; 上述实现查询指定课程的平均成绩。对FROM得到的结果集1&#xff0c;通过WHER进一步过滤得到结果集2。对结果集2中每一行执行汇总计算。 _2.创建分组 …...

Android网络模块基本实现步骤

Android网络模块主要是用于访问网络和获取数据&#xff0c;下面是网络模块的基本实现步骤&#xff1a; 选择网络框架&#xff1a;Android中常用的网络框架有HttpURLConnection、OkHttp、Volley和Retrofit等。最新的版本已经支持使用Kotlin协程完成网络请求&#xff0c;可以根据…...

Rust6.2 An I/O Project: Building a Command Line Program (mini_grep)

Rust学习笔记 Rust编程语言入门教程课程笔记 参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community) Lecture 12: An I/O Project: Building a Command Line Program project: minigrep src/main.r…...

云轴科技ZStack信创云平台支撑长江航务管理局35套航运管理系统

信创是数字中国建设的重要组成部分&#xff0c;也是数字经济发展的关键推动力量。作为云基础软件企业&#xff0c;云轴科技ZStack产品矩阵全面覆盖数据中心云基础设施&#xff0c;ZStack信创云首批通过可信云《一云多芯IaaS平台能力要求》先进级&#xff0c;是其中唯一兼容四种…...

Canal+Kafka实现MySQL与Redis数据同步(一)

CanalKafka实现MySQL与Redis数据同步&#xff08;一&#xff09; 前言 在很多业务情况下&#xff0c;我们都会在系统中加入redis缓存做查询优化。 如果数据库数据发生更新&#xff0c;这时候就需要在业务代码中写一段同步更新redis的代码。 这种数据同步的代码跟业务代码糅合…...

集合的运算

集合的运算 #include <stdio.h> #include <stdlib.h> void print(int size, char arr[]) {if (size 0) {printf("null");}for (int i 0; i < size; i) {printf("%c", arr[i]);}printf("\n"); } int main() {char U[] { a,b,c,…...

在MySQL上实现间隔5分钟汇总取数及相关字符串、时间处理方法实践

1. 实践案例需求描述 查询mysql数据库&#xff0c;按每5分钟分组获取3个小时内的电量数据&#xff0c;参考SQL语句如下。 select sd.RecordTime RecordTime, sd.sddl sddl,sd.pvdl ,cap.capdl capdl from ((SELECT CONCAT(DATE_FORMAT(RecordTime,%Y-%m-%d %H:), LPAD(floor(…...

什么是AIGC

1 定义 "AIGC"代表“人工智能生成内容”&#xff08;Artificial Intelligence Generated Content&#xff09;&#xff0c;它指的是使用人工智能&#xff08;AI&#xff09;技术自动生成的内容&#xff0c;这些内容可以包括文本、图像、音乐、视频或其他多媒体形式。…...

〖大前端 - 基础入门三大核心之JS篇㊳〗- DOM访问元素节点

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;不渴望力量的哈士奇(哈哥)&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xf…...

GitHub Universe 2023:AI 技术引领软件开发创新浪潮

GitHub 是全球领先的软件开发和协作平台&#xff0c;数百万开发者和企业在此分享、学习和创建卓越的软件。同时 GitHub 处在 AI 技术前沿&#xff0c;通过其先进的 AI 技术增强开发者体验并赋能未来软件开发的使命。在今天的文章中&#xff0c;我们将一起看看在 GitHub 年度大会…...

数据结构:红黑树的插入实现(C++)

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 一、红黑树二、红黑树的插入三、代码实现总结 一、红黑树 红黑树的概念&#xff1a; 红黑树是一颗二叉搜索树&#xff0c;但在每个节点上增加一个存储位表示节点的颜色&…...

飞天使-django之数据库简介

文章目录 增删改查解决数据库不能存储中文问题创建表数据类型表的基本操作主键唯一键 unique外键实战 增删改查 四个常用的语句查询 : insert delete update select insert into student(Sno,name) values(95001,"张三") delete from student where name张三 upda…...

Flink之KeyedState

前面的文章中介绍过Operator State,这里介绍一下Keyed State. 在使用Operator State时必须要实现CheckpointFunction接口,而Keyed State则不需要,在使用keyBy(...)分组分组后,调用的函数必须是实现RichFuntion接口的函数才可以使用Keyed State.同样使用Keyed State也必须开启Ch…...

c语言:模拟实现qsort函数

qsort函数的功能&#xff1a; qsort相较于冒泡排序法&#xff0c;不仅效率更快&#xff0c;而且能够比较不同类型的元素&#xff0c;如&#xff1a;浮点数&#xff0c;结构体等等。这里我们来模拟下qsort是如何实现这一功能的&#xff0c;方便我们对指针数组有一个更深层次的理…...

从0开始学习数据结构 C语言实现 1.前篇及二分查找算法

一、前篇 1、什么是数据结构&#xff1f; 数据结构是带有结构特性的数据元素的集合&#xff0c;它研究的是数据的逻辑结构和数据的物理结构以及它们之间的相互关系 2、时间复杂度与空间复杂度 大O符号是用于描述函数渐进行为的数学符号 常用函数的增长表 阶乘O(n!) > 指数…...

Linux端口占用排查:工具与实战技巧

1. 网络端口占用排查的必要性遇到"Address already in use"错误提示时&#xff0c;每个Linux系统管理员都会心头一紧。这种端口冲突问题不仅影响服务启动&#xff0c;还可能导致关键业务中断。我刚入行时就曾因为Nginx和Apache争抢80端口&#xff0c;导致公司官网瘫痪…...

高校如何快速提升科技成果转化效率?

观点作者&#xff1a;科易网-国家科技成果转化&#xff08;厦门&#xff09;示范基地 一、现状概述&#xff1a;成效与短板 近年来&#xff0c;我国高校科技创新成果数量持续增长&#xff0c;专利授权量、论文发表量均居世界前列。然而&#xff0c;科技成果转化效率低下仍是制…...

技术赋能B端拓客:号码核验行业的迭代与价值升级

2026年&#xff0c;数字经济高质量发展进入深水区&#xff0c;B端市场的竞争逻辑已从“规模制胜”转向“效能突围”&#xff0c;拓客环节的精细化、高效化成为企业构建核心竞争力的关键。号码核验作为B端拓客的前置基础性环节&#xff0c;直接关联线索质量、人力效能与拓客投入…...

安全运维体系建设思路

安全运维体系建设思路 注意&#xff1a;后续技术分享&#xff0c;第一时间更新&#xff0c;以及更多更及时的技术资讯和学习技术资料&#xff0c;将在公众号CTO Plus发布&#xff0c;欢迎关注公众号&#xff1a;CTO Plus 关于Articulate“做一个知识和技术的搬运工。做一个终身…...

Python NumPy 使用指南:科学计算的基石

Python NumPy 使用指南&#xff1a;科学计算的基石作者&#xff1a;书到用时方恨少&#xff01; 发布日期&#xff1a;2026年4月3日 阅读时长&#xff1a;约22分钟&#x1f4cc; 前言 在 Python 数据科学和数值计算的生态系统中&#xff0c;NumPy&#xff08;Numerical Python&…...

YOLO26涨点改进| TPAMI 2026 |独家创新首发、Conv改进篇| 引入LPM 局部先验特征增强模块,更加聚焦于目标区域并抑制背景干扰,助力目标检测、图像分割、图像恢复、图像增强有效涨点

一、本文介绍 🔥本文给大家介绍使用 LPM 局部先验特征增强模块 改进YOLO26网络模型,通过构建重要性图对特征提取过程进行引导,使模型能够更加聚焦于目标区域并抑制背景干扰,从而提升特征表达质量和目标区分能力。其优势体现在能够有效增强关键区域信息、提升小目标和复杂…...

递推限幅消抖数字滤波函数的实现(C 语言,嵌入式 / Keil 通用)

前言在嵌入式系统、传感器采样、工业数据采集场景中&#xff0c;瞬时尖峰、随机野值、信号抖动是最常见的干扰问题。直接使用原始数据极易导致控制误判、显示跳变、系统异常。本文介绍一种轻量、高效、鲁棒性极强的递推限幅 连续消抖数字滤波算法&#xff0c;不占用大量 RAM、…...

RHCSA 认证必备:目录文件的管理

目录 一、创建目录 &#xff08;1&#xff09;格式 &#xff08;2&#xff09;参数 &#xff08;3&#xff09;示例 二、查看目录文件 1、查看目录文件 2、统计命令 3、编辑与删除 a.编辑目录文件 b.删除目录文件 一、创建目录 &#xff08;1&#xff09;格式 mkdi…...

温度场与锂枝晶生长的相场电势场及浓度场耦合仿真研究

comsol 锂枝晶仿真——耦合温度场 在相场&#xff0c;电势场和浓度场的基础上耦合了温度场&#xff0c;可以看不同温度对锂枝晶的影响指尖的金属晶体在电解液中野蛮生长&#xff0c;就像寒冬玻璃上的冰花。当我们盯着显微镜观察锂枝晶时&#xff0c;常忽略了一个重要变量——温…...

用OpenPCDet跑通Nuscenes-mini:小显存福音与多模态数据处理的实战笔记

用OpenPCDet跑通Nuscenes-mini&#xff1a;小显存福音与多模态数据处理的实战笔记 在3D目标检测领域&#xff0c;Nuscenes数据集因其丰富的多模态数据&#xff08;LiDAR、摄像头、雷达&#xff09;和复杂的城市场景而备受研究者青睐。但对于大多数个人开发者和学生来说&#x…...