docker 存储驱动之 overlay2

摘要:
正如所声称的,OverlayFS仍然年轻。Docker的覆盖存储驱动程序使用许多OverlayFS功能来构建和管理图像和容器的磁盘结构。从Docker 1.12开始,Docker还支持overlay 2存储驱动程序。与覆盖层相比,覆盖层2在索引节点优化方面效率更高。然而,为了在本文中进行区分,我们使用OverlayFS表示整个文件系统,使用overlay/Overlay2表示Docker的存储驱动程序。
overlay2 简介

  OverlayFS是一种和AUFS很类似的文件系统,与AUFS相比,OverlayFS有以下特性: 
   1) 更简单地设计
   2) 从3.18开始,就进入了Linux内核主线
   3) 可能更快一些


  因此,OverlayFS在Docker社区关注度提高很快,被很多人认为是AUFS的继承者。就像宣称的一样,OverlayFS还很年轻。所以,在生成环境使用它时,还是需要更加当心。 
  Docker的overlay存储驱动利用了很多OverlayFS特性来构建和管理镜像与容器的磁盘结构。 


  自从Docker1.12起,Docker也支持overlay2存储驱动,相比于overlay来说,overlay2在inode优化上更加高效。但overlay2驱动只兼容Linux kernel4.0以上的版本。 


  注意:自从OverlayFS加入kernel主线后,它在kernel模块中的名称就被从overlayfs改为overlay了。但是为了在本文中区别,我们使用OverlayFS代表整个文件系统,而overlay/overlay2表示Docker的存储驱动。

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

这里写图片描述

overlay2原生支持128层,这提供docker build和docker commit更好的性能支持 
在执行完docker pull ubuntu后,可以看到

1 $ ls -l /var/lib/docker/overlay2
2 
3 total 24
4 drwx------ 5 root root 4096 Jun 20 07:36 223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7
5 drwx------ 3 root root 4096 Jun 20 07:36 3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b
6 drwx------ 5 root root 4096 Jun 20 07:36 4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1
7 drwx------ 5 root root 4096 Jun 20 07:36 e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5
8 drwx------ 5 root root 4096 Jun 20 07:36 eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed
9 drwx------ 2 root root 4096 Jun 20 07:36 l

这个 l 目录是新加的,这里面都是软连接文件目录的简写标识,这个主要是为了避免mount时候页大小的限制

1 $ ls -l /var/lib/docker/overlay2/l
2 
3 total 20
4 lrwxrwxrwx 1 root root 72 Jun 20 07:36 6Y5IM2XC7TSNIJZZFLJCS6I4I4 -> ../3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff
5 lrwxrwxrwx 1 root root 72 Jun 20 07:36 B3WWEFKBG3PLLV737KZFIASSW7 -> ../4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1/diff
6 lrwxrwxrwx 1 root root 72 Jun 20 07:36 JEYMODZYFCZFYSDABYXD5MF6YO -> ../eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed/diff
7 lrwxrwxrwx 1 root root 72 Jun 20 07:36 NFYKDW6APBCCUCTOUSYDH4DXAT -> ../223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7/diff
8 lrwxrwxrwx 1 root root 72 Jun 20 07:36 UL2MW33MSE3Q5VYIKBRN4ZAGQP -> ../e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5/diff

然后我们看看具体的目录下是什么,如果是最下面的是没有lower的

 1  ls /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/
 2 
 3 diff  link
 4 
 5 cat /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/link
 6 
 7 6Y5IM2XC7TSNIJZZFLJCS6I4I4
 8 
 9 
10 ls  /var/lib/docker/overlay2/3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b/diff
11 
12 bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

lower从第二次开始

 1 //最底层
 2 cat 72dd847f8c4a40ce1762353c216d32e18db433b17c65e61ee1558758631fb59f/lower
 3 cat: 72dd847f8c4a40ce1762353c216d32e18db433b17c65e61ee1558758631fb59f/lower: 没有那个文件或目录
 4 
 5 //倒数第二次层
 6 cat 91af527ebbb6357fb1694334be10105edd07432da7cb901ef17ecdaf28944442/lower
 7 l/YSWCORVIDFAIEIAFPP5AWBJZ5G
 8 
 9 //倒数第三次
10 cat 76bc3e1bdecdd1da6ecfea3086d7fecefa589e567da864fd5a4b910c04568bbb/lower
11 l/N7S5NM6TVQ4X7NFK7ROIQ6JOAP:l/YSWCORVIDFAIEIAFPP5AWBJZ5G
12 
13 //倒数第四底层
14 cat 6d7bdb155539b21b411fe5a4b7ebd41a7bc92dfb5d0158b961622dee834e19d0/lower
15 l/Q7UBZ47OWOXEF4YL5POZBJ3UKY:l/N7S5NM6TVQ4X7NFK7ROIQ6JOAP:l/YSWCORVIDFAIEIAFPP5AWBJZ5G
16 
17 //镜像最上层
18 cat c249bc61bf63b4f39b316b30f0dbe83bc6b9425f6fc92b28dd9b36bf80308f5e/lower
19 l/JF7WPJE6K6CN5A7SSJEYDWWWMA:l/Q7UBZ47OWOXEF4YL5POZBJ3UKY:l/N7S5NM6TVQ4X7NFK7ROIQ6JOAP:l/YSWCORVIDFAIEIAFPP5AWBJZ5G

通过lower标识了镜像的父层的分层关联关系

diff记录了本层的信息,

1 ll  91af527ebbb6357fb1694334be10105edd07432da7cb901ef17ecdaf28944442/diff/
2 
3 drwxr-xr-x 4 root root 4096 1月  26 02:23 etc
4 drwxr-xr-x 2 root root 4096 1月  26 02:23 sbin
5 drwxr-xr-x 3 root root 4096 1月  24 06:49 usr
6 drwxr-xr-x 3 root root 4096 1月  24 06:49 var

如果是容器层,还会多一个merge层,这个和overlay的merge的概念是一样的。譬如我启动一个容器,并在var目录下创建aaaa文件可以看到最上层的读写层

 1 ll a1d281675ce2eacb0617b989ae846e29b8890954b8917b2919fbd025f537d7a0/diff/var/
 2 
 3 -rw-r--r-- 1 root root 0 1月  31 12:23 aaaa
 4 
 5 
 6 ll a1d281675ce2eacb0617b989ae846e29b8890954b8917b2919fbd025f537d7a0/merged/var/
 7 
 8 -rw-r--r-- 1 root root    0 1月  31 12:23 aaaa
 9 drwxr-xr-x 2 root root 4096 4月  13 2016 backups
10 drwxr-xr-x 5 root root 4096 1月  24 06:49 cache
11 drwxr-xr-x 1 root root 4096 2月   5 2016 lib
12 drwxrwsr-x 2 root ftp  4096 4月  13 2016 local
13 lrwxrwxrwx 1 root root    9 1月  24 06:49 lock -> /run/lock
14 drwxr-xr-x 4 root root 4096 1月  24 06:49 log
15 drwxrwsr-x 2 root mem  4096 1月  24 06:49 mail
16 drwxr-xr-x 2 root root 4096 1月  24 06:49 opt
17 lrwxrwxrwx 1 root root    4 1月  24 06:49 run -> /run
18 drwxr-xr-x 2 root root 4096 1月  24 06:49 spool
19 drwxrwxrwt 2 root root 4096 1月  24 06:49 tmp

这里如果启动容器还有一点需要介绍,你会看到多了一个”读写层-init”,这个只读层,它的目的是为了初始化容器配置信息,譬如hostname等信息

1 ll a1d281675ce2eacb0617b989ae846e29b8890954b8917b2919fbd025f537d7a0-init/diff/etc/hostname 
2 -rwxr-xr-x 1 root root 0 1月  31 12:21 a1d281675ce2eacb0617b989ae846e29b8890954b8917b2919fbd025f537d7a0-init/diff/etc/hostname

查看mount信息

1  mount|grep overlay
2 overlay on /var/lib/docker/overlay2/a1d281675ce2eacb0617b989ae846e29b8890954b8917b2919fbd025f537d7a0/merged type 
3 overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/EETCZ74DSQUEXSCTWSVYKD6RSA:
4 /var/lib/docker/overlay2/l/MOZ5Z5Y6HVYMH2C5H4HCP64VPX:/var/lib/docker/overlay2/l/JF7WPJE6K6CN5A7SSJEYDWWWMA:
5 /var/lib/docker/overlay2/l/Q7UBZ47OWOXEF4YL5POZBJ3UKY:/var/lib/docker/overlay2/l/N7S5NM6TVQ4X7NFK7ROIQ6JOAP:
6 /var/lib/docker/overlay2/l/YSWCORVIDFAIEIAFPP5AWBJZ5G,
7 upperdir=/var/lib/docker/overlay2/a1d281675ce2eacb0617b989ae846e29b8890954b8917b2919fbd025f537d7a0/diff,
8 workdir=/var/lib/docker/overlay2/a1d281675ce2eacb0617b989ae846e29b8890954b8917b2919fbd025f537d7a0/work)

上面lowdir(只读层),第一个是最上层,譬如EETCZ74DSQUEXSCTWSVYKD6RSA,这个顺序很重要

容器使用overlay读写

  有三种场景,容器会通过overlay只读访问文件。 
    容器层不存在的文件。如果容器只读打开一个文件,但该容器不在容器层(upperdir),就要从镜像层(lowerdir)中读取。这会引起很小的性能损耗。 
    只存在于容器层的文件。如果容器只读权限打开一个文件,并且容器只存在于容器层(upperdir)而不是镜像层(lowerdir),那么直接从镜像层读取文件,无额外性能损耗。 
    文件同时存在于容器层和镜像层。那么会读取容器层的文件,因为容器层(upperdir)隐藏了镜像层(lowerdir)的同名文件。因此,也没有额外的性能损耗。 
  有以下场景容器修改文件。 
    第一次写一个文件。容器第一次写一个已经存在的文件,容器层不存在这个文件。overlay/overlay2驱动执行copy-up操作,将文件从镜像层拷贝到容器层。然后容器修改容器层新拷贝的文件。 
    然而,OverlayFS工作在文件级别而不是块级别。也就是说所有的OverlayFS的copy-up操作都会拷贝整个文件,即使文件非常大但却只修改了一小部分,这在容器写性能上有着显著的影响。不过,有两个方面值得注意: 
     ▷ copy-up操作只发生在第一次写文件时。后续的对同一个文件的写操作都是直接针对拷贝到容器层的那个新文件。 
     ▷ OverlayFS只工作在两层中。这比AUFS要在多层镜像中查找时性能要好。 
    删除文件和目录。删除文件时,容器会在镜像层创建一个whiteout文件,而镜像层的文件并没有删除。但是,whiteout文件会隐藏它。 
    容器中删除一个目录,容器层会创建一个不透明目录。这和whiteout文件隐藏镜像层的文件类似。 
    重命名目录。只有在源路径和目的路径都在顶层容器层时,才允许执行rename操作。否则,会返回EXDEV。 
    因此,你的应用需要能够处理EXDEV,并且回滚操作,执行替代的“拷贝和删除”策略。

免责声明:文章转载自《docker 存储驱动之 overlay2》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇2019 多益网络java面试笔试题 (含面试题解析)Informatica_(3)组件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Kubernetes 使用 Kubevirt 运行管理 Windows 10 操作系统

原文链接:https://fuckcloudnative.io/posts/use-kubevirt-to-manage-windows-on-kubernetes/ 最近我发现我的 Kubernetes 集群资源实在是太多了,有点浪费,不信你看: 既然闲置资源那么多,那我何不想办法利用一下。怎么用,用来干什么又是一个问题,想到我手中只有 MacBook...

MFS+Keepalived双机高可用热备方案操作记录

基于MFS的单点及手动备份的缺陷,考虑将其与Keepalived相结合以提高可用性。在Centos下MooseFS(MFS)分布式存储共享环境部署记录这篇文档部署环境的基础上,只需要做如下改动: 1)将master-server作为Keepalived_MASTER(启动mfsmaster、mfscgiserv) 2)将matelogger作为Keepa...

jimdb压测踩坑记

本文记录在jimdb压测过程中遇到的各种小坑,望能够抛砖引玉。 1.压测流量起来后,过了5分钟左右,发现ops突降,大概降了三分之一,然后稳定了下来 大概原因:此种情况,jimdb极有可能某个分片的连接数打满,从而导致分片的cpu达到100%。 调优方案:首先,默认分片连接数为1w,此时可以根据自己的需求,如果自己的docker数量很少,可以调整成2...

macOS下通过docker在局域网成功访问mysql5.6数据库

1.获取mysql镜像 docker pull mysql:5.6 注意:此处之所以获取mysql5.6是因为mysql5.7在centos7中启动可能会报错, 2.查看镜像列表 docker images 3.启动mysql镜像 docker run -itd -P mysql:5.6 bash 其中 docker run是启动容器的命令;i是交互式操...

wiki部署

一、准备环节 1.上传软件 [root@web01 tools]# tar xf jdk-8u60-linux-x64.tar.gz -C /application/ [root@web01 tools]# ln -s /application/jdk1.8.0_60/ /application/jdk 2.解压安装jdk [root@we...

4--Docker之Dockerfile镜像定制

目录 一、Dockerfile 镜像定制的使用 1.什么是Dockerfile? 2.基础知识 3.dockerfile指令说明 4.通过Dockerfile生成镜像 5.实战测试(构建自己的centos) 一、Dockerfile 镜像定制的使用 创建docker镜像的方式有两种: 手动修改容器内容,然后docker commit提交容器...