存放系统镜像的文件夹

存放系统镜像的文件夹,第1张

Docker镜像存储overlayfs的使用

本文主要介绍Docker镜像存储overlayfs的使用方法,通过示例代码非常详细的介绍,对大家的学习或者工作有一定的参考价值。有需要的朋友下面和边肖一起学习。

一、概述

Docker中的镜子是分层设计的,每一层都可以称为“层”。这些层存储在/var/lib/Docker/

通常ubuntu系统默认使用AUFS,centos7.1+系列使用OverlayFS。本文将介绍以OverlayFS为存储驱动的镜像存储的原理和结构。

二。OverlayFS简介

OverlayFS是一个堆栈式的文件系统,它依赖并构建在其他文件系统上(如ext4fs和xfs等。),并且不直接参与磁盘间结构的划分空。它只是将原来底层文件系统中不同的目录“合并”呈现给用户,这就是联合挂载技术。与AUFS相比,OverlayFS更快,也更容易实现。Linux内核为Docker提供的overlayFS驱动有两种:Overlay和overlay2。Overlay2是对Overlay的改进,在索引节点利用率方面,overlay比overlay更有效。但是overlay有环境要求:docker版本17.06.02+,主机文件系统需要是ext4或者xfs格式。

关节支架

Overlayfs由三个目录实现:下级目录、上级目录、工作目录,其中下级目录可以是多个,工作目录是工作的基本目录。挂载后内容会被清除空,用户在使用过程中看不到其内容。最后,联合挂载完成后呈现给用户的统一视图称为合并目录。下面mount的使用将演示它是如何工作的。

使用mount命令装载overlayfs语法,如下所示:

mount-toverlayoverlay-olowerdir=lower1:lower2:lower3,upperdir=upper,workdir=workmerged_dir

创建三个目录A、B、C和worker目录:

然后使用mountunion在/tmp/test下挂载:

然后我们来看看/tmp/test目录。你会发现目录A、B、C合并在一起,文件名相同的文件会被“覆盖”。在这里,覆盖并不是真正的覆盖,而是当目录中的两个文件在合并过程中具有相同的名称时,合并的层目录将显示最近层的文件:

同时,我们还可以通过mount命令查看其挂载选项:

以上方法就是接头安装技术。

Docker中的覆盖驱动程序

介绍完叠加驱动的原理,我们再来看看docker中的叠加存储驱动。以下是来自Docker官网的overlay工作原理图:

上图可以看到三个层结构,分别是:lowerdir、uperdir和merged,其中lowerdir是一个只读的图像层,实际上就是rootfs。对比我们上面演示的目录A和B,我们知道图像层可以分为很多层,所以对应的lowerdir可以有多个目录。上层是下层之上的一层。这一层是读写层,将在容器启动时创建。对容器数据的所有更改都发生在这一层。与示例中的C进行比较。最后,合并的目录是容器的挂载点,也就是向用户公开的统一透视图。示例中的Compare/tmp/test。并且这些目录层保存在/var/lib/docker/overlay2/或/var/lib/docker/overlay/(如果使用overlay的话)。

演示

启动一个容器。

查看其覆盖挂载点,您可以找到其挂载的合并目录lowerdir、upperdir和workdir:

Overlay2可以有不止一个lowerdir,而且是软连接挂载的,我们后面会解释。

工作原理

当容器中的数据被修改时,overlayfs存储驱动程序如何工作?下面将描述读写过程:

