联合文件系统(UnionFS)总结

联合文件系统(UnionFS)总结

大纲

  • 概念
  • 实例
  • aufs & overlayfs

概念

联合文件系统(Union File System):2004年由纽约州立大学石溪分校开发,它可以把多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。UnionFS允许只读和可读写目录并存,就是说可同时删除和增加内容。UnionFS应用的地方很多,比如在多个磁盘分区上合并不同文件系统的主目录。另外UnionFS具有写时复制(copy-on-write)功能UnionFS可以把只读和可读写文件系统合并在一起,虚拟上允许只读文件系统的修改可以保存到可写文件系统当中

UnionFS的核心就是高效的利用磁盘空间

docker中使用到了UnionFS
任何程序运行时都会有依赖,无论是开发语言层的依赖库,还是各种系统lib、操作系统等,不同的系统上这些库可能是不一样的,或者有缺失的。为了让容器运行时一致,docker将依赖的操作系统、各种lib依赖整合打包在一起(即镜像),然后容器启动时,作为它的根目录(根文件系统rootfs),使得容器进程的各种依赖调用都在这个根目录里,这样就做到了环境的一致性

实例

ubuntu UnionFS 实现 aufs

注意 aufs并不是内核支持的(aufs是各个linux发行版自己在做支持 例如ubuntu上可以使用aufs)

ubuntu下使用aufs实现UnionFS 挂载命令各式:

mount -t aufs -o dirs=【文件夹 多个用:分割】【自定义挂载名称】【挂载位置】

  • mount -t aufs 模板各式 -t aufs指定使用 aufs

  • -o dirs=【文件夹 多个用:分割】

  • 【自定义挂载名称】 此名称会在mount 中显示

  • 【挂载位置】联合文件挂载的位置

    例如以下命令
    mount -t aufs -o dirs=/data/tmpfile/go:/data/tmpfile/java myaufs /data/ufs/
    以上命令把/data/tmpfile/go文件夹内容 /data/tmpfile/java文件内容 挂载到/data/ufs/文件夹 挂载名称为myaufs

联合文件系统(UnionFS)总结_第1张图片

以上命令没有指定权限,默认第一个(最左边)的目录(/data/tmpfile/go)是可读可写的后面的全都是只读的
后面会说明如何指定文件权限可读可写

联合文件系统(UnionFS)总结_第2张图片

可以看到在/data/ufs中操作从/data/tmpfile/go文件夹挂载过来的文件,原始文件也会被修改。 同理在配置为读写权限的原始文件夹中添加内容 也会同步到 UnionFS中

在UnionFS文件系统中添加文件,新添加的文件也会被加载到原始的有读写权限的文件夹下

在这里插入图片描述

对文件内容的删除

联合文件系统(UnionFS)总结_第3张图片

注意那些wh开头的都是隐藏文件 使用ls是看不到的

一般来说只读目录都会有whiteout的属性,所谓whiteout的意思,就是如果在union中删除的某个文件,实际上是位于一个readonly的目录上,那么,在mount的union这个目录中你将看不到这个文件,但是readonly这个层上我们无法做任何的修改,所以,我们就需要对这个readonly目录里的文件作whiteout。AUFS的whiteout的实现是通过在上层的可写的目录下建立对应的whiteout隐藏文件来实现的。 所以上面的rm Test.go操作和touch PP.java效果相同。

指定被挂载的原始文件夹的读写权限 是用=rw

例如
mount -t aufs -o dirs=/data/tmpfile/java=rw:/data/tmpfile/python=rw:/data/tmpfile/go/ rwaufs /data/aufsmnt/
这里 /data/tmpfile/java=rw /data/tmpfile/python=rw 表示这两个文件夹是有读写权限的
并且 /data/tmpfile/java作为最上层主文件夹 在UnionFS中的新增内容都会同步到这里

联合文件系统(UnionFS)总结_第4张图片

AUFS 中被 Union 的目录(分支)有以下这些权限:

  • rw 表示可读可写 read-write
  • ro 表示只读 read-only,那么对于 ro 目录来说,是永远不会收到写操作的,也不会收到查找 whiteout 的操作。
  • rr 表示 read-read-only,与 read-only 不同的是,rr 标记的是天生就是只读的目录。这样一来, AUFS 可以提高性能,比如不再设置 inotify 来检查文件变动的通知。
  • wh 表示 whiteout,它通常和 ro 一起使用,比如 [dir]=ro+wh

whiteout 主要用于隐藏底层分支的文件。当 union 中要删除的某个文件实际上位于 read-only 的目录上的,由于在 read-only 上我们无法做任何的修改,此时我们就可以对这个 read-only 目录里的文件做 whiteout。具体做法就是在可写的目录中创建对应的 whiteout 隐藏文件来实现,比如 demo 这个文件位于 read-only 目录中,那么要 union 的目录中要删除这个文件了,那么就在可写的目录中创建一个名为 .wh.demo 的文件即可。除此之外,whiteout 还可以用于阻止 readdir 进入低层分支,此时的名字应该是 .wh…wh…opq 或者 .wh.__dir_opaque

ubuntu UnionFS 实现 overlayfs

overlay是一种联合文件系统,并且与linux3.10进入内核 所以所有的linux系统内核大于3.10的都可以使用overlay 实现UnionFS 包括ubuntu centos
docker也使用的是overlayfs,OverlayFS这种堆叠的文件系统,依赖于其他文件系统之上例如 xfs ext4

