主要回答的问题
- aufs原始的用途
- aufs的普通演示
- aufs在docker中的使用的演示
- aufs,overlays的架构
- 明白docker镜像的本质只是文件.
docker容器就是在镜像层上又增加了可读写的容器层,然后联合挂载到宿主机的一个挂载点上。使得运行时对容器的所有修改都只针对这个容器层,不影响镜像文件 - aufs缺点,overlays优点
- aufs没有加入linux内核, ubuntu默认支持,centos默认不支持。
设置CentOS支持aufs
[/sys/fs/aufs/目录]
-
/sys/fs目录 按照设计是用于描述系统中所有文件系统,包括文件系统本身和
按文件系统分类存放的已挂载点
,但目前只有 fuse,gfs2 等少数文件系统支持 sysfs 接口,一些传统的虚拟文件系统(VFS)层次控制参数仍然在 sysctl (/proc/sys/fs) 接口中中; -
使用 /sys 文件系统访问 Linux 内核
sysfs 虚拟文件系统提供了一种比 proc 更为理想的访问内核数据的途径
https://www.ibm.com/developerworks/cn/linux/l-cn-sysfs/index.html
root@192:/tmp/aufs# ls /sys/fs/
aufs bpf cgroup ecryptfs ext4 fuse pstore
root@192:/tmp/aufs# ls /sys/fs/ext4/
features sda1
root@192:/tmp/aufs# ls /sys/fs/aufs/
config si_e8bf3ef3161c9271
aufs的架构
- 只读层+读写层 mount> 宿主机的union挂载点, 作为容器的根目录。
只读层就是镜像,读写层是执行docker run时新增的容器层, 对容器的修改就是对union挂载点的修改,只影响读写层。
直接修改宿主机的挂载点,也就是修改容器的根目录,反之亦然。
aufs的关键技术
看起来这个虚拟后的联合文件系统是可以对任何文件进行操作的,但是其实它并没有改变原来的文件。这是因为 Union File System 用到了一个重要的资源管理技术:写时复制。
但是 aufs 出现的时间要比 docker 长很多,它常见的用法包括
参考附录1
- Linux 光盘演示和教程,录制了 Linux 的光盘可以用来让用户体验,但是光盘的内容是只读的,可以通过 aufs 把光盘和 U 盘或者磁盘 mount 到一起,用户对文件的修改保存到后面的存储上
- 如果系统上因为各种原因,不同用户的 home 目录保存在不同的路径和磁盘上,可以通过 aufs 把它们 mount 到一起,统一进行操作
AUFS演示
centos默认是没有启动aufs的,然后安装过程中出现了不少问题,所以就用ubuntu来演示了。
第一个例子
参考附录1
base 作为底层的目录
top 作为上层的目录
mnt: aufs 使用的挂载点,会把上面两个目录挂载到这里
第2个例子
参考附录2(包含图示讲解)
// 挂载后未修改时,container-layer目录有1个文件
root@192:/tmp/aufs# tree
.
├── container-layer
│ └── container-layer.txt
├── image-layer1
│ ├── image-layer1.txt
│ └── subdir1
│ └── subdir1.txt
├── image-layer2
│ ├── image-layer2.txt
│ └── subdir2
│ └── subdir2.txt
├── image-layer3
│ ├── image-layer3.txt
│ └── subdir3
│ └── subdir3.txt
├── mnt
│ ├── container-layer.txt
│ ├── image-layer1.txt
│ ├── image-layer2.txt
│ ├── image-layer3.txt
│ ├── subdir1
│ │ └── subdir1.txt
│ ├── subdir2
│ │ └── subdir2.txt
│ └── subdir3
│ └── subdir3.txt
└── run.sh
11 directories, 15 files
// 2. 对rw层(readwrite)的文件进行修改。直接修改。
root@192:/tmp/aufs# echo 666 > ./mnt/container-layer.txt
root@192:/tmp/aufs# cat container-layer/container-layer.txt
666
// 3. 对ro层(readonly)的文件进行修改。copy到rw读写层之后再wrtie。(copy on write)
root@192:/tmp/aufs# echo 777 > ./mnt/image-layer1.txt
root@192:/tmp/aufs# cat image-layer1/image-layer1.txt
I am image layer 1
root@192:/tmp/aufs# cat ./mnt/image-layer1.txt
777
// 4. 对ro层进行修改后的目录树,container-layer目录(rw层)增加了1个文件
root@192:/tmp/aufs# tree
.
├── container-layer
│ ├── container-layer.txt
│ └── image-layer1.txt // ydd:这是copy on write的文件
├── image-layer1
│ ├── image-layer1.txt
│ └── subdir1
│ └── subdir1.txt
├── image-layer2
│ ├── image-layer2.txt
│ └── subdir2
│ └── subdir2.txt
├── image-layer3
│ ├── image-layer3.txt
│ └── subdir3
│ └── subdir3.txt
├── mnt
│ ├── container-layer.txt
│ ├── image-layer1.txt
│ ├── image-layer2.txt
│ ├── image-layer3.txt
│ ├── subdir1
│ │ └── subdir1.txt
│ ├── subdir2
│ │ └── subdir2.txt
│ └── subdir3
│ └── subdir3.txt
└── run.sh
11 directories, 16 files
演示docker使用aufs作为storage driver
借助这个场景来理解:宿主机如何往运行中的docker容器中传输文件--Q: docker运行中的容器又是存在哪里的
AUFS的缺点
参考附录1
- 最大的问题是它不没有进入到 Linux 内核,因此不能保证可移植性,虽然像 ubuntu 这种发行版默认支持 aufs,但并不是所有系统都如此,比如
centos 就默认没有提供 aufs 支持
。之所以没有合并到内核,据说是因为 aufs 的实现代码很冗杂,Linus 认为代码质量太差,虽然开发者多次精简,最终还是没有进入到内核,而且在短时间内也不会有什么变化。 - 我们至少能看到两个性能问题:第一次修改一个大文件会非常耗时;另外层级过多也会影响整体的读写性能。
docker默认的存储驱动已经演进到了overlay2
-
overlay架构 / /附录5
-
附录3
虽然当前 docker 默认的存储驱动已经演进到了 overlay2,但是学习 AUFS 依然可以帮助我们深入理解 docker 中的文件系统。 -
附录4
在最新的 Docker 中,overlay2 取代了 aufs 成为了推荐的存储驱动,但是在没有 overlay2 驱动的机器上仍然会使用 aufs 作为 Docker 的默认驱动。
其他对容器镜像的理解
附录4
- Docker 镜像其实本质就是一个压缩包,我们可以使用下面的命令将一个 Docker 镜像中的文件导出:
- 容器和镜像的区别就在于,所有的镜像都是只读的,而每一个容器其实等于镜像加上一个可读写的层,也就是同一个镜像可以对应多个容器。