热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Docker存储原理

Docker存储可以分为分层文件系统和卷,本文将介绍AUFS分层文件系统。1.基础知识1.1Linux的rootfs和bootfs一个典型的Linux系统要能运行
Docker 存储可以分为分层文件系统和卷,本文将介绍 AUFS 分层文件系统。

1. 基础知识


1.1 Linux 的 rootfs 和 bootfs

  一个典型的 Linux 系统要能运行的话,它至少需要两个文件系统:

  • boot file system (bootfs):包含 boot loader 和 kernel。用户不会修改这个文件系统。实际上,在启动(boot)过程完成后,整个内核都会被加载进内存,此时 bootfs 会被卸载掉从而释放出所占用的内存。同时也可以看出,对于同样内核版本的不同的 Linux 发行版的 bootfs 都是一致的。
  • root file system (rootfs):包含典型的目录结构,包括 /dev, /proc, /bin, /etc, /lib, /usr, and /tmp 等再加上要运行用户应用所需要的所有配置文件,二进制文件和库文件。这个文件系统在不同的Linux 发行版中是不同的。而且用户可以对这个文件进行修改。

Linux 系统在启动时,roofs 首先会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了。

1.2 AUFS

 AUFS 是一种 Union File System(联合文件系统),又叫 Another UnionFS,后来叫Alternative UnionFS,再后来叫成高大上的 Advance UnionFS。所谓 UnionFS,就是把不同物理位置的目录合并mount到同一个目录中。UnionFS的一个最主要的应用是,把一张CD/DVD和一个硬盘目录给联合 mount在一起,然后,你就可以对这个只读的CD/DVD上的文件进行修改(当然,修改的文件存于硬盘上的目录里)。

  举个例子,在 Ubuntu 14.04 系统上现有如下目录结构:

$ tree
.
├── fruits
│ ├── apple
│ └── tomato
└── vegetables├── carrots└── tomato


输入以下几个命令:

# 创建一个mount目录
$ mkdir mnt# 把水果目录和蔬菜目录union mount到 .
/mnt目录中
$ sudo mount
-t aufs -o dirs=./fruits:./vegetables none ./mnt# 查看./mnt目录
$ tree .
/mnt
.
/mnt
├── apple
├── carrots
└── tomato


我们可以看到在./mnt目录下有三个文件,苹果apple、胡萝卜carrots和蕃茄tomato。水果和蔬菜的目录被union到了./mnt目录下了。

我们来修改一下其中的文件内容:

$ echo mnt > ./mnt/apple
$ cat .
/mnt/apple
mnt
$ cat .
/fruits/apple
mnt

上面的示例,我们可以看到./mnt/apple的内容改了,./fruits/apple的内容也改了。

$ echo mnt_carrots > ./mnt/carrots
$ cat .
/vegetables/carrots$ cat ./fruits/carrots
mnt_carrots

关于 AUFS 的几个特点:

  • AUFS 是一种联合文件系统,它把若干目录按照顺序和权限 mount 为一个目录并呈现出来
  • 默认情况下,只有第一层(第一个目录)是可写的,其余层是只读的。
  • 增加文件:默认情况下,新增的文件都会被放在最上面的可写层中。
  • 删除文件:因为底下各层都是只读的,当需要删除这些层中的文件时,AUFS 使用 whiteout 机制,它的实现是通过在上层的可写的目录下建立对应的whiteout隐藏文件来实现的。
  • 修改文件:AUFS 利用其 CoW (copy-on-write)特性来修改只读层中的文件。AUFS 工作在文件层面,因此,只要有对只读层中的文件做修改,不管修改数据的量的多少,在第一次修改时,文件都会被拷贝到可写层然后再被修改。
  • 节省空间:AUFS 的 CoW 特性能够允许在多个容器之间共享分层,从而减少物理空间占用。
  • 查找文件:AUFS 的查找性能在层数非常多时会出现下降,层数越多,查找性能越低,因此,在制作 Docker 镜像时要注意层数不要太多。
  • 性能:AUFS 的 CoW 特性在写入大型文件时第一次会出现延迟。

本部分内容主要应用自 Docker基础技术:AUFS。 

2. Docker 文件系统


2.1 Docker 镜像的 rootfs

  前面基础知识部分谈到过,同一个内核版本的所有 Linux 系统的 bootfs 是相同的,而 rootfs 则是不同的。在 Docker 中,基础镜像中的 roofs 会一直保持只读模式,Docker 会利用 union mount 来在这个 rootfs 上增加更多的只读文件系统,最后它们看起来就像一个文件系统即容器的 rootfs。

 (图片来源)