阅读:

  • 如果文件在容器层(upperdir),直接读取文件;
  • 如果文件不在容器层(upperdir),则从镜像层(lowerdir)读取;
  • 修改:

  • 首次写入:如果upperdir中不存在,overlay和overlay2执行copy_up *** 作,将文件从lowdir复制到upperdir。由于overlayfs是在文件级(即使文件只是轻微修改,也会产生copy_up行为),所以这里对同一个文件的后续写 *** 作,都会对已经复制到容器的文件副本进行 *** 作。这通常被称为写入时拷贝
  • 删除文件和目录:当在容器中删除文件时,在容器层(upperdir)创建空白文件。镜像层(lowerdir)中的文件不会被删除,因为它们是只读的,但是没有文件会阻止它们被显示。当在容器中删除目录时,在容器层(upperdir)中有一个不透明的目录。这与上面的whiteout原则是一样的,它阻止用户继续访问,即使
  • 需要注意的事项

  • Copy_up *** 作只在文件第一次写入时发生,以后只修改副本。
  • Overlayfs只适用于两层目录,查找和搜索比AUFS更快。
  • 容器层的文件删除只是一个“烟幕”,被whiteout文件屏蔽了,但是图像层并没有被删除,这也是为什么使用dockercommit提交保存的图像会越来越大,无论容器层怎么删除数据,图像层都不会改变的原因。
  • 三。重叠2镜像存储结构

    从仓库中拉一张ubuntu图片,结果显示一共拉了4层图片,如下:

    此时,第4层存储在/var/lib/docker/overlay2/目录中:

    有一个额外的L目录包含所有层的软链接。短链接使用短名称来避免参数在装载过程中达到页面大小限制(在演示中查看装载命令时为短目录):

    底层的镜像目录包含一个diff和一个链接文件。diff目录存储当前层的镜像内容,而链接文件是与之对应的简称:

    在此之上,有更多的工作目录和更低的文件。下层文件用来记录父层的简称,工作目录用来联合挂载指定的工作目录。这些目录和镜像之间的关系是如何组织在一起的?答案是用元数据关联的。元数据分为影像元数据和图层元数据。

    图像元数据

    镜像元数据存储在/var/lib/docker/image/中。/imagedb/content/sha256/directory,名称是以图像ID命名的文件,可以通过dockerimages查看。这些文件保存rootfs信息、映像创建时间、构建历史信息、使用的容器,包括启动入口点和CMD等。json格式的图片。比如ubuntu图片的id是47b19964fb50:

    查看其对应的元数据(使用vim:%!格式为json的Python-mjson.tool)截取其rootfs的组成:

    上面的diff_id对应一个镜像层,它的排列也是有序的,从上到下,镜像层的最底层到顶层:

    diff_id与进度层有什么关系?具体来说,docker使用rootfs中的每个diff_id和历史信息计算对应的内容寻址索引(ChaiID),chaiID与层layer关联,再与每个镜像层的镜像文件关联。

    层元数据

    层对应于镜像层的概念。在Docker版之前,镜像是通过图结构来管理的。每个镜像层都有元数据,记录了该层的构造信息和父镜像层的ID,而顶层镜像层会记录更多的信息作为整个镜像的元数据。Graph根据镜像ID(即顶层镜像层ID)和每个镜像层记录的父镜像层ID维护一个树状镜像层结构。

    Docker版本之后,镜像元数据管理的一个很大的变化就是简化了镜像层的元数据,只包含一个特定的镜像层文件包。用户在docker的主机上下载某个镜像层后,docker会构建本地层元数据,包括diff、parent、size等。,基于主机上的镜像图层包和图像元数据。docker将主机上生成的新镜像层上传到registry时,主机上与新镜像层相关的元数据不会与镜像层一起打包上传。

    Docker中定义了Layer和RWLayer两个接口,分别用来定义只读层和读写层的一些 *** 作,还定义了roLayer和mountedLayer,分别实现了以上两个接口。RoLayer用于描述不可变的镜像层,mountedLayer用于描述可读的容器层。具体来说,roLayer存储的内容主要包括镜像层的chainID,镜像层的校验码diffID,父镜像层和storage_driver存储的当前镜像层文件的cacheID,镜像层的大小。元数据保存在/var/lib/docker/image/

    每个chainID目录中有三个文件cache-id、diff和zize:

    缓存id文件:

    docker随机生成的Uuid,其内容为镜像层的目录索引,即/var/lib/docker/overlay2/中的目录,这也是通过chainID可以找到对应层目录的原因。与chainidd801a12f6f6af7bef367268f99607376584d8B2da656DCD8656973b7ad9779ab4对应的目录是130ea10D6f0ebfaf8ca260992c8d0bef63a1b5ca37d55a1d1b1031d23efD5,也保存在/var/lib/docker/overlay2/1300

    差异文件:

    将diff_id保存在镜像元数据中(对应于元数据中diff_id中的uuid)

    文件大小:

    镜像层的大小被保存。

    在图层的所有属性中,diffID是由SHA256算法根据镜像图层的文件包内容计算的。而chainID是基于内容存储的索引,它是根据当前层和所有祖先镜像层的diffID计算的,如下:

  • 如果镜像层是最低层(没有父镜像层),则该层的diffID是chainID。
  • 镜像层chainID的计算公式为chainID(n)=SHA256(chain(n-1)diffID(n)),即在父镜像层的chainID和当前层的diffID上加一个空点阵,然后计算sha256校验码。
  • 存储在mountedLayer信息中的可读init层和容器挂载点信息包括容器init层ID(init-id)、用于联合挂载的ID(mount-ID)和容器层的父映像的chainID(parent)。相关文件位于/var/lib/docker/image/

    检查其对应的mountedLayer三个文件:

    可以看到,在mountID后面添加了一个-init作为initID,initID是存储在/var/lib/docker/overlay2/中的目录名:

    要查看mountID,也可以通过mount命令直接查看对应挂载的mountID,对应的是/var/lib/docker/overlay2/目录,也是overlayfs呈现的合并目录:

    在容器中创建了一个文件:

    此时,您可以在主机的合并目录中看到相应的文件:

    关于初始化层

    init层以uuid+-init结束,它夹在只读层和读写层之间。用于存储/etc/hosts、/etc/resolv.conf等信息,之所以需要这一层,是因为在容器启动时,这些应该属于镜像层的文件或目录,比如主机名,需要用户修改,但是镜像层是不允许修改的。因此,当容器启动时,会挂载一个单独的init层,并且可以修改应该属于image层的文件或目录。但是,这些更改通常只能从当前容器中读取,当dockercommit作为镜像提交时,init层将不会被提交。图层文件存储在目录/var/lib/docker/overlay2/中。/diff

    摘要

    通过上面的介绍,一个完整的容器层应该由三部分组成,如下图所示:

  • 镜像层:也称为rootfs,提供容器启动的文件系统。
  • init层用于修改容器中的一些文件,如/etc/hostname、/etc/resolv.conf等。
  • 容器层:使用联合挂载提供给用户的可读可写的目录。
  • 四。摘要

    介绍了overlayfs驱动的镜像存储原理,其中每一层的镜像数据都存储在/var/lib/docker/overlay2/中

    参考:

    《使用overlayfs驱动程序》

    Docker图像的存储管理

    这就是这篇关于Docker镜像存储覆盖的使用的文章。有关Docker镜像存储overlayfs的更多信息,请搜索我们以前的文章或下面的相关文章。希望大家以后能多多支持我们!

    欢迎分享,转载请注明来源:内存溢出

    原文地址: http://outofmemory.cn/zz/774630.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-05-03
    下一篇 2022-05-03

    发表评论

    登录后才能评论

    评论列表(0条)

    保存