Docker:存储原理

Docker:存储原理

    • 镜像
      • 联合文件系统
      • overlay
      • 镜像存储结构
      • 容器存储结构
    • 存储卷
      • 绑定挂载
      • 存储卷结构


镜像

联合文件系统

联合文件系统Union File System是一种分层,轻量且高效的文件系统。其将整个文件系统分为多个层,层与层之间进行覆盖,并对外表现为一个一致的文件系统。

在这里插入图片描述

上图有三种操作,A(add)表示新建文件,C(change)表示修改文件,D(delete)表示删除文件。这个文件系统分为三层,但是对外用户只能看到红色这一层。

比如a.txt,在第二层就被删除了,那么用户看不到这个文件,但是其实这个文件依然被存储在文件系统的第一层中。删除文件只是一种标记,表示上层不可见,不会真的删除文件

再比如b.txt,在第一层创建,在第二层修改,那么第二层的内容就会覆盖掉第一层的内容,用户看到第二层的内容。但是对于b.txt,其实保存了两份在文件系统中,第一份在第一层,第二份在第二层。

在红色层,其实是没有存储任何具体的文件的,而是存储了大量文件的引用。比如访问c.txt,其实访问到的是第二层中的文件,其并没有把文件系统内部的文件再进行一次拷贝。但是如果用户要修改文件,此时触发写时拷贝,那么会把该文件拷贝一份到当前层,然后再修改。比如b.txt在第二层进行了修改,其实就是把第一层的文件拷贝一份到第二层,然后再进行修改。所以先前才说b.txt在文件系统中保存了两份。


overlay

overlay是联合文件系统的一种具体实现,其也是Docker采用的联合系统方案。

在这里插入图片描述

overlay采用三层结构,每一层由一个目录管理。从下往上依次是:

  • lowerdir:最底层,内部的所有文件都是只读文件
  • upperdir:中间层,可以读写,可以在该层创建,删除,修改文件
  • merged:最顶层,也就是用户所看到的层,其基于前两层提供一个统一的视图

除去这三个层,还有一个workdir层,这层并不展示给用户,当upperdir层要修改文件时,会先在workdir层进行修改,只有操作完成后,才会同步到upperdir层。

  1. 读取文件: 用户读取文件时,可以同时看到upperdir或者lowerdir层,只要文件没有被覆盖,就可以被读取到
  2. 写入文件:如果文件在upperdir层,直接进行修改,如果文件在lowerdir层,发生写时拷贝,将文件拷贝到upperdir层再修改
  3. 删除文件:如果文件在upperdir层,那么直接删除文件,如果文件在lowerdir层,不会删除文件,而是标记为不可见

对于大部分Linux系统,都是自带overlay文件系统的,可以基于mount命令模拟一下overlay文件系统。

  1. 创建四个目录,表示不同层

在这里插入图片描述

overlay中,其实一层就是一个目录,创建四个目录,后续在这四个目录上创建一个overlay文件系统。

  1. 写入文件

在这里插入图片描述

lowerupper目录中写入一些文件,low.txt只在lower层出现,up.txt只在upper层出现,both.txt在两个层都出现。

  1. 创建文件系统
mount -t overlay overlay 
-o lowerdir=./lower,upperdir=./upper,workdir=./work ./merged

这个命令,会创建一个overlay文件系统,-t overlay表示文件系统类型,第二个overlay是一个应用程序,表示用这个程序来操控文件系统。

-o指定文件系统的相关参数,用,逗号分隔,可以看出分别代表lowerdirupperdirworkdir三个层。

最后的./merged不是-o的参数,这是挂载点,表示用户最后通过./merged目录访问整个文件系统。

在这里插入图片描述

执行命令挂载成功后,./merged就被初始化了,其可以看到low.txtup.txtboth.txt

此处merged目录中,所有文件都是一个引用,文件都存储在lowerupper中。这可以通过查询inode来证明,如果两个文件的inode一样,那么在硬盘中指向的就是同一块空间,通过ls-i参数。

在这里插入图片描述

查询mergeupperup.txt文件,第一栏都是562812,也就是说两者inode相同,就是同一个文件。

借此,可以查看merge/both.txt使用的哪一层的内容:

在这里插入图片描述

可以看到merge/both.txtupper/both.txtinode = 562810,相同的,也就是说lower层的both.txt被覆盖了,用户看不到这层的both.txt

  • 修改merged/low.txt

在这里插入图片描述