可见在一个Linux 系统之中,

  • 所有 Docker 容器都共享主机系统的 bootfs 即 Linux 内核
  • 每个容器有自己的 rootfs,它来自不同的 Linux 发行版的基础镜像,包括 Ubuntu,Debian 和 SUSE 等
  • 所有基于一种基础镜像的容器都共享这种 rootfs

以 training/webapp 镜像为例,

root@docker1:/var/lib/docker/aufs/diff/b2188d5c09cfe24acd6da5ce67720f81138f0c605a25efc592f1f55b3fd3dffa# docker history training/webapp
IMAGE CREATED CREATED BY SIZE COMMENT
6fae60ef3446
16 months ago /bin/sh -c #(nop) CMD ["python" "app.py"] 0 B
16 months ago /bin/sh -c #(nop) EXPOSE 5000/tcp 0 B
16 months ago /bin/sh -c #(nop) WORKDIR /opt/webapp 0 B
16 months ago /bin/sh -c #(nop) ADD dir:9b2a69f6f30d18b02b5 703 B
16 months ago /bin/sh -c pip install -qr /tmp/requirements. 4.363 MB
16 months ago /bin/sh -c #(nop) ADD file:c59059439864153904 41 B
16 months ago /bin/sh -c DEBIAN_FRONTEND=noninteractive apt 135.3 MB
16 months ago /bin/sh -c apt-get update 20.8 MB
16 months ago /bin/sh -c #(nop) MAINTAINER Docker Education 0 B
17 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
17 months ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/ 1.895 kB
17 months ago /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic 194.5 kB
17 months ago /bin/sh -c #(nop) ADD file:f4d7b4b3402b5c53f2 188.1 MB


它是基于 Ubuntu Docker 基础镜像。在基础镜像层中,我们能看到完整的 Ubuntu rootfs:

root@docker1:/var/lib/docker/aufs/diff/b2188d5c09cfe24acd6da5ce67720f81138f0c605a25efc592f1f55b3fd3dffa# ls -l
total
76
drwxr
-xr-x 2 root root 4096 Apr 27 2015 bin
drwxr
-xr-x 2 root root 4096 Apr 11 2014 boot
drwxr
-xr-x 3 root root 4096 Apr 27 2015 dev
drwxr
-xr-x 61 root root 4096 Apr 27 2015 etc
drwxr
-xr-x 2 root root 4096 Apr 11 2014 home
drwxr
-xr-x 12 root root 4096 Apr 27 2015 lib
drwxr
-xr-x 2 root root 4096 Apr 27 2015 lib64
drwxr
-xr-x 2 root root 4096 Apr 27 2015 media
drwxr
-xr-x 2 root root 4096 Apr 11 2014 mnt
drwxr
-xr-x 2 root root 4096 Apr 27 2015 opt
drwxr
-xr-x 2 root root 4096 Apr 11 2014 proc
drwx
------ 2 root root 4096 Apr 27 2015 root
drwxr
-xr-x 7 root root 4096 Apr 27 2015 run
drwxr
-xr-x 2 root root 4096 Apr 27 2015 sbin
drwxr
-xr-x 2 root root 4096 Apr 27 2015 srv
drwxr
-xr-x 2 root root 4096 Mar 13 2014 sys
drwxrwxrwt
2 root root 4096 Apr 27 2015 tmp
drwxr
-xr-x 10 root root 4096 Apr 27 2015 usr
drwxr
-xr-x 11 root root 4096 Apr 27 2015 var


我们来看两种典型的文件:

(1)bin 目录中的文件会被直接使用

root@docker1:/var/lib/docker/aufs/diff# find -iname mountpoint
.
/b2188d5c09cfe24acd6da5ce67720f81138f0c605a25efc592f1f55b3fd3dffa/bin/mountpoint

(2)在基础镜像层中 proc 目录为空,也就是说容器中看到的 proc 目录中的文件是后来生成的。

2.2 Docker 使用的 AUFS 文件系统

  关于 Docker的分层镜像,除了 aufs,docker还支持btrfs, devicemapper和vfs,你可以使用 -s 或 –storage-driver= 选项来指定相关的镜像存储。在Ubuntu 14.04下,Docker 默认 Ubuntu的 AUFS。因为 AUFS 还没有进入Linux 内核主干的原因,RedHat 上使用的是 devicemapper。

  我们可以在 docker info 命令的输出中查看所使用的存储驱动:

