Docker存储驱动之AUFS简介
简介
AUFS曾是Docker默认的首选存储驱动。它非常稳定、有很多真实场景的部署、很强的社区支持。它有以下主要优点:
极短的容器启动时间。
有效的存储利用率。
有效的内存利用率。
虽然如此,但由于它没有包含在Linux内核主线中,所有很多Linux发行版并不支持AUFS。
以下章节介绍AUFS的特性,并且它们如何作用于Docker。
特性
镜像分层和部署
AUFS是一种联合文件系统。它使用同一个Linux host上的多个目录,逐个堆叠起来,对外呈现出一个统一的文件系统。AUFS使用该特性,实现了Docker镜像的分层。下图展示出ubuntu:latest的镜像的分层。
注意:在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文件如何工作的:
重命名目录
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 &
如果想持久化这个配置,可以编辑你的Docker配置文件(如/etc/default/docker,虽然官方已经不建议使用该文件了),并加入--storage-driver=aufs选项到DOCKER_OPTS中。
# Use DOCKER_OPTS to modify the daemon startup options.
DOCKER_OPTS="--storage-driver=aufs"
重启docker daemon(systemctl restart docker.service)后,确认默认存储驱动是否配置成功:
$ docker info | grep "Storage Driver"
Storage Driver: aufs
本地存储和AUFS
当dockerd使用AUFS驱动时,驱动把镜像和容器存储在Docker host的本地存储下:/var/lib/docker/aufs。
镜像
镜像层存储在/var/lib/docker/aufs/diff里。Docker 1.10之后,镜像对应的目录名称不再和镜像ID意义对应了。
/var/lib/docker/aufs/layers/目录保存了元数据信息,这些元数据显示了image层是如何叠加的。该目录下的每个文件,对应了一个层,而这个文件的内容就是该层之下的层。如:
$ cat /var/lib/docker/aufs/layers/91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c
d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82
c22013c8472965aa5b62559f2b540cd440716ef149756e7b958a1b2aba421e87
d3a1f33e8a5a513092f01bb7eb1c2abf4d711e5105390a3fe1ae2248cfde1391
由于base layer之下不再有其它层,所有base layer对应的文件内容是空的。
容器
运行中的容器映射在 /var/lib/docker/aufs/mnt/下,这就是AUFS给容器和它下层layer的一个mount point。如果容器没有运行了,依然还有这个目录,但却是个空目录,因为AUFS只在容器运行是才映射。Docker 1.10之上的版本,目录名同样不和容器ID对应。
容器元数据和多种配置文件存放在该目录下。
$ ls /var/lib/docker/aufs/mnt/670e0053b2ba02ab33dc24daca293e200aa98e871cefec016a5cbf9d41b7cfbf
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
容器的可写层存储在目录 /var/lib/docker/aufs/diff/,即使容器停止了,容器对应的目录依然存在。只有删除容器时,对应的目录才会删除。
AUFS在Docker中的性能
对于PaaS层来说,AUFS存储驱动是一个很好的选择。因为AUFS有效地在多个运行容器中共享镜像,加速了容器启动时间,减少了容器使用的磁盘空间。
AUFS在多个镜像层和容器间分享文件所使用的底层机制,高效地使用了系统的页缓存。
同时,AUFS存储驱动也带来了一些容器写性能上的隐患。这是因为,容器第一次对任何文件的修改,都需要先定位到文件的所在的镜像层次,并拷贝到容器最顶层的读写层。尤其当这些文件存在于很底层,或者文件本身非常大时,性能问题尤其严重。
小结
AUFS是Docker在Ubuntu/Debian中的默认存储驱动,虽然后面可能会被替换掉。但暂时来说,它完美地契合Docker的特性。并且,如何合理使用,其性能非常优异。另外,需要注意的是,AUFS对目录的重命名支持得不好,在编写程序时需要注意这点。
Docker存储驱动之AUFS简介的更多相关文章
- Docker存储驱动之OverlayFS简介
简介 OverlayFS是一种和AUFS很类似的文件系统,与AUFS相比,OverlayFS有以下特性: 1) 更简单地设计: 2) 从3.18开始,就进入了Linux内核主线: 3) 可能更快一些. ...
- 有容云-【原理】Docker存储驱动之AUFS
编者按:今天聊一聊Docker的Image(镜像)与Container(容器)的存储以及存储驱动之AUFS. Docker存储驱动简介 Docker内置多种存储驱动,每种存储驱动都是基于Linux ...
- Docker存储驱动之Btrfs简介
简介 Btrfs是下一代的copy-on-write文件系统,它支持很多高级特性,使其更加适合Docker.Btrfs合并在内核主线中,并且它的on-disk-format也逐渐稳定了.不过,它的很多 ...
- Docker存储驱动之ZFS简介
ZFS是下一代的文件系统,支持了很多存储高级特性,如卷管理.快照.和校验.压缩和重复删除技术.拷贝等. ZFS由Sun公司创建,现属于Oracle,ZFS是开源的,并基于CDDL license.因为 ...
- Docker存储驱动Device Mapper,Overlay,AUFS
Docker存储驱动之Device Mapper简介 - BookShu - 博客园https://www.cnblogs.com/styshoo/p/6528762.html Docker存储驱动之 ...
- Docker存储驱动之Device Mapper简介
Device Mapper是一个基于kernel的框架,它增强了很多Linux上的高级卷管理技术.Docker的devicemapper驱动在镜像和容器管理上,利用了该框架的超配和快照功能.为了区别, ...
- Docker存储驱动之总览
简介 本文会介绍Docker存储驱动的特性,别列出现在已经支持的存储驱动,最后,会介绍如果选型适合你的存储驱动. 可插拔的存储驱动架构 Docker的存储驱动架构是可插拔的,可以让你很方便的将适合你环 ...
- 聊一聊docker存储驱动
目录 镜像的分层特性 容器读写层的工作原理 写时复制 用时配置 Docker存储驱动 AUFS OverlayFS Devicemapper 常用存储驱动对比 AUFS VS OverlayFS Ov ...
- DOCKER学习_006:Docker存储驱动
一 镜像的分层特性 在说docker的文件系统之前,我们需要先想清楚一个问题.我们知道docker的启动是依赖于image,docker在启动之前,需要先拉取image,然后启动.多个容器可以使用同一 ...
随机推荐
- C# Winform窗口之间传值的多种方法浅析(转)
摘要http://www.jb51.net/article/63837.htm 这篇文章主要介绍了C# Winform窗口之间传值的多种方法浅析,本文起讲解了通过构造器传值.通过属性传递.通过事件携带 ...
- Java中间件:淘宝网系统高性能利器(转)
淘宝网是亚太最大的网络零售商圈,其知名度毋庸置疑,吸引着越来越多的消费者从街头移步这里,成为其忠实粉丝.如此多的用户和交易量,也意味着海量的信息处理,其背后的IT架构的稳定性.可靠性也显得尤为重要.那 ...
- iOS 之 Block Variable
在某个变量前面加__block ,这个变量就变成了block variable.那么就可以在block里面修改该值.
- Intent的属性及Intent-filter配置——指定Action、Category调用系统Activity
Intent代表了启动某个程序组件的“意图”,实际上Intent对象不仅可以启动本应用内程序组件,也可启动Android系统的其他应用的程序组件,包括系统自带的程序组件——只要权限允许. 实际上And ...
- Java Web快速入门——全十讲
Java Web快速入门——全十讲 这是一次培训的讲义,就是我在给学生讲的过程中记录下来的,非常完整,原来发表在Blog上,我感觉这里的学生可能更需要. 内容比较长,你可以先收藏起来,慢慢看. 第一讲 ...
- JSON数据格式中的引号
JSON数据中必须使用双引号: $.getJSON,的输入必须是正确的JSON数据,否则不会执行回调函数: $.parseJSON的输入必须是正确的JSON数据,否则会有异常:
- lo dash api
https://lodash.com/docs 用 Lo-Dash 替换 underscore http://segmentfault.com/a/1190000000359484
- 关于flash擦除的方法
一般的Flash,只允许写时将1变成0,而不允许0变成1:仅当擦除时将0变成1.所以写全0xff是没什么意义的 以前对flash只能进行一次写很困惑,这句话解释了原因. norflash就是 对bit ...
- C语言函数名与函数指针详解
一.通常的函数调用 一个通常的函数调用的例子: /* 自行包含头文件 */ void MyFun(int x); /* 此处的声明也可写成:void MyFun(int) */ int main(in ...
- [html5] 学习笔记-html5音频视频
HTML5 最大的新特色之一就是支持音频和视频.在 HTML5 之前,我们必须使用插件如 Silverlight 或 Flash 来实现这些功能.在 HTML5 中,可以直接使用新标签< au ...