此时不仅仅是merged内部的low.txt改变了,而upper层多出一个low.txt,这是因为写时拷贝。如果修改的文件在lower层,会把文件拷贝到upper层再修改,不会影响原文件。

因此后续cat输出文件内容时,可以看到upper/low.txt是最新写入的内容,而lower/low.txt是一个空文件。

  • 删除merge/low.txt

在这里插入图片描述

删除文件后,lower层内部的文件还在,在upper目录下,多出一个low.txtwork也多出一个新内容。

看看多出的upper/low.txt

在这里插入图片描述

其权限为c---------,也就是没有任何权限,这就是一个删除标记,表示这个文件虽然在lower中存在,但是已经被标记为删除了,所以用户看不到这个文件。

  • 删除merge/up.txt

在这里插入图片描述

此时这个up.txt真的就被删除了,没有任何标记,因为upper层本身就是可以读写的,删除文件 并不会被标记。

实验完毕,可以通过umount卸载这个文件系统:

umount 挂载路径

在这里插入图片描述


那么这个联合文件系统,到底和Docker什么关系?

在这里插入图片描述

其实Docker就是使用的overlay结构存储文件,镜像层就是lowerdir层,容器层就是upperdir层,用户看到的是merged层。

一个镜像可以实例化为多个容器,就是因为所有容器都共用一个lowerdir,因为这个层只读,不会修改镜像的内容,任何容器做的所有修改,都在自己的upperdir中。


镜像存储结构

docker inspect centos查看一个centos镜像的详细信息:

在这里插入图片描述

可以看到,在GraphDriver中,包含了三个熟悉的目录,MergedDirUpperDirWorkDir,并且使用的文件系统为overlay2

查看这个UpperDir的内容:

在这里插入图片描述

这就是操作系统的根目录!所以每当创建一个centos容器时,看到的就是这个目录,让用户感觉自己处于一个新的操作系统中。

由于centos镜像,本身就是一个非常底层的镜像,所以它没有lowerDir,此时可以基于centos镜像再创建一个镜像:

在这里插入图片描述

以上操作,创建了一个centos容器,然后进去创建了三个文件,退出后通过commit创建了一个test:v1镜像。

docker inspect test:v1查看这个镜像的信息:

在这里插入图片描述

这个新建的镜像,就有LowerDir了,查看LowerDir的内容,其实就是centos镜像的内容,说明新的镜像把老的镜像作为了基底。

而在UpperDir中,是之前在容器内部创建的三个文件。


容器存储结构

刚才发现,在一个镜像内部,有upperdir层,lowerdir层,那么容器层去哪里了,不是说upper层是容器吗?为什么镜像也有upper层?

把刚才的test:v1镜像,实例化为一个容器:

docker run -d --name test test:v1

然后再查看容器的详细信息:

docker container inspect test

在这里插入图片描述

可以发现,容器也分为LowerDirUpperDir等等内容,在LowerDir,有很长一个路径,细看可以看出是由:冒号分隔的三段路径:

/data/var/lib/docker/overlay2/9f8d970f2ece5d2ad7985cad1d12821e0c10355f60846ce5429207788b8b81ed-init/diff
/data/var/lib/docker/overlay2/20c74607fa2b73e5e419e6f2167e4220aa2b3f3e164cbaa928e8ed87421d3051/diff
/data/var/lib/docker/overlay2/ef10e4f37d8b8015c2319620bc8e391a824275741bc50e34bbf92392cb53c474/diff

依次输出这三段路径的内容:

在这里插入图片描述

熟悉的目录出现了,依次是centos层,test:v1新增的层,以及一个init层。

原先镜像的所有层,在容器实例化后,都变成了容器的LowerDir

此处的init层,内部包含两个目录devetc,这在centos层中也有。其实这个init层,是容器初始化时的层,因为初始化时修改了devetc,由于写时拷贝,会把文件拷贝到init层再修改。

docker通过overlay来对容器分层,而镜像本身也被overlay分层了,所以这里使用了两次联合文件系统。

在这里插入图片描述

对于容器来说,将镜像作为LowerDir进行处理。而对于镜像来说,镜像本身的资源结构也被分层管理了,镜像的所有层,都作为容器的LowerDir层。


存储卷

绑定挂载

存储卷是基于绑定挂载实现的,绑定挂载是Linux中的一种挂载操作,它允许将一个文件或目录挂载到文件系统的另一个位置,从而在两个不同的路径下访问相同的文件或目录这种挂载方式不会复制文件,而是创建一个指向原始文件或目录的引用

可以使用mount命令来执行绑定挂载:

