专栏首页容器云生态overlayfs存储驱动的使用以及技术探究

overlayfs存储驱动的使用以及技术探究

overlayfs存储驱动的使用以及技术探究

1.overlayfs 基本概念

一种联合文件系统,设计简单,速度更快。overlayfs在linux主机上只有两层,一个目录在下层,用来保存镜像(docker),另外一个目录在上层,用来存储容器信息。在overlayfs中,底层的目录叫做lowerdir,顶层的目录称之为upperdir,对外提供统一的文件系统为merged。 当需要修改一个文件时,使用CoW将文件从只读的Lower复制到可写的Upper进行修改,结果也保存在Upper层。在Docker中,底下的只读层就是image,可写层就是Container。

可以看到镜像层和容器层可以保存相同的文件,容器层的文件会覆盖镜像层的文件

  • 在overlayfs中每个镜像层都会在/var/lib/docker/overlay有对应的目录,使用硬链接与底层数据进行关联。

2. 优势劣势

  • 1.OverlayFS支持页缓存共享,多个容器访问同一个文件能共享一个页缓存,以此提高内存使用
  • 2.OverlayFS消耗inode,随着镜像和容器增加,inode会遇到瓶颈。Overlay2能解决这个问题。在Overlay下,为了解决inode问题,可以考虑将/var/lib/docker挂在单独的文件系统上,或者增加系统inode设置。

3. overlay中的读写

3.1 在容器中读取文件

  • (1)目标文件不在容器层内,overlay会从镜像层读取文件,此时,对容器性能的影响很小。
  • (2)目标文件在容器层内,overlay直接从容器层读取。
  • (3)目标文件在容器层和镜像层同时存在,overlay读入容器层中的文件,此时容器层的文件会覆盖镜像层的文件。

3.2 在容器中修改文件

在容器中第一次修改文件,此时文件不在容器层中。overlay会把文件从镜像层复制到容器层,所有该文件中的修改都保存在容器层中。

注意:overlay工作文件系统层(devicemapper工作再块层面),因此复制文件会复制整个文件,因此在频繁读写会很消耗资源

  • (1)只是在第一次修改文件时,需要把文件从镜像层复制到容器层,后续操作都是在容器层中完成。
  • (2)overlayfs只有两层,lowerdir和upperdir,因此在很深的目录树中,搜索文件会相对比较快

3.3 在容器中删除文件和目录

在容器中删除文件时,overlay存储驱动在容器层中新建一个without文件,该文件用语隐藏镜像层中的目标文件。在容器层删除目录时,overlay存储驱动在容器层新建一个opaque目录,该目录用于隐藏镜像层中的目标目录。 需要明白的一点是,任何存储驱动都不会删除底层image中的目标文件和目录的。

3.4 overlayfs的原理测试

overlayfs挂载后系统文件的page cache是全部共享的。

# mkdir low upper work
# ls
low  upper  work
# echo 'abs' > low/11.txt
# echo 'xuxuebiao' > upper/22.txt
# mkdir merged
# mount -t overlay overlay -olowerdir=./low,upperdir=./upper,workdir=./work ./merged
# ls
low  merged  upper  work
# cd merged/
# ls
11.txt  22.txt
# ll
total 8
-rw-r--r--. 1 root root  4 Mar 27 18:57 11.txt
-rw-r--r--. 1 root root 10 Mar 27 18:58 22.txt

# tree
.
├── low
│   └── 11.txt
├── merged
│   ├── 11.txt
│   └── 22.txt
├── upper
│   └── 22.txt
└── work
    └── work

5 directories, 4 files
可以看到,merged目录中时low和upper目录联合的结果


分别修改文件:
# cat 11.txt
abs
# cat 22.txt
xuxuebiao
# vim 11.txt
# cat 11.txt
Hello ,overlayfs!
# cat ../low/11.txt
abs
# cat ../upper/
11.txt   11.txt~  22.txt
# cat ../upper/11.txt
Hello ,overlayfs!
# cat ../upper/11.txt~
cat: ../upper/11.txt~: No such device or address
# cat ../upper/11.txt
11.txt   11.txt~
# cat ../upper/11.txt~
cat: ../upper/11.txt~: No such device or address

可以看到low目录下的文件没有变化,但是upper里面的文件内容已经改变,并且有了一个11.txt~文件


# ls -i ../upper/11.txt 11.txt
143902921 11.txt  143902921 ../upper/11.txt
可以看到upper和merged目录中的两个文件11.txt的inode其实是一致的,其实是硬链接