2014 年,OverlayFS 第一个版本被合并到 Linux 内核 3.18 版本中,由于第一版的overlay文件系统存在很多弊端(例如运行一段时间后Docker 会报 “too many links problem” 的错误), Linux 内核在 4.0 版本对overlay做了很多必要的改进,此时的 OverlayFS 被称之为overlay2。

所以操作系统是 RHEL 或 CentOS,Linux内核版本大于等于 3.10.0-514 其他 Linux 发行版的内核版本大于 4.0(例如 Ubuntu 或 Debian)此时的overlay 都是 overlay2

要想使用overlay2,Docker 版本必须高于 17.06.02
overlay2最好搭配 xfs 文件系统使用,并且使用 xfs 作为底层文件系统时,d_type必须开启,可以使用以下命令验证 d_type 是否开启:

创建xfs文件系统
mkfs.xfs -f -n ftype=1 /path/to/disk

ubuntu下使用overlay实现UnionFS 挂载命令各式:

mount -t overlay 【自定义挂载名称】 -o lowerdir=【底层文件夹】,upperdir=【上层文件夹】,workdir=【工作文件夹】 【挂载位置】

  • mount -t overlay 模板各式 -t overlay 指定使用 overlay
  • 【自定义挂载名称】 此名称会在mount 中显示
  • 【挂载位置】联合文件挂载的位置
  • -o 后面主要有lowerdir upperdir workdir

在overlayfs 中有几个主要的概念

  • LowerDir
  • UpperDir
  • WorkDir
  • MergedDir

联合文件系统(UnionFS)总结_第5张图片

LowerDir

LowerDir 基础层即原始文件所在的位置,lower层的文件只读

例如 lowerdir=lowerA:lowerB:lowerC   
其中"lowerA:lowerB:lowerC"表示不同的lower层目录,不同的目录使用":"分隔,层次关系依次为lowerA > lowerB > lowerC
(注:多lower层功能支持在Linux-4.0合入,**Linux-3.18版本只能指定一个lower dir** 使用uname -a 查看linux内核版本)

用户在写文件时,如果文件来自upper层,那直接写入即可。但是如果文件来自lower层,由于lower层文件无法修改,因此需要先复制到upper层,然后再往其中写入内容,这就是overlayfs的写时复制(copy-up)特性。

UpperDir

客户端所做的任何修改都将反映在Upper层 ,故upper层可读可写

注意 只能指定一个UpperDir

WorkDir

指定文件系统的工作基础目录,挂载后内容会被清空,且在使用过程中其内容用户不可见

它只是一个存放临时文件的目录,OverlayFS 中如果有文件修改,就会在中间过程中临时存放文件到这里

如果指定了UpperDir 就必须要指定 WorkDir,也可以省略upperdir和workdir参数,但/MergedDir为只读属性

联合文件系统(UnionFS)总结_第6张图片

MergedDir

就是UnionFS挂载的文件夹

OverlayFS规则

使用mount进行OverlayFS合并之后遵循如下规则:

  • 1 lowerdir和upperdir两个目录存在同名文件时,lowerdir的文件将会被隐藏,用户只能看到upperdir的文件。
  • 2 lowerdir低优先级的同目录同名文件将会被隐藏。
  • 3 如果存在同名目录,那么lowerdir和upperdir目录中的内容将会合并。
  • 4 当用户修改mergedir中来自upperdir的数据时,数据将直接写入upperdir中原来目录中,删除文件也同理。
  • 5 当用户修改mergedir中来自lowerdir的数据时,lowerdir中内容均不会发生任何改变。因为lowerdir是只读的,用户想修改来自lowerdir数据时,overlayfs会首先拷贝一份lowerdir中文件副本到upperdir中(这也被称作OverlayFS的copy-up特性)。后续修改或删除将会在upperdir下的副本中进行,lowerdir中原文件将会被隐藏。
  • 6 如果某一个目录单纯来自lowerdir或者lowerdir和upperdir合并,默认无法进行rename系统调用。但是可以通过mv重命名。如果要支持rename,需要CONFIG_OVERLAY_FS_REDIRECT_DIR。

在这里插入图片描述

使用例子

把lower1 lower2 go文件夹挂载到 overlagtest文件夹

mount -t overlay myoverlay -o lowerdir=/data/tmpfile/lower1:/data/tmpfile/lower2:/data/tmpfile/go,upperdir=/data/tmpfile/upper1,workdir=/data/tmpfile/work/ /data/overlagtest/ 

联合文件系统(UnionFS)总结_第7张图片

对lower层文件修改 原始数据不变,验证lower层只读

在这里插入图片描述

对upper层文件修改 原始数据会变化,验证upper层可以读写
在这里插入图片描述

相关术语

Branch – 就是各个要被union起来的目录(就是使用的dirs的命令行参数)

šBranch根据被union的顺序形成一个stack,一般来说最上面的是可写的,下面的都是只读的。
šBranch的stack可以在被mount后进行修改,比如:修改顺序,加入新的branch,或是删除其中的branch,或是直接修改branch的权限

Whiteout 和 Opaque

š如果UnionFS中的某个目录被删除了,那么就应该不可见了,就算是在底层的branch中还有这个目录,那也应该不可见了。
šWhiteout就是某个上层目录覆盖了下层的相同名字的目录。用于隐藏低层分支的文件,也用于阻止readdir进入低层分支。
šOpaque的意思就是不允许任何下层的某个目录显示出来。
š在隐藏低层档的情况下,whiteout的名字是’.wh.’。
š在阻止readdir的情况下,名字是’.wh..wh..opq’或者 ’.wh.__dir_opaque’。

你可能感兴趣的:(一些杂文,java,linux,ubuntu)