阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Docker存储驱动之AUFS简介

150次阅读
没有评论

共计 4319 个字符,预计需要花费 11 分钟才能阅读完成。

简介

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 &

如果想持久化这个配置,可以编辑你的 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/

$ 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 相关教程见以下内容

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

Ubuntu 14.04 安装 Docker  http://www.linuxidc.com/linux/2014-08/105656.htm

Ubuntu 使用 VNC 运行基于 Docker 的桌面系统  http://www.linuxidc.com/Linux/2015-08/121170.htm

阿里云 CentOS 6.5 模板��安装 Docker http://www.linuxidc.com/Linux/2014-11/109107.htm

Ubuntu 15.04 下安装 Docker  http://www.linuxidc.com/Linux/2015-07/120444.htm

在 Ubuntu Trusty 14.04 (LTS) (64-bit)安装 Docker http://www.linuxidc.com/Linux/2014-10/108184.htm

在 Ubuntu 15.04 上如何安装 Docker 及基本用法 http://www.linuxidc.com/Linux/2015-09/122885.htm

Ubuntu 16.04 上 Docker 使用手记 http://www.linuxidc.com/Linux/2016-12/138490.htm

Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-03/141581.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计4319字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中