# ls -i ../low/11.txt 11.txt
143902921 11.txt  143902918 ../low/11.txt
merged目录文件和low目录文件对比


删除文件测试:
# rm 11.txt
rm: remove regular file ‘11.txt’? y
# ls
ls: cannot access 11.txt: No such file or directory
ls: cannot access 11.txt~: No such file or directory
11.txt  11.txt~  22.txt

# cat ../upper/11.txt~
cat: ../upper/11.txt~: No such device or address
# ls -l ../upper/11.txt
c---------. 1 root root 0, 0 Mar 27 19:08 ../upper/11.txt

删除文件后发现文件无法访问,底层变成了一个大小为0,且没有任何人有权限的一个空文件。
overlayfs用这种删除标记的方式标识文件被删除,(如果upper中没有该文件的话,则底层low中的同名文件又恢复出来显示了,因此需要有这个空文件来标识删除,并且覆盖底层的文件)

4.overlayfs在docker中的使用

首先,overlayfs是在高版本的内核上才支持的存储驱动,因此不管使用的官方内核,还是自己patch的内核,首先需要检查overlayfs是否被加载

overlayfs

并且同样重要的是,对于aufs和overlay的实现,用来读取或执行共享库的共享内存也在所有运行的容器之间共享,大大的减少了通用库如’libc’的内存占用。这是一个分层策略的巨大优势,同时也是Docker的graphdriver是引擎中相当重要的一部分的原因之一。graphdriver的功能作用。

  • 1.检查overlay是否被加载
查看overlay是否被加载
$ lsmod | grep overlay
查看内核是否支持overlay模块
$ modinfo overlayfs
加载内核模块
$ modprobe overlayfs
  • 2.docker启动参数修改
检测overlayfs释放被识别,成功启动后修改参数到默认的配置文件中
$ docker daemon(dockerd) -s overlay(--storage-driver=overlay) 

修改配置文件
$ cat /etc/sysconfig/docker.conf
DOCKER_OPTS="--storage-driver=overlay"

模拟配置:
other_args="-s overlay --graph=/export/lib/docker -H unix:///var/run/docker.sock --bip 10.0.0.1/24 -H 0.0.0.0:5256  --api-enable-cors=true"
  • 3.检验overlayfs是否成功启动
$ sudo /etc/init.d/docker restart
成功启动,查看存储信息:
$ sudo docker info
Containers: 11
Images: 5
Server Version: 1.9.1
Storage Driver: overlay
 Backing Filesystem: extfs
Execution Driver: native-0.2
Logging Driver: json-file
Kernel Version: 2.6.32-431.el6.x86_64
Operating System: <unknown>
CPUs: 32
Total Memory: 126 GiB
Name: -----
ID: 2IER:NO5S:4NKX:ULDJ:THGQ:GBNR:NIN6:SCXG:SMFX:PG72:JAQF:GRZW

可用看到相关存储驱动是overlay,文件系统是extfs
  • 4.overlay在docker上面的使用

默认docker会将容器以及镜像相关的文件存储在/var/lib/docker/overlay目录下

sh-4.1# docker  images
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos6.8-sshd   latest              42c75e16533e        12 weeks ago        402 MB
sh-4.1# pwd  (这里我们是配置了存储路径)
/export/lib/docker/overlay

sh-4.1# ll -t
total 28
drwx------ 4 root root 4096 Mar 31 10:37 8ab8690b0769d07cc0b546112cfc40068d99298ed7e1857272c98a522cede527
drwx------ 4 root root 4096 Mar 31 10:37 8ab8690b0769d07cc0b546112cfc40068d99298ed7e1857272c98a522cede527-init
drwx------ 3 root root 4096 Mar 31 10:35 42c75e16533e2ef46ffd22a21318d354b3f3e520709230e9848ebaca8f1f514e
drwx------ 3 root root 4096 Mar 31 10:35 b46ba152cc17054229bc0099e7fda8b34958d518ce687c0d378b4832c4d8c91e
drwx------ 3 root root 4096 Mar 31 10:35 9016bb11dc9b4a3ee23fbef484cf5b3c9b80491e87d67092febec45759baeb4f
drwx------ 3 root root 4096 Mar 31 10:35 ea80c789cb2b3bcc1d12b9b3226c8482a06f28e94a4a49f8e201b5e9cdbdf0cc
drwx------ 3 root root 4096 Mar 31 10:35 e444e2175366cd3507bc9278d9a68a7b7ca5759b364bfe960fc12a87f219e847