Storage Driver: aufsRoot Dir: /var/lib/docker/aufsBacking Filesystem: extfsDirs: 19Dirperm1 Supported: false

以一个正在运行着的 Docker 容器为例,其镜像有13层:

"RootFS": {"Type": "layers","Layers": ["sha256:1154ba695078d29ea6c4e1adb55c463959cd77509adf09710e2315827d66271a","sha256:528c8710fd95f61d40b8bb8a549fa8dfa737d9b9c7c7b2ae55f745c972dddacd","sha256:37ee47034d9b78f10f0c5ce3a25e6b6e58997fcadaf5f896c603a10c5f35fb31","sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef","sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef","sha256:b75c0703b86b8ccbdc1f1b28b4982774768861ac250f83bdb940b1e90291f302","sha256:5c121779bb29172c628a21087ea8ced766959da2f223c8b6bd4ffe943ace43d8","sha256:3ee91c5cb95b01496b4afdc721ba7fd3c22e0e5e2f3e9e70d3f8579b5082d4f3","sha256:6bbb1d0f845289217e20b66697fa7d651394d89983b0f5a89b88f037194476fe","sha256:b44b0832d4c6bf33122ce3aa896b133df88275e6d20663a9bf2d941f764ac1fd","sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef","sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef","sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"]}


从 AUFS 的角度,可以看到有一个可写的容器层和14个只读的镜像层:

root@docker1:/sys/fs/aufs/si_ab487e40195df24f# cat *
/var/lib/docker/aufs/diff/2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab=rw #可写的容器层
/var/lib/docker/aufs/diff/2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab-init=ro+wh #本层及以下是只读的镜像层
/var/lib/docker/aufs/diff/5472f8388f9a61f6bd84498201a5ad71a2ec88cda16c42a3a1da7c30da45f102=ro+wh
/var/lib/docker/aufs/diff/61dcf0881e790bf52ec555727b58641791adeefadcc7abc2a77fd228bde1371a=ro+wh
/var/lib/docker/aufs/diff/f68672aaf17dd158aabc635b2d8d459d79db1cd5ff38bf3834fe8f9c7a05235e=ro+wh
/var/lib/docker/aufs/diff/45818d286499870412357d66eb6af951699f89db785c7c6a242d2e1ac99734f9=ro+wh
/var/lib/docker/aufs/diff/b2188d5c09cfe24acd6da5ce67720f81138f0c605a25efc592f1f55b3fd3dffa=ro+wh
/var/lib/docker/aufs/diff/85cb840562788e1b458e68265e62fd2da9d0d7e737256500e8a276bcb237183c=ro+wh
/var/lib/docker/aufs/diff/c18ba8efcb455e97f6aabe3985b147f6a37b8f5ad090373e88ddd326b4f90896=ro+wh
/var/lib/docker/aufs/diff/25de7dcc3a06f0caa3c701d4ed6c62f03e0757f6d477cc822db6e884bb366441=ro+wh
/var/lib/docker/aufs/diff/ad9e831217594cdfecd5e824690b0e52f2e16d6e2bb39b7143e66d467150cfe8=ro+wh
/var/lib/docker/aufs/diff/56d37c8eecd8be9ba13e07e1486e7a6ac2f0aa01f8e865ee6136137369d8d8a0=ro+wh
/var/lib/docker/aufs/diff/31bc6290457af4e560a3103020c85fbb5dfcfb201b0662a33165260529f87c07=ro+wh
/var/lib/docker/aufs/diff/e104672666119006648d0b82988c49527e52c64629750c5c9adde88acc790682=ro+wh
/var/lib/docker/aufs/diff/7a085e415855435121fb7837c26a5e951f622bc69364d9228d409a4929b627e1=ro+wh


根据上面 AUFS 的定义,容器的文件系统是从 14 个只读镜像层和1个可写容器层通过 AUFS mount 出来的。示意图如下:

(图片来源)

这种分层文件系统可以通过官网的图来清晰的展示出来:

做一些实验:

(1)在容器中创建一个文件,该文件会被创建在可写的容器层中

root@docker1:/var/lib/docker/aufs/diff# find -iname createdbysammy
.
/2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab/opt/webapp/createdbysammy
root@docker1:
/var/lib/docker/aufs/diff# ls -lt
total
60
drwxr
-xr-x 9 root root 4096 Oct 4 22:37 2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab
drwxr
-xr-x 6 root root 4096 Oct 1 11:56 2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab-init