mount --bind <source> <target>
  • source:要挂载的原始文件或目录的路径
  • target:挂载点,即你希望文件或目录出现在的位置

要卸载绑定挂载,可以使用umount命令:

umount 挂载点

这将卸载/mnt/data的挂载点,但不会删除/data目录或其内容。

试验一下:

在这里插入图片描述

首先创建两个目录,在第一个目录中有三个文件,第二个目录是一个空目录。

dir2绑定挂载到dir1

在这里插入图片描述

此时dir2也出现了这三个文件,并且查询1.txt,可以发现两个文件的inode是一样的。


存储卷结构

Docker的存储卷,就是使用了绑定挂载,把宿主机的文件,与容器内部的文件进行绑定,此时两个文件其实是同一个文件,互相操作都是可以看到的。

那么问题来了,容器是有文件系统隔离的,在mount --bind时要指定两个文件,宿主机看不到容器内部的文件,容器内看不到宿主机的文件,如何才能mount --bind同时指定处于不同环境下的两个文件?

其实这是不可行的,被文件隔离的两个环境,是无法mount --bind绑定挂载两个文件的,因此要在容器创建后,文件隔离开启前,进行绑定挂载存储卷

在容器创建后,会经过一段时间的初始化,文件隔离很早就会开启,但是开启文件隔离后,还要chroot命令,容器与宿主机的文件系统才相互不可见。

所以要在执行chroot命令之前,就进行绑定挂载:

在这里插入图片描述

顺便说一下,联合文件系统中,容器也是要访问宿主机中的镜像底层文件的,这也要在choroot之前完成挂载,让容器可以看到宿主机中的镜像文件,这基于联合挂载,是一种和绑定挂载不同的挂载方式,也是联合文件系统依赖的挂载方式。

联合挂载完毕后,就是存储卷的绑定挂载,最后执行chroot,两个文件系统彻底隔离。


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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【源码+文档】基于SpringBoot的养老院管理系统

作者简介&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容&#xff1a;&#x1f31f;Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…

LVGL UI设计神器助你高效开发嵌入式UI应用——v0.16.0发布

文章目录 Preface一、What is Anyui&#xff1f;二、Features of v0.16.0 releaseSum up Preface As coming of Internet of Things, the “screen reading” era predicted by Kevin Kelly has also arrived. Besides products like mobile phones and tablets which are PC-…

JavaFx -- chapter06(UDPSocket)

chapter06(UDPSocket) UPD的特点 UDP有独立的套接字&#xff08;IP PORT&#xff09;&#xff0c;与TCP使用相同端口号不会冲突。UDP在使用前不需要进行连接&#xff0c;没有流的概念。UDP通信类似于邮件通信&#xff1a;不需要实时连接&#xff0c;只需要目的地址。UDP通信…

爬虫学习2

数据解析 正则表达式 量词&#xff1a; import re#searcch只会匹配到第一次匹配的内容#result re.search(r"\d","今年32")#print(result.group()) #result re.findall(r"\d","我是一个abcdeafg") #print(result)#search只会匹配到第…

radio astronomy 2

地球上的电离层会被太阳风影响。

服务器作业(2)

架设一台NFS服务器&#xff0c;并按照以下要求配置 关闭防火墙 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 配置文件设置&#xff1a; [rootlocalhost ~]# vim /etc/exports 1、开放/nfs/shared目录&#xff0c;供所有用户查询资料 共享…

基于MATLAB多参数结合火焰识别系统

一、课题介绍 本设计为基于MATLAB的火焰烟雾火灾检测系统。传统的采用颜色的方法&#xff0c;误识别大&#xff0c;局限性强。结合火焰是实时动态跳跃的&#xff0c;采用面积增长率&#xff0c;角点和圆形度三个维度相结合的方式判断是否有火焰。该设计测试对象为视频&#xf…

云轴科技ZStack在CID大会上分享VF网卡热迁移技术

近日&#xff0c;2024中国云计算基础架构开发者大会&#xff08;以下简称CID大会&#xff09;在北京举行。此次大会集中展示了云计算基础架构技术领域最前沿的科创成果&#xff0c;汇聚众多的技术专家和行业先锋&#xff0c;共同探讨云计算基础设施的最新发展和未来趋势。云轴科…

阿里云 K8S ACK服务 创建使用教程

目录 1.1 阿里云容器服务ACK介绍和创建 1.1.1 什么是容器服务Kubernetes版? 1.1.2 创建专有版Kubernetes集群 1.1.3 访问专有版Kubernetes集群 1.1.4 在专有版ACK集群创建资源并访问 通过百度网盘分享的文件&#xff1a;第12章-阿里云托管k8s集群ACK创建和使用 链接&…

