中国建设银行e路通网站,什么软件可以推广自己的产品,卡片式网站模板下载,义乌跨境电商公司前十名Docker#xff1a;存储原理 镜像联合文件系统overlay镜像存储结构容器存储结构 存储卷绑定挂载存储卷结构 镜像
联合文件系统
联合文件系统Union File System是一种分层#xff0c;轻量且高效的文件系统。其将整个文件系统分为多个层#xff0c;层与层之间进行覆盖#x… 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层。
读取文件 用户读取文件时可以同时看到upperdir或者lowerdir层只要文件没有被覆盖就可以被读取到写入文件如果文件在upperdir层直接进行修改如果文件在lowerdir层发生写时拷贝将文件拷贝到upperdir层再修改删除文件如果文件在upperdir层那么直接删除文件如果文件在lowerdir层不会删除文件而是标记为不可见 对于大部分Linux系统都是自带overlay文件系统的可以基于mount命令模拟一下overlay文件系统。
创建四个目录表示不同层 在overlay中其实一层就是一个目录创建四个目录后续在这四个目录上创建一个overlay文件系统。
写入文件 往lower和upper目录中写入一些文件low.txt只在lower层出现up.txt只在upper层出现both.txt在两个层都出现。
创建文件系统
mount -t overlay overlay
-o lowerdir./lower,upperdir./upper,workdir./work ./merged这个命令会创建一个overlay文件系统-t overlay表示文件系统类型第二个overlay是一个应用程序表示用这个程序来操控文件系统。
-o指定文件系统的相关参数用,逗号分隔可以看出分别代表lowerdir、upperdir、workdir三个层。
最后的./merged不是-o的参数这是挂载点表示用户最后通过./merged目录访问整个文件系统。 执行命令挂载成功后./merged就被初始化了其可以看到low.txt、up.txt、both.txt。
此处merged目录中所有文件都是一个引用文件都存储在lower和upper中。这可以通过查询inode来证明如果两个文件的inode一样那么在硬盘中指向的就是同一块空间通过ls的-i参数。 查询merge和upper的up.txt文件第一栏都是562812也就是说两者inode相同就是同一个文件。
借此可以查看merge/both.txt使用的哪一层的内容 可以看到merge/both.txt和upper/both.txt的inode 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中包含了三个熟悉的目录MergedDir、UpperDir、WorkDir并且使用的文件系统为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可以发现容器也分为LowerDir、UpperDir等等内容在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层内部包含两个目录dev和etc这在centos层中也有。其实这个init层是容器初始化时的层因为初始化时修改了dev和etc由于写时拷贝会把文件拷贝到init层再修改。
docker通过overlay来对容器分层而镜像本身也被overlay分层了所以这里使用了两次联合文件系统。 对于容器来说将镜像作为LowerDir进行处理。而对于镜像来说镜像本身的资源结构也被分层管理了镜像的所有层都作为容器的LowerDir层。 存储卷
绑定挂载
存储卷是基于绑定挂载实现的绑定挂载是Linux中的一种挂载操作它允许将一个文件或目录挂载到文件系统的另一个位置从而在两个不同的路径下访问相同的文件或目录。这种挂载方式不会复制文件而是创建一个指向原始文件或目录的引用。
可以使用mount命令来执行绑定挂载
mount --bind source targetsource要挂载的原始文件或目录的路径target挂载点即你希望文件或目录出现在的位置
要卸载绑定挂载可以使用umount命令
umount 挂载点这将卸载/mnt/data的挂载点但不会删除/data目录或其内容。
试验一下 首先创建两个目录在第一个目录中有三个文件第二个目录是一个空目录。
把dir2绑定挂载到dir1 此时dir2也出现了这三个文件并且查询1.txt可以发现两个文件的inode是一样的。 存储卷结构
Docker的存储卷就是使用了绑定挂载把宿主机的文件与容器内部的文件进行绑定此时两个文件其实是同一个文件互相操作都是可以看到的。
那么问题来了容器是有文件系统隔离的在mount --bind时要指定两个文件宿主机看不到容器内部的文件容器内看不到宿主机的文件如何才能mount --bind同时指定处于不同环境下的两个文件
其实这是不可行的被文件隔离的两个环境是无法mount --bind绑定挂载两个文件的因此要在容器创建后文件隔离开启前进行绑定挂载存储卷。
在容器创建后会经过一段时间的初始化文件隔离很早就会开启但是开启文件隔离后还要chroot命令容器与宿主机的文件系统才相互不可见。
所以要在执行chroot命令之前就进行绑定挂载 顺便说一下联合文件系统中容器也是要访问宿主机中的镜像底层文件的这也要在choroot之前完成挂载让容器可以看到宿主机中的镜像文件这基于联合挂载是一种和绑定挂载不同的挂载方式也是联合文件系统依赖的挂载方式。
联合挂载完毕后就是存储卷的绑定挂载最后执行chroot两个文件系统彻底隔离。