(2)修改一个镜像层中的文件

修改前,文件 /etc/apt/sources.list 出现在两个层中:

root@docker1:/var/lib/docker/aufs/diff# find -iname sources.list
.
/f68672aaf17dd158aabc635b2d8d459d79db1cd5ff38bf3834fe8f9c7a05235e/etc/apt/sources.list
.
/b2188d5c09cfe24acd6da5ce67720f81138f0c605a25efc592f1f55b3fd3dffa/etc/apt/sources.list

在容器中对它进行修改后,它被拷贝到了容器层然后被修改了:

root@docker1:/var/lib/docker/aufs/diff# find -iname sources.list
.
/f68672aaf17dd158aabc635b2d8d459d79db1cd5ff38bf3834fe8f9c7a05235e/etc/apt/sources.list
.
/2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab/etc/apt/sources.list
.
/b2188d5c09cfe24acd6da5ce67720f81138f0c605a25efc592f1f55b3fd3dffa/etc/apt/sources.list

而另外两个层中的文件保持了不变。这说明了 AUFS 的 CoW 特性。

(3)删除容器层中的文件

容器中的文件 ./usr/local/lib/python2.7/dist-packages/itsdangerous.py 位于 56d37c8eecd8be9ba13e07e1486e7a6ac2f0aa01f8e865ee6136137369d8d8a0 层中,这是一个只读层。

在容器内删除它:

root@fa385836d5b9:/# find -iname itsdangerous.py
.
/usr/local/lib/python2.7/dist-packages/itsdangerous.py
root@fa385836d5b9:
/# rm ./usr/local/lib/python2.7/dist-packages/itsdangerous.py
root@fa385836d5b9:
/# find -iname itsdangerous.py

然后,容器层中出现了一个 .wh 文件,而镜像层中的文件保持不变:

root@docker1:/var/lib/docker/aufs/diff# find -iname *itsdangerous.py
.
/56d37c8eecd8be9ba13e07e1486e7a6ac2f0aa01f8e865ee6136137369d8d8a0/usr/local/lib/python2.7/dist-packages/itsdangerous.py
.
/2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab/usr/local/lib/python2.7/dist-packages/.wh.itsdangerous.py

在手工将 .wh 文件删除后,文件就会再次回到容器中。

rm ./2ee58d81e4ac6811bbc78beb4b46bf213c79c9e2dc7e441741afc8c4349c6bab/usr/local/lib/python2.7/dist-packages/.wh.itsdangerous.py


root@fa385836d5b9:/# find -iname itsdangerous.py
.
/usr/local/lib/python2.7/dist-packages/itsdangerous.py





转自:http://www.cnblogs.com/sammyliu/p/5931383.html


推荐阅读
  • EzPP 0.2发布,新增YAML布局渲染功能
    EzPP发布了0.2.1版本,新增了YAML布局渲染功能,可以将YAML文件渲染为图片,并且可以复用YAML作为模版,通过传递不同参数生成不同的图片。这个功能可以用于绘制Logo、封面或其他图片,让用户不需要安装或卸载Photoshop。文章还提供了一个入门例子,介绍了使用ezpp的基本渲染方法,以及如何使用canvas、text类元素、自定义字体等。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • Ubuntu安装常用软件详细步骤
    目录1.GoogleChrome浏览器2.搜狗拼音输入法3.Pycharm4.Clion5.其他软件1.GoogleChrome浏览器通过直接下载安装GoogleChro ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Ubuntu 9.04中安装谷歌Chromium浏览器及使用体验[图文]
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 本文讨论了在Linux系统中,使用chown命令将django项目目录下的static目录的拥有者从root改为eureka的问题。作者尝试了多种命令,包括chown和sudo chown等,但都没有成功修改拥有者。文章提供了相关目录的权限信息,并补充了项目所在磁盘和操作系统的信息。 ... [详细]
  • 分享css中提升优先级属性!important的用法总结
    web前端|css教程css!importantweb前端-css教程本文分享css中提升优先级属性!important的用法总结微信门店展示源码,vscode如何管理站点,ubu ... [详细]
  • 本文介绍了在Ubuntu系统中清理残余配置文件和无用内容的方法,包括清理残余配置文件、清理下载缓存包、清理不再需要的包、清理无用的语言文件和清理无用的翻译内容。通过这些清理操作可以节省硬盘空间,提高系统的运行效率。 ... [详细]
author-avatar
mobiledu2502886333
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有