Docker存储驱动之AUFS简介

  AUFS曾是Docker默认的首选存储驱动。它非常稳定、有很多真实场景的部署、很强的社区支持。它有以下主要优点:
  极短的容器启动时间。
  有效的存储利用率。
  有效的内存利用率。
  虽然如此,但由于它没有包含在Linux内核主线中,所有很多Linux发行版并不支持AUFS。
  以下章节介绍AUFS的特性,并且它们如何作用于Docker。

特性 镜像分层和部署

  AUFS是一种联合文件系统。它使用同一个Linux host上的多个目录,逐个堆叠起来,对外呈现出一个统一的文件系统。AUFS使用该特性,实现了Docker镜像的分层。下图展示出Ubuntu:latest的镜像的分层。
  

Docker存储驱动之AUFS简介


  注意:在Docker1.10之前,layer的ID对应着其在/var/lib/docker下的目录名称,但在Docker1.10之后,不再有这种直接的对应关系。
  对于一个容器来说,只有顶层的容器layer是可读写的,而下面的layer都是只读的。

读写文件

  Docker使用AUFS的CoW(Copy-on-Write)技术来实现镜像共享和最小化磁盘空间的使用。AUFS作用于文件层,也就是说AUFS CoW拷贝整个文件——即使文件只修改了一点点的内容。所以,它对容器的性能影响很明显,尤其拷贝多层镜像下的大文件,或者是在一个深层次的目录树中进行搜索。
  不过,在给定的容器中,这种拷贝到顶层layer的操作,每个文件只会做一次。随后,对该文件的读写操作,都只针对容器顶层可读写layer的拷贝文件。

删除文件

  通过上面的介绍,很容易想到。如果要在容器中删除一个非顶层layer的文件,肯定不会在下层layer中直接删除,因为下层layer对于容器来说都是只读的。AUFS存储驱动要删除一个文件,是通过在容器顶层layer增加一个whiteout文件来实现的。这个whiteout文件可以隐藏下层只读layer中文件的存在,容器感知不到只读层layer中文的存在。事实上,无论该文件在下层只读layer中是否还存在,容器都认为这个文件被删除了。下图展示了whiteout文件如何工作的:
  

Docker存储驱动之AUFS简介

重命名目录

  AUFS未能完美的支持rename(2)重命名操作,会返回EXDEV[“cross-device link not permitted”],即使源路径和目的路径都在同一个AUFS层。因此,你的应用需要能处理EXDEV,可以用“拷贝再删除”的策略来替代rename操作。
  我在这里做了一个测试,写了一个简单地C程序,该程序将目录test重命名为目录gaga,并打印出rename的结果。该程序在普通服务器上完美运行,那么在容器中呢?开始做测试吧。

创建docker build目录,进入该目录。并在该目录下创建子目录test。 $ mkdir build-rename $ cd build-rename $ mkdir test 创建文件test.c $ vim test.c #include<stdio.h> #include <fcntl.h> int main(void) { char oldname[100] = "test", newname[100]="gaga"; int ret = rename(oldname, newname); if (ret == 0) printf("rename ok.\n"); else printf("ret = %d\n", ret); return 0; }

  编译该程序,生成可执行文件a.out。

$ gcc test.c 创建Dockerfile $ vim Dockerfile FROM ubuntu WORKDIR /usr/src/app COPY ./* /usr/src/app/ CMD /usr/src/app/a.out 生成镜像。 $ docker build -t rename:v1.0 ./ 运行容器 $ docker run --rm rename:v1.0 ret = -1

  该容器启动后会执行可执行文件a.out,重命名一个目录。可见结果,rename重命名一个目录的确是返回了失败。

配置AUFS 准备

  只有在OS安装了AUFS的情况下才能使用AUFS存储驱动,一般来说,Debian/Ubuntu都支持AUFS,而RedHat/CentOS都不支持AUFS。所以,你需要先查看下你的系统是否安装了AUFS。

$ grep aufs /proc/filesystems nodev aufs

  如果以上命令有输出则表示支持AUFS,否则就说明还未安装AUFS。可执行以下步骤:
  a. 升级你系统的kernel版本到3.13或者更高,另外建议安装kernel headers;
  b. 对于Ubuntu/Debian:安装linux-image-extra-*包:

$ apt-get install linux-image-extra-$(uname -r) \ linux-image-extra-virtual 配置

  如果上述操作无误,就可以使用AUFS来作为你Docker Daemon的存储驱动了。

$ dockerd --storage-driver=aufs &

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/c32a43c0fb6ea1546d264f87f30e4263.html