会东| 临沭| 柳城| 阜康| 梁平| 汉阳| 五华| 石泉| 怀集| 彭阳| 温县| 壤塘| 玛多| 任县| 嘉善| 漳州| 荔波| 茌平| 邵阳县| 宁陵| 称多| 佳县| 黄岛| 库伦旗| 杨凌| 阳新| 徐州| 石嘴山| 萨迦| 梅县| 固安| 塘沽| 库伦旗| 宁阳| 望谟| 甘南| 墨玉| 新乡| 高县| 理县| 柯坪| 鲁甸| 涟源| 井陉矿| 建水| 永济| 四方台| 临夏县| 南宫| 广安| 旺苍| 正安| 岱岳| 贵池| 和顺| 汉川| 嘉黎| 江永| 冠县| 汶上| 江苏| 左贡| 安义| 博湖| 琼山| 河北| 纳溪| 温县| 徐水| 余江| 武邑| 乌拉特前旗| 芒康| 乐至| 句容| 兰考| 东营| 东光| 西乡| 南芬| 大竹| 望江| 阳西| 兰西| 郁南| 东安| 临泉| 西平| 安国| 斗门| 怀柔| 丰镇| 承德县| 和平| 达孜| 武定| 徽县| 德阳| 维西| 灌云| 庆云| 昭苏| 古丈| 崂山| 南安| 三门峡| 行唐| 二连浩特| 双城| 铜陵市| 安泽| 永泰| 桑植| 美溪| 合浦| 神池| 高阳| 攀枝花| 朝阳市| 略阳| 新邱| 玉山| 云浮| 东阿| 茶陵| 唐山| 龙游| 阜新市| 大姚| 孝昌| 桓台| 邢台| 东平| 洪江| 库车| 门源| 宜宾县| 金乡| 冠县| 隆德| 金昌| 合山| 武鸣| 牡丹江| 平山| 登封| 顺德| 大通| 宜君| 环江| 青浦| 西平| 锡林浩特| 高雄市| 饶平| 平邑| 平利| 甘谷| 仲巴| 榕江| 蓝田| 长兴| 龙胜| 富锦| 松溪| 博山| 海阳| 武当山| 奉贤| 化隆| 吉安市| 新邱| 八达岭| 富裕| 峨眉山| 泾源| 繁峙| 孝昌| 仙桃| 衡东| 唐山| 吉林| 阿瓦提| 通城| 恩施| 同心| 永泰| 盂县| 云霄| 禹城| 仙桃| 清涧| 武功| 临澧| 班戈| 中卫| 开鲁| 阳谷| 菏泽| 牟定| 渝北| 鹤岗| 静乐| 克拉玛依| 巴马| 应城| 西吉| 南康| 崇明| 新干| 曲阳| 丹阳| 咸阳| 楚州| 仁怀| 阳西| 郏县| 围场| 察雅| 滁州| 刚察| 高雄县| 团风| 索县| 山丹| 克山| 南汇| 道县| 和硕| 宜黄| 平邑| 依兰| 彭阳| 永胜| 鄯善| 诸城| 黄岩| 普洱| 彬县| 北票| 凤城| 中牟| 姚安| 单县| 隆子| 丰都| 温县| 柯坪| 巴中| 南漳| 咸阳| 昌邑| 富县| 启东| 永城| 博白| 宝丰| 宜宾县| 余江| 台湾| 临海| 滨州| 满洲里| 赵县| 拉斯维加斯线上赌博
|
|
51CTO旗下网站
|
|
移动端

一步步了解 Docker 存储驱动

在说docker的文件系统之前,我们需要先想清楚一个问题。我们知道docker的启动是依赖于image,docker在启动之前,需要先拉取image,然后启动。多个容器可以使用同一个image启动。

作者:breezey来源:容器和大数据前沿技术|2019-01-24 10:04

镜像的分层特性

在说docker的文件系统之前,我们需要先想清楚一个问题。我们知道docker的启动是依赖于image,docker在启动之前,需要先拉取image,然后启动。多个容器可以使用同一个image启动。那么问题来了:这些个容器是共用一个image,还是各自将这个image复制了一份,然后各自独立运行呢?

我们假设每个容器都复制了一份这个image,然后各自独立运行,那么就意味着,启动多少个容器,就需要复制多少个image,毫无疑问这是对空间的一种巨大浪费。事实上,在容器的设计当中,通过同一个Image启动的容器,全部都共享这个image,而并不复制。那么问题又随之而来:既然所有的容器都共用这一个image,那么岂不是我在任意一个容器中所做的修改,在其他容器中都可见?如果我一个容器要将一个配置文件修改成A,而另一个容器同样要将这个文件修改成B,两个容器岂不是会产生冲突?