可用看到我们现在有一个image,id为42c75e16533e,overlay会把该镜像的所有父镜像存储到本地(image的分层缓存),该image共5层。
sh-4.1# docker  inspect 42c75e16533e | grep b46ba152cc1
    "Parent": "b46ba152cc17054229bc0099e7fda8b34958d518ce687c0d378b4832c4d8c91e",
sh-4.1# docker  inspect b46ba152cc1 | grep 9016bb11dc9b4a
    "Parent": "9016bb11dc9b4a3ee23fbef484cf5b3c9b80491e87d67092febec45759baeb4f",
sh-4.1# docker  inspect 9016bb11dc9b4a | grep ea80c789cb2
    "Parent": "ea80c789cb2b3bcc1d12b9b3226c8482a06f28e94a4a49f8e201b5e9cdbdf0cc",
sh-4.1# docker  inspect ea80c789cb2 | grep e444e2175366cd35
    "Parent": "e444e2175366cd3507bc9278d9a68a7b7ca5759b364bfe960fc12a87f219e847",
sh-4.1# docker  inspect e444e2175366cd35 | grep Parent
    "Parent": "",
sh-4.1#


由下面示例可以看到容器id 8ab8690b07,实际上是使用image 42c75e16533e 启动起来的一个container,并给出了container 的LowerDir:`/export/lib/docker/overlay/42c75e16533e2ef46ffd22a21318d354b3f3e520709230e9848ebaca8f1f514e/root`

sh-4.1# docker inspect 8ab8690b07 | grep Parent
        "CgroupParent": "",
sh-4.1# docker inspect 8ab8690b07 | grep 42c75e1653
    "Image": "42c75e16533e2ef46ffd22a21318d354b3f3e520709230e9848ebaca8f1f514e",
            "LowerDir": "/export/lib/docker/overlay/42c75e16533e2ef46ffd22a21318d354b3f3e520709230e9848ebaca8f1f514e/root",
        "Image": "42c75e16533e",
sh-4.1#

查看容器内部的存储结构:
sh-4.1# ls 8ab8690b0769d07cc0b546112cfc40068d99298ed7e1857272c98a522cede527/
lower-id  merged/   upper/
容器的存储里面默认会存放三个文件,lower-id纪录的是image的id,也就是上面提到的LowerDir,其次存在merged和upper目录,分别为容器层,和容器最终看到的merged层。overlayfs中的lower,upper,merged三者的关系看文首。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • heartbeat+lvs构建高可用负载均衡集群

    heartbeat+lvs实现高可用负载均衡原理: 两台heartbeat(ldirectord)主机构成高可用集群,同时监管着lvs(负载均衡集群)整体构成了...

    BGBiao
  • awk-grep-sed简单使用总结(正则表达式的应用)

    正则表达式: 匹配一组字符: #[ns]a.\.xls  //[]用于限定字符;“.”用于匹配任意字符; \.用于转义"." 匹配到s/na*.xls  [n...

    BGBiao
  • Golang单元测试入门实践总结

    单元测试是程序开发者适用一段代码来验证另外一段代码写的是否符合预期的一种相对高效的自我测试方法。

    BGBiao
  • 程序员专用的抢票小助手,再也不用担心抢不到车票了。

    马上临近过年了,漂泊在远方的朋友,也都准备陆续抢过年回家的车票了,但是往年每次不管是十一假期还是年关,大家也都知道这时候买票是特别难买到的。本来辛辛苦苦干了一年...

    杰哥的IT之旅
  • 一种生产环境Docker Overlay Network的配置方案

    到manager节点上创建attachable的overlay network,名字叫做prod-overlay:

    颇忒脱
  • 深入正则表达式(3):正则表达式工作引擎流程分析与原理释义

    作为正则的使用者也一样,不懂正则引擎原理的情况下,同样可以写出满足需求的正则,但是不知道原理,却很难写出高效且没有隐患的正则。所以对于经常使用正则,或是有兴趣深...

    周陆军
  • Python学习 Day 13 IO编程 (最后一篇 明天换教材)

    要以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符:

    统计学家
  • 网络编程—tcp

    TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议...

    py3study
  • Linux进价命令

    sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲...

    呼延十
  • 针对Memcached缓存服务器的渗透测试方法介绍

    在之前的文章中,我向大家介绍了如何在Ubuntu 18.04上配置Memcached Server,来构建我们自己的渗透测试实验环境。而本文我们将学习多种利用M...

    FB客服

扫码关注云+社区

领取腾讯云代金券