H5测试点总结

一、概述 1.1 什么是H5 H5 即 HTML5&#xff0c;是最新的 Web 端开发语言版本&#xff0c;现如今&#xff0c;大多数手机 APP 页面会用 H5 实现&#xff0c;包括 PC Web 站点也会用它开发实现。所以 Web 的通用测试点和方法基本都可以适用于它。H5其实就是&#xff1a;移动端…

TapData 发布官方性能测试报告,针对各流行数据源,在多项指标中表现拔群

近日&#xff0c;TapData 官方发布了最新的性能测试报告&#xff0c;该报告详细展示了 TapData v3.5.13 在各种数据源下的性能表现&#xff0c;包括全量同步、增量同步、读写延迟等关键性能指标。 随着企业对实时数据集成和处理能力需求的提升&#xff0c;TapData 凭借其高效、…

小红书发布IP与实际不一样?揭秘背后的原因与应对策略

在小红书这个充满活力的社交平台上&#xff0c;用户们经常分享着各自的生活点滴、购物心得、美食体验等丰富内容。然而&#xff0c;有时你可能会发现&#xff0c;小红书上显示的IP地址与你的实际所在地并不一致&#xff0c;这不禁让人心性疑惑。那么&#xff0c;小红书发布IP与…

Java8 新特性 —— Stream API 详解

本文涉及到的知识点有Lambda表达式以及函数式接口&#xff0c;有不了解的小伙伴可以先学习上一篇文章&#xff1a; Java8 新特性 —— Lambda 表达式、函数接口以及方法引用详解 文章目录 引言Stream API 的使用1、创建 Stream2、中间操作&#xff08;1&#xff09;筛选与切片…

Linux历史命令history增加执行时间显示

Centos系统默认历史命令显示如下 为了更好的溯源&#xff0c;获取执行命令的准确时间&#xff0c;需要增加一些配置 设置环境变量 vim /etc/profile 在最下面添加以下环境配置 export HISTTIMEFORMAT"%Y-%m-%d %H:%M:%S " 立即刷新该环境变量 source /etc/pro…

【测试平台】【前端VUE】工具页面学习记录

背景&#xff1a; 这个我4年半以前刚接手记录&#xff0c;测试工具页面一般比较简单&#xff0c;不需要复杂东西&#xff0c;剩下就是维护。 工程安装 npm install 1.执行nmp install前先确认一下自己的node版本&#xff0c;这个项目需要是node12才可以&#xff0c;否则会出…

mysq-B+Treel(一)

介绍 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典 MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的RDBMS (Relational Database Management System&#xff0c;关系…

解决使用netstat查看端口显示FIN_WAIT的问题

解决使用netstat查看端口显示FIN_WAIT的问题 1. 理解`FIN_WAIT`状态2. 检查应用程序3. 检查网络延迟和稳定性4. 更新和修补系统5. 调整TCP参数6. 使用更详细的工具进行分析7. 咨询开发者或技术支持8. 定期监控和评估结论在使用 netstat查看网络连接状态时,如果发现大量连接处…

微服务实战系列之玩转Docker(十八)

导览 前言Q&#xff1a;如何保障容器云环境下etcd集群的数据安全一、安全机制身份认证必学必看1. 启动参数2. 授权命令3. 开启认证 二、应用实践1. 访问容器2. 查看认证是否开启3. 查看是否已创建用户4. 创建用户5. 开启认证6. 验证是否开启7. 验证数据 结语系列回顾 前言 etc…

畅享云边大模型!火山引擎 x 地瓜机器人,大模型网关能力免费开放

前期&#xff0c;火山引擎官宣与地瓜机器人达成了合作&#xff0c;实现了火山引擎边缘智能-大模型网关与地瓜机器人软硬件通用底座“云-边-端”的全面打通&#xff0c;拓展机器人的无限智能化潜能。地瓜 RDK X5 机器人开发套件集成了火山引擎边缘智能-大模型网关能力&#xff0…

计算机性能监控体系:Quark2.0

一、背景 在过去的IT日常支持场景中&#xff0c;因为服务的用户、终端、系统等等因业务而异&#xff0c;往往会遇到以下类似这些问题或需求&#xff1a; IT工程师定位终端问题跨越不同的平台或系统&#xff0c;低效繁琐用户想要获取一些个人相关的IT环境信息&#xff0c;只能…