我们把上面的问题放一放,先来看下面一个拉取镜像的示例:

  1. root@ubuntu:~# docker pull nginx  
  2. Using default tag: latest  
  3. latest: Pulling from library/nginx  
  4. be8881be8156: Pull complete  
  5. 32d9726baeef: Pull complete  
  6. 87e5e6f71297: Pull complete  
  7. Digest: sha256:6ae5dd1664d46b98257382fd91b50e332da989059482e2944aaa41ae6cf8043a  
  8. Status: Downloaded newer image for nginx:latest 

上面的示例是从docker官方镜像仓库拉取一个nginx:latest镜像,可以看到在拉取镜像时,是一层一层的拉取的。事实上镜像也是这么一层一层的存储在磁盘上的。通常一个应用镜像包含多层,如下:

我们首先需要明确一点,镜像是只读的。每一层都只读。在上图上,我们可以看到,在内核之上,最底层首先是一个基础镜像层,这里是一个ubuntu的基础镜像,因为镜像的只读特性,如果我们想要在这个ubuntu的基础镜像上安装一个emacs编辑器,则只能在基础镜像之上,在构建一层新的镜像层。同样的道理,如果想要在当前的emacs镜像层之上添加一个apache,则只能在其上再构建一个新的镜像层。而这即是镜像的分层特性。

容器读写层的工作原理

我们刚刚在说镜像的分层特性的时候说到镜像是只读的。而事实上当我们使用镜像启动一个容器的时候,我们其实是可以在容器里随意读写的,从结果上看,似乎与镜像的只读特性相悖。

我们继续看上面的图,其实可以看到在镜像的最上层,还有一个读写层。而这个读写层,即在容器启动时为当前容器单独挂载。每一个容器在运行时,都会基于当前镜像在其最上层挂载一个读写层。而用户针对容器的所有操作都在读写层中完成。一旦容器销毁,这个读写层也随之销毁。

知识点: 容器=镜像+读写层而我们针对这个读写层的操作,主要基于两种方式:写时复制和用时分配。

写时复制

所有驱动都用到的技术——写时复制(CoW)。CoW就是copy-on-write,表示只在需要写时才去复制,这个是针对已有文件的修改场景。比如基于一个image启动多个Container,如果为每个Container都去分配一个image一样的文件系统,那么将会占用大量的磁盘空间。而CoW技术可以让所有的容器共享image的文件系统,所有数据都从image中读取,只有当要对文件进行写操作时,才从image里把要写的文件复制到自己的文件系统进行修改。所以无论有多少个容器共享同一个image,所做的写操作都是对从image中复制到自己的文件系统中的复本上进行,并不会修改image的源文件,且多个容器操作同一个文件,会在每个容器的文件系统里生成一个复本,每个容器修改的都是自己的复本,相互隔离,相互不影响。使用CoW可以有效的提高磁盘的利用率。

用时配置

用时分配是用在原本没有这个文件的场景,只有在要新写入一个文件时才分配空间,这样可以提高存储资源的利用率。比如启动一个容器,并不会为这个容器预分配一些磁盘空间,而是当有新文件写入时,才按需分配新空间。

Docker存储驱动

接下来我们说一说,这些分层的镜像是如何在磁盘中存储的。

docker提供了多种存储驱动来实现不同的方式存储镜像,下面是常用的几种存储驱动:

  • AUFS
  • OverlayFS
  • Devicemapper
  • Btrfs
  • ZFS

下面说一说AUFS、OverlayFS及Devicemapper:

AUFS

AUFS(AnotherUnionFS)是一种Union FS,是文件级的存储驱动。AUFS是一个能透明覆盖一个或多个现有文件系统的层状文件系统,把多层合并成文件系统的单层表示。简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。这种文件系统可以一层一层地叠加修改文件。无论底下有多少层都是只读的,只有最上层的文件系统是可写的。当需要修改一个文件时,AUFS创建该文件的一个副本,使用CoW将文件从只读层复制到可写层进行修改,结果也保存在可写层。在Docker中,底下的只读层就是image,可写层就是Container。结构如下图所示:

OverlayFS

Overlay是Linux内核3.18后支持的,也是一种Union FS,和AUFS的多层不同的是Overlay只有两层:一个upper文件系统和一个lower文件系统,分别代表Docker的镜像层和容器层。当需要修改一个文件时,使用CoW将文件从只读的lower复制到可写的upper进行修改,结果也保存在upper层。在Docker中,底下的只读层就是image,可写层就是Container。目前最新的OverlayFS为Overlay2。结构如下图所示:

Devicemapper

Device mapper是Linux内核2.6.9后支持的,提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。前面讲的AUFS和OverlayFS都是文件级存储,而Device mapper是块级存储,所有的操作都是直接对块进行操作,而不是文件。Device mapper驱动会先在块设备上创建一个资源池,然后在资源池上创建一个带有文件系统的基本设备,所有镜像都是这个基本设备的快照,而容器则是镜像的快照。所以在容器里看到文件系统是资源池上基本设备的文件系统的快照,并没有为容器分配空间。当要写入一个新文件时,在容器的镜像内为其分配新的块并写入数据,这个叫用时分配。当要修改已有文件时,再使用CoW为容器快照分配块空间,将要修改的数据复制到在容器快照中新的块里再进行修改。Device mapper 驱动默认会创建一个100G的文件包含镜像和容器。每一个容器被限制在10G大小的卷内,可以自己配置调整。结构如下图所示:

常用存储驱动对比

AUFS VS OverlayFS

AUFS和Overlay都是联合文件系统,但AUFS有多层,而Overlay只有两层,所以在做写时复制操作时,如果文件比较大且存在比较低的层,则AUSF可能会慢一些。而且Overlay并入了linux kernel mainline,AUFS没有。目前AUFS已基本被淘汰。

OverlayFS VS Device mapper

OverlayFS是文件级存储,Device mapper是块级存储,当文件特别大而修改的内容很小,Overlay不管修改的内容大小都会复制整个文件,对大文件进行修改显示要比小文件要消耗更多的时间,而块级无论是大文件还是小文件都只复制需要修改的块,并不是整个文件,在这种场景下,显然device mapper要快一些。因为块级的是直接访问逻辑盘,适合IO密集的场景。而对于程序内部复杂,大并发但少IO的场景,Overlay的性能相对要强一些。

【编辑推荐】

  1. 关于私有云与存储风向的深度解读
  2. 杉岩与粤港澳大湾区金融创新研究院联合成立“智能存储实验室”
  3. Hive实践分享之存储和压缩的坑
  4. 存储芯片之战,中国厂商能否吹响胜利号角?
  5. 大数据存储的进化史 --从 RAID 到 Hdfs
【责任编辑:武晓燕 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

Cisco CCNA 640-802题库

Cisco 640-802 Cisco Certified Network Associate (CCNA) Testinside CCNA 640-802 V14 最新题库与Testinside CCNA 640-802 Q&A 192 ...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊
黄洞 大石岭村 庞各庄 元氏县 和平大街
人民广场东 银川路街道 二道沟乡 绿景居委会 西宝龙
现金游戏 威尼斯人官方网站 明升官网 四大赌场官网 威尼斯人网上
葡京网址导航 澳门大发888博彩娱乐 电子游艺 鸿博赌博网开户平台 澳门大发888赌场网站
神秘的梦电子游戏 威尼斯人网上真人赌场 澳门海立方网站 澳门百家乐必胜技巧 斗地主下载
澳门赌场 龙虎斗游戏娱乐 澳门葡京官网 澳门葡京 澳门威尼斯人平台
老虎机定位器 澳门大富豪网址 现金三公注册网址 牛牛游戏下载 现金骰宝 年度十大电子游戏 大小点游戏 玩什么游戏可以挣钱 电子游戏厅 方法奇葩赌博网 巴黎人网站 pt电子游戏哪个最会爆 澳门巴黎人游戏 澳门龙虎斗注册 澳门大富豪网站 押大小排行 真钱打牌 明升网站 十三水技巧 电子游戏下载 二十一点平台 现金网游戏开户平台 澳门百老汇游戏官网 皇博压大小 真钱捕鱼 跑马机游戏 赌博技巧 巴比伦赌场官网 现金三公 地下网址 捕鱼游戏技巧 英皇网站 手机玩游戏赚钱平台 现金网排行 pt电子游戏注册 赌博技巧 电脑玩游戏赚钱平台 海立方游戏 ag电子游戏排行 希尔顿官网 太阳网上压大小 现金赌钱游戏 现金棋牌游戏 真人网站网址 地下开户 九五至尊娱乐网址 澳门梭哈游戏官网 奇葩袖赌博网 鸿胜国际压大小 博狗扑克游戏 德州扑克游戏规则 庄闲代理 奔驰宝马老虎机下载 现金三公开户注册 免费试玩电子游戏 GT压大小 新濠天地注册 现金老虎机网站 纸牌赌博种类 乐天堂开户 澳门永利平台 电脑版捕鱼达人 玩电子游戏入门 斗牛游戏 bbin压大小 网上电子游戏网址 澳门网络下注平台 明升国际网址 明升娱乐 捕鱼达人电子游戏 mg电子游戏试玩 二十一点游戏赌场 澳门万利赌场官网 大小对比网站 现金电子游戏 电子游戏实用技术 老虎机破解器 澳门梭哈官网 澳门百老汇赌场注册 千炮捕鱼兑换现金 网上合法赌场 PT电子游戏 波克棋牌官方下载 天天棋牌 凤凰棋牌 美少女战士电子游戏 什么游戏可以赚人民币 银河国际娱乐 澳门番摊官网 澳门梭哈官网 胜博发电子游戏 电子游戏打鱼机 澳门现金网 大三巴网站 PT电子游戏 澳门银河国际娱乐