为了有效地减少磁盘上冗余的镜像数据,同时减少冗余的镜像数据在网络上的传输,选择一种针对于容器的文件系统是很有必要的,而这类的文件系统被称为 UnionFS。

在linux上,从内核3.18,overlayFS合入主线之后,其就成为了默认的容器文件系统。

先创建一个overlayFS的示例

#!/bin/bash
 
umount ./merged
rm upper lower merged work -r
 
mkdir upper lower merged work
echo "I'm from lower!" > lower/in_lower.txt
echo "I'm from upper!" > upper/in_upper.txt
# `in_both` is in both directories
echo "I'm from lower!" > lower/in_both.txt
echo "I'm from upper!" > upper/in_both.txt
 
sudo mount -t overlay overlay \
 -o lowerdir=./lower,upperdir=./upper,workdir=./work \
 ./merged

在上面挂载一个overlay的过程当中,我们可以确定其有四种目录

  • lowerdir:mount的最底层的目录。只能读
  • upperdir:lowerdir上层的目录。可读写
  • workdir:修改文件的中间过程中的临时文件存放到这里。
  • merged:最终挂载的结果 忽略掉workdir这个目录,最终的挂载结果如下图 lowerdir和upperdir是输入,merged是输出,最终读写文件的地方是发生在merged中的。而由于lowerdir是只读的,所以实际的修改操作都发生在upper这一层。
  1. 新建文件:会出现在upper当中
  2. 修改文件:还是操作在upper,修改的lowerdir中的文件,则是会在upper中创建一个同名文件进行覆盖
  3. 删除文件:删除的是upper中的文件则会直接删除。删除lowerdir中的文件,则是会在upperdir创建一个特殊的文件来标记删除。

基于上面的介绍,就比较容易理解容器是如何使用overlay的了。

容器的镜像由很多layer组成,每层都对应lowerdir中的一个目录(lowerdir支持多目录),容器启动之后所有的修改都会发生在upperdir中。

容器文件读写变慢的问题

在linux内核5.4使用fio测试容器文件读写性能会出现性能下降的问题。 这是因为fio使用异步IO来测试性能,但是在5.4版本,aio_read() 之后调用的是 ovl_read_iter() 这个函数,不支持异步IO,但是测试的性能下降。

不过在5.6版本之后就修复了。