OverlayFS是内核提供的文件系统,overlay和overlay2是docker的存储驱动

 

docker存储驱动介绍


docker支持多种graphDriver,包括vfs、devicemapper、overlay、overlay2、aufs等等,其中最常用的就是aufs了,但随着linux内核3.18把overlay纳入其中,overlay的地位变得更重。

OverlayFS是一个类似于AUFS 的现代联合文件系统,但更快,实现更简单。

Docker为OverlayFS提供了一个存储驱动程序。OverlayFS是内核提供的文件系统,overlayoverlay2docker提供的存储驱动

 

设置存储方式


/etc/docker/daemon.json

{
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}

 

overlay原理


OverlayFS将单个Linux主机上的两个目录合并成一个目录。这些目录被称为层,统一过程被称为联合挂载。

OverlayFS底层目录称为lowerdir, 高层目录称为upperdir。合并统一视图称为merged。当需要修改一个文件时,将文件从只读的Lower复制到可写的Upper进行修改,结果也保存在Upper层。在Docker中,底下的只读层就是image,可写层就是Container。

下图是一个docker镜像和docke容器的分层图,docker镜像是lowerdir,docker容器是upperdir。而统一的视图层是merged层。

overlay具有:上下合并、同名覆盖 、写时拷贝等特点,具体如下:

Lowerdir与Upperdir同名文件在 Merged中显示的只有Upperdir中的同名文件,不同名文件会合并在Merged中显示修改文件或目录策略:

        (1)若文件存在于Upperdir,则直接修改Upperdir中的文件

        (2)若文件只存在于Lowerdir,则先将文件从Lowerdir中拷贝至Upperdir再进行修改

在Merged层创建文件或目录,会直接在Upperdir层创建,在Merged层删除文件策略:

        (1)若文件只存在Upperdir层,则直接在Upprdir层删除文件

        (2)若文件存在Lowerdir层,则在Upperdir层创建一个同名的任何用户都没有任何权限,大小为0的字符设备

基于以上策略,Lowerdir层内容都不会被修改,使得在OverlayFS中,Lower可以是只读的,而Upper则需要是可读写的文件系统。
 

 

性能对比


使用overlay和overlay2驱动性能好于aufs和devicemapper,在实际生产环境overlay2的性能高于btrfs

  • 页缓存:overlayfs支持页缓存共享,也就是说如果多个容器访问同一个文件,可以共享同一个页缓存。这使得overlay/overlay2驱动高效地利用了内存
  • copy_up:aufs和overlayfs,由于第一次写入都会导致copy_up,尤其是大文件,会导致写延迟,以后的写入不会有问题。由于overlayfs层级比aufs的多,所以ovelayfs的拷贝高于aufs
  • inode限制:使用overlay存储驱动可能导致inode过度消耗,特别是当容器和镜像很多的情况下,所以建议使用overlay2.

 

高性能建议


  • 使用高性能磁盘如:SSD
  • 如果是高IO:建议使用外挂高性能盘

但 overlay2驱动程序本身最多支持128个较低的OverlayFS层。此功能可为与层相关的Docker命令(如docker buildand)提供更好的性能docker commit,并在后备文件系统上占用更少的inode。

overlay2镜像结构


​在路径/var/lib/docker/overlay2/下,每个镜像层都有一个对应的目录,包含了该层镜像的内容

 

overlay2 容器结构


启动一个容器,也是在/var/lib/docker/overlay2目录下生成一层容器层,目录包括diff,link,lower,merged,work,diff记录每一层自己内容的数据,link记录该层链接目录(实际是目录下到层的链接),比如在容器中创建目录或在diff新增该目录 

[root@jenkins merged]# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED       STATUS       PORTS      NAMES
fc219fc9d337   java-demo:latest   "/bin/sh -c 'java -X…"   2 hours ago   Up 2 hours   8000/tcp   java-demo

[root@je 4d1f5c7f5cb4df1aaba9bcafd0175d08003cc6a00f4648f910b34e76d2d28d17]# ls
diff  link  lower  merged  work
[root@je 4d1f5c7f5cb4df1aaba9bcafd0175d08003cc6a00f4648f910b34e76d2d28d17]# cd merged/

[root@jenkins merged]# ls
bin  demo.jar  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var 

 

实战


创建如下几个目录:

[root@localhost tmp]#  mkdir -p lower upper merger worker
[root@localhost tmp]# ll
total 0
drwxr-xr-x 2 root root 6 Jul 20 17:11 lower
drwxr-xr-x 2 root root 6 Jul 20 17:11 merger
drwxr-xr-x 2 root root 6 Jul 20 17:11 upper
drwxr-xr-x 2 root root 6 Jul 20 17:11 worker

创建内容如下:

[root@localhost lower]# echo '1.txt lower' >1.txt
[root@localhost lower]# echo '3.txt lower' >3.txt


[root@localhost upper]# echo '1.txt upper' >1.txt
[root@localhost upper]# echo '2.txt upper' >2.txt

[root@localhost tmp]# tree
.
├── lower
│   ├── 1.txt
│   └── 3.txt
├── merger
├── upper
│   ├── 1.txt
│   └── 2.txt
└── worker

加载overlay支持,嵌入式可在内核编译时用make menuconfig配置overlay支持

[root@localhost tmp]# modprobe overlay

创建overlay

[root@localhost tmp]# mount -n -t overlay overlayfs:/overlay -o lowerdir=lower/,upperdir=upper/,workdir=worker/ merger/ 

创建完后结果(可看出merger层的文件是lower层和upper层的不同名文件合并,同名的文件为upper层文件覆盖

[root@localhost tmp]# tree 
.
├── lower
│   ├── 1.txt
│   └── 3.txt
├── merger
│   ├── 1.txt
│   ├── 2.txt
│   └── 3.txt
├── upper
│   ├── 1.txt
│   └── 2.txt
└── worker
    └── work

[root@localhost tmp]# cd merger/
[root@localhost merger]# cat 1.txt 
1.txt upper

(1)在merger中创建文件

[root@localhost merger]# echo 'meger' > meger1.txt
[root@localhost merger]# cd ..
[root@localhost tmp]# tree 
.
├── lower
│   ├── 1.txt
│   └── 3.txt
├── merger
│   ├── 1.txt
│   ├── 2.txt
│   ├── 3.txt
│   └── meger1.txt
├── upper
│   ├── 1.txt
│   ├── 2.txt
│   └── meger1.txt
└── worker
    └── work

(2)在merger中修改文件(只有upper层发生改变了,lower层是一直不变的)


[root@localhost merger]# echo "change 1.txt in meger"> 1.txt 
[root@localhost merger]# cat ../upper/1.txt 
change 1.txt in meger
[root@localhost merger]# cat ../lower/1.txt 
1.txt lower


[root@localhost merger]# echo 'change in  meger' > 3.txt
[root@localhost merger]# cat ../upper/3.txt 
change in  meger
[root@localhost merger]# cat ../lower/1.txt 
1.txt lower

(3)在merger中删除文件

[root@localhost merger]# rm -rf 1.txt 
[root@localhost merger]# cd ..
[root@localhost tmp]# tree 
.
├── lower
│   ├── 1.txt
│   └── 3.txt
├── merger
│   ├── 2.txt
│   ├── 3.txt
│   └── meger1.txt
├── upper
│   ├── 1.txt
│   ├── 2.txt
│   └── meger1.txt
└── worker
    └── work

[root@localhost upper]# cat 1.txt 
cat: 1.txt: No such device or address
[root@localhost upper]# cat ../lower/1.txt 
1.txt lower
Logo

更多推荐