docker作为一个容器平台,它有一套自己的存储系统。它支持的driver有overlay,overlay2, aufs等等。

这篇文章主要分析overlay和overlay2的区别。

overlay

启动docker,删除本地所有的镜像。进入/var/lib/docker/overlay目录,可以看到此时这个目录下面什么都没有,是空的。

然后按照下面的Dockerfile制作一个镜像:

[root@localhost ~]# echo aa>>aa
[root@localhost ~]# echo bb>>bb
[root@localhost ~]# echo cc>>cc
[root@localhost ~]# cat Dockerfile
FROM ubuntu
COPY aa /
COPY bb /
COPY cc /
[root@localhost ~]# docker build -t aabbcc .
Sending build context to Docker daemon 478.8 MB
Step 1/4 : FROM ubuntu
 ---> 7698f282e524
Step 2/4 : COPY aa /
 ---> cb97dcb8731f
Removing intermediate container 894ff7c4e4bb
Step 3/4 : COPY bb /
 ---> f073ea1ca7f3
Removing intermediate container 857c5cf0e128
Step 4/4 : COPY cc /
 ---> 9ace6ecb0953
Removing intermediate container e2a682d5cd56
Successfully built 9ace6ecb0953

上面的一系列操作制作了一个名字为aabbcc的image。此时可以在/var/lib/docker/overlay 下面观察到新的层已经生成了。这里每copy一个文件就会生成新的一层。

下面的代码框中红色标记的部分就是我们copy了三个文件, aa, bb,cc所生成的三层。

[root@localhost overlay]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
aabbcc latest 9ace6ecb0953 14 hours ago 69.9 MB
docker.io/ubuntu latest 7698f282e524 4 weeks ago 69.9 MB
[root@localhost overlay]# docker history aabbcc
IMAGE CREATED CREATED BY SIZE COMMENT
9ace6ecb0953 14 hours ago /bin/sh -c #(nop) COPY file:a79ff676c1e17f... 3 B
f073ea1ca7f3 14 hours ago /bin/sh -c #(nop) COPY file:77c3ff995e3afe... 3 B
cb97dcb8731f 14 hours ago /bin/sh -c #(nop) COPY file:f17d63ff0a8d89... 3 B
7698f282e524 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing> 4 weeks ago /bin/sh -c mkdir -p /run/systemd && echo '... 7 B
<missing> 4 weeks ago /bin/sh -c rm -rf /var/lib/apt/lists/* 0 B
<missing> 4 weeks ago /bin/sh -c set -xe && echo '#!/bin/sh' >... 745 B
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:1f4fdc61e133d2f... 69.9 MB
[root@localhost overlay]#

观察一下/var/lib/docker/overlay/目录。aa文件出现了三次,bb文件出现了两次,cc文件只出现了一次,这也与我们拷贝它们的顺序相吻合。

层级结构一目了然。

[root@localhost overlay]# ls cfd414e52a3b25dade86fb2333d5cd84bb0632e55872914e42c0510cf7c211ea/root/
aa bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@localhost overlay]# ls 5b42d020f1bc93d2643e67c6fe7d86f3a20efd80767bf505853dd743d8b51a31/root/
aa bb bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@localhost overlay]# ls 00e5e192b42ad8923eda7d43016c56864fdb0c22c239cb141140c9959d138400/root/
aa bb bin boot cc dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

再观察一下几个aa文件的inode号

[root@localhost overlay]# find . -name aa|xargs ls -i
1057923 ./00e5e192b42ad8923eda7d43016c56864fdb0c22c239cb141140c9959d138400/root/aa 1057923 ./cfd414e52a3b25dade86fb2333d5cd84bb0632e55872914e42c0510cf7c211ea/root/aa
1057923 ./5b42d020f1bc93d2643e67c6fe7d86f3a20efd80767bf505853dd743d8b51a31/root/aa

我们可以看到,这里aa实际上是通过硬链接的方式链到不同的层里的。下面,我们尝试使用aabbcc运行一个容器。从中我们可以观察到,多出了一个aa文件,这实际上就是容器真正运行的rootfs(bfa602b98523bcc9d311e39729f1b4fd8a5046d5856b3d153886a67373a0f9f9/merged)。

通过mount指令,我们可以观察到内核将镜像和upper挂载到了指定的rootfs中了。

[root@localhost overlay]# find . -name aa|xargs ls -i
1057923 ./00e5e192b42ad8923eda7d43016c56864fdb0c22c239cb141140c9959d138400/root/aa 1057923 ./bfa602b98523bcc9d311e39729f1b4fd8a5046d5856b3d153886a67373a0f9f9/merged/aa
1057923 ./5b42d020f1bc93d2643e67c6fe7d86f3a20efd80767bf505853dd743d8b51a31/root/aa 1057923 ./cfd414e52a3b25dade86fb2333d5cd84bb0632e55872914e42c0510cf7c211ea/root/aa
[root@localhost overlay]# mount|grep overlay
/dev/mapper/fedora-root on /var/lib/docker/overlay type ext4 (rw,relatime,seclabel)
overlay on /var/lib/docker/overlay/bfa602b98523bcc9d311e39729f1b4fd8a5046d5856b3d153886a67373a0f9f9/merged type overlay (rw,relatime,context="system_u:object_r:container_file_t:s0:c286,c1020",lowerdir=/var/lib/docker/overlay/00e5e192b42ad8923eda7d43016c56864fdb0c22c239cb141140c9959d138400/root,upperdir=/var/lib/docker/overlay/bfa602b98523bcc9d311e39729f1b4fd8a5046d5856b3d153886a67373a0f9f9/upper,workdir=/var/lib/docker/overlay/bfa602b98523bcc9d311e39729f1b4fd8a5046d5856b3d153886a67373a0f9f9/work)
[root@localhost overlay]# ls

总结一下,overlay对于每一层都会构筑一个完整的镜像,镜像和镜像之间通过硬链接共享文件。当启动一个容器时,内核会union mount这个容器所

使用的镜像所对应的layer(lowerdir)和一个读写层(upperdir),并且lowerdir只有一层。

overlay2

用同样的Dockerfile构建一个叫aabbcc的image,观察/var/lib/docker/overlay2下面的文件,我们可以看到各个文件只有一个。

[root@localhost overlay2]# find . -name aa
./6e3c65cf94f4775224ee352074375629e368daaf9061681b08d2f5ab31c96a6d/diff/aa
[root@localhost overlay2]# find . -name bb
./6dd8011792252dea81cf322244e2ec78ced101c5b40c4750025d7b1aef7856f1/diff/bb
[root@localhost overlay2]# find . -name cc
./503efa11453748cadb1eaa7c0a2dde817047568d5ff7c255d0dfac885be6d557/diff/cc

进入到cc所在layer中,可以看到里面有四个文件/文件夹,diff里面存储了这一层所包含的文件,这里就只有cc这一个文件。link中存储的是这一层所对应的/var/lib/docker/overlay2/l/中的软连接。

lower文件中存储的是这一层所依赖的低层。它们用冒号隔开,每一条记录都是指向/var/lib/docker/overlay2/l/ 中的软连接。

[root@localhost 503efa11453748cadb1eaa7c0a2dde817047568d5ff7c255d0dfac885be6d557]# ls
diff link lower work
[root@localhost 503efa11453748cadb1eaa7c0a2dde817047568d5ff7c255d0dfac885be6d557]# tree
.
├── diff
│   └── cc
├── link
├── lower
└── work 2 directories, 3 files
[root@localhost 503efa11453748cadb1eaa7c0a2dde817047568d5ff7c255d0dfac885be6d557]# cat link
JYJ3FGGMPXESBF7GQL72HXOXRV
[root@localhost 503efa11453748cadb1eaa7c0a2dde817047568d5ff7c255d0dfac885be6d557]# cat lower
l/C35GLEH6TWWOAX4BIZE6VT5KYG:l/7ODJACACJZTVZHL26VDQWAX3RS:l/2M2BNBIKMH7INTTHG2DVXM2YTM:l/2TH4LWHZM3V7UAVOSTQS6KY25A:l/52C2E2ZTZQUNS7YEWOIVT7RUOK

下面我们尝试运行一个容器,然后观察overlay2的挂载情况:

[root@localhost overlay2]# find . -name aa|xargs ls -i
./6e3c65cf94f4775224ee352074375629e368daaf9061681b08d2f5ab31c96a6d/diff/aa ./9151b049c61baa18cc19f2b2afddc12e08fac0f24af7f5d3a0f803a605482558/merged/aa
[root@localhost overlay2]# mount|grep overlay
overlay on /var/lib/docker/overlay2/9151b049c61baa18cc19f2b2afddc12e08fac0f24af7f5d3a0f803a605482558/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/MPGCJYXEJSAZHETJT64ETIGTZJ:/var/lib/docker/overlay2/l/JYJ3FGGMPXESBF7GQL72HXOXRV:/var/lib/docker/overlay2/l/C35GLEH6TWWOAX4BIZE6VT5KYG:/var/lib/docker/overlay2/l/7ODJACACJZTVZHL26VDQWAX3RS:/var/lib/docker/overlay2/l/2M2BNBIKMH7INTTHG2DVXM2YTM:/var/lib/docker/overlay2/l/2TH4LWHZM3V7UAVOSTQS6KY25A:/var/lib/docker/overlay2/l/52C2E2ZTZQUNS7YEWOIVT7RUOK,upperdir=/var/lib/docker/overlay2/9151b049c61baa18cc19f2b2afddc12e08fac0f24af7f5d3a0f803a605482558/diff,workdir=/var/lib/docker/overlay2/9151b049c61baa18cc19f2b2afddc12e08fac0f24af7f5d3a0f803a605482558/work)

从中可以看到,这个容器的rootfs是挂载到一个lowerdi为多层的rootfs上的。

总结

综上所述,overlay实际上通过硬链接在层和层之间共享文件,而overlay2的每一层都是完全独立的。如果容器启动的话,它会将多层lowerdir 挂载到它的rootfs。

这种设计就会带来一个问题,那就是linux系统会限制系统中硬链接的数量,如果用户下载了很多容器,那么docker就会在系统中到处创建硬链接,达到最大值后将无法创建新容器。

因此,我们应该使用overlay2作为docker的graph driver而不是overlay

overlay和overlay2的区别的更多相关文章

  1. [docker]存储驱动overlay和overlay2的区别

    overlay和overlay2的区别 参考:http://blog.csdn.net/styshoo/article/details/60715942 docker pull ubuntu 本质区别 ...

  2. Docker的OverlayFS存储驱动

    OverlayFS存储驱动 OverlayFS是一个现代的Union Filesystem,类似于AUFS,但速度更快,实现更简单.Docker为OverlayFS提供了两个存储驱动程序:overla ...

  3. [转帖]overlay文件系统解析

    overlay文件系统解析 来源:http://dockone.io/article/1511 原作者: 陈爱珍 布道师@七牛云 一个 overlay 文件系统包含两个文件系统,一个 upper 文件 ...

  4. Docker存储驱动之OverlayFS简介

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

  5. Docker存储驱动之总览

    简介 本文会介绍Docker存储驱动的特性,别列出现在已经支持的存储驱动,最后,会介绍如果选型适合你的存储驱动. 可插拔的存储驱动架构 Docker的存储驱动架构是可插拔的,可以让你很方便的将适合你环 ...

  6. 转-4年!我对OpenStack运维架构的总结

    4年!我对OpenStack运维架构的总结 原创: 徐超 云技术之家 今天 前言 应“云技术社区”北极熊之邀,写点东西.思来想去云计算范畴实在广泛,自然就聊点最近话题异常火热,让广大云计算从业者爱之深 ...

  7. 理解Docker镜像分层

    关于base镜像 base 镜像有两层含义: 不依赖其他镜像,从 scratch 构建. 其他镜像可以之为基础进行扩展. 所以,能称作 base 镜像的通常都是各种 Linux 发行版的 Docker ...

  8. 史上最全docker基础知识汇总

    正文 Docker常用命令 run docker run [OPTIONS] IMAGE [COMMAND] [ARG...] -e设置环境变量:-e username=zhj --name为容器指定 ...

  9. 对OpenStack运维架构的总结(转)

    这里,仅从技术角度出发,谈谈OpenStack云平台在部署.架构和运维实施等方面的感想. 缘起,在2014年大二首次接触到OpenStack,当时国内外资料远没有当前这么丰富,为安装一个OpenSta ...

随机推荐

  1. 计算两个日期之间的天数差C++/java

    1--Java 分析:调用java中Calendar类 int days(Date date1,Date date2){ Calendar cal = new Calendar.getInstance ...

  2. 【转】一个java页游服务器框架

    源地址:http://www.cnblogs.com/metoy/p/4305326.html?utm_source=tuicool&utm_medium=referral 一.前言 此游戏服 ...

  3. 使用 Python 获取 Linux 系统信息

    探索platform模块 platform模块在标准库中,它有很多运行我们获得众多系统信息的函数.让我们运行Python解释器来探索它们中的一些函数,那就从platform.uname()函数开始吧: ...

  4. Struts2,get/set 自动获取/设置数据ActionSupport 类

    主页:http://struts.apache.org/在用户请求和模块化处理方面以及页面的展现这块,Struts2 发挥了强大的作用:相对于传统的Jsp+Servlet 模式,Struts2 更适合 ...

  5. Android获取系统时间yyyyMMddHHmmssSSS

    代码改变世界 public String testTime1() throws ParseException { String DEFAULT_TIME_FORMAT = "yyyy-MM- ...

  6. CSA Round 84 Growing Trees

    题目 题目大意 给定一棵有 $n$ 个节点的树,边的权值每天变化.对于第 $i$ 条边,在第 $0$ 天,其权值为 $c_i$,每天权值变化 $a_i$(即,在第 $k$ 天,其权值为 $c_i + ...

  7. HDU 3333 Turing Tree(离线树状数组)

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  8. js本地对象的操作

    1 String对象方法: concat 将两个或多个字符的文本组合起来,返回一个新的字符串. var a = "hello"; var b = ",world" ...

  9. 怎样在SQL2005中设置 自增长类型?

    原文发布时间为:2009-04-25 -- 来源于本人的百度文章 [由搬家工具导入] 最近好几个人问我。。。。。 企业管理器-->右键你的表-->设计表-->选中一int类型字段-- ...

  10. Android开发跳坑记录

    本文主要记录在Android开发中遇见的一些问题,以及解决方法. 2015.12.01 1.adb.exe 端口被占用 解决: http://blog.csdn.net/xiaanming/artic ...