由于aufs并未并入内核,故而目前只有Ubuntu系统上能够使用aufs作为docker的存储引擎,而其他系统上使用lvm thin provisioning(overlayfs是一个和aufs类似的union filesystem,未来有可能进入内核,但目前还没有;Lvm snapshot are useful for doing e.g. backup of a snapshot, but regress badly in performance when you start having many snapshots of the same device.)。为了实现lvm thin provisioning,docker启动时会设置一个100G的sparse文件(/var/lib/docker/devicemapper/devicemapper/data,元数据为/var/lib/docker/devicemapper/devicemapper/metadata),并将其作为devicemapper的存储池,而所有容器都从该存储池中分配默认10G的存储空间使用,如下图所示:
 
比如创建一个apache容器时devicemapper处理流程如下所示:
 
  1. Create a snapshot of the base device.
  2. Mount it and apply the changes in the fedora image.
  3. Create a snapshot based on the fedora device.
  4. Mount it and apply the changes in the apache image.
  5. Create a snapshot based on the apache device.
  6. Mount it and use as the root in the new container.
 
thin provisioning管理
 
使用lvm工具来创建一个thin pool:
 
dd if=/dev/zero of=lvm.img bs=1M count=100
losetup /dev/loop7 lvm.img
losetup -a
pvcreate /dev/loop7
vgcreate lvm_pool /dev/loop7
# create thin pool
lvcreate -L 80M -T lvm_pool/thin_pool
# create volume in thin pool
lvcreate -T lvm_pool/thin_pool -V 500M -n first_lv
 
docker启动时创建的默认存储池:
#dmsetup table docker-253:1-138011042-pool
0 209715200 thin-pool 7:2 7:1 128 32768 1 skip_block_zeroing    # 209715200*512/1024/1024/1024=100GB
 
当启动容器后,会从该池中分配10G出来:
#dmsetup table docker-253:1-138011042-641cdebd22b55f2656a560cd250e661ab181dcf2f5c5b78dc306df7ce62231f2
0 20971520 thin 253:2 166    # 20971520*512/1024/1024/1024=10GB
该10G存储的分配过程为:
dmsetup message /dev/mapper/docker-253:1-138011042-pool 0 "create_thin 166"
dmsetup create docker-253:1-138011042-641cdebd22b55f2656a560cd250e661ab181dcf2f5c5b78dc306df7ce62231f3 --table "0 20971520 thin /dev/mapper/docker-253:1-138011042-pool 166"
 
创建快照:
dmsetup suspend /dev/mapper/thin
dmsetup message /dev/mapper/yy_thin_pool 0 "create_snap 1 0"
dmsetup resume /dev/mapper/thin
dmsetup create snap --table "0 40960 thin /dev/mapper/yy_thin_pool 1"
 
docker服务在启动的时候可以配置devicemapper的启动参数,docker -d --storage-opt dm.foo=bar,可选参数有以下几个:
 
  1. dm.basesize 默认为10G,限制容器和镜像的大小
  2. dm.loopdatasize 存储池大小,默认为100G
  3. dm.datadev 存储池设备,默认生成一个/var/lib/docker/devicemapper/devicemapper/data文件
  4. dm.loopmetadatasize 元数据大小,默认为2G
  5. dm.metadatadev 元数据设备,默认生成一个/var/lib/docker/devicemapper/devicemapper/metadata文件
  6. dm.fs 文件系统,默认ext4
  7. dm.blocksize blocksize默认64K
  8. dm.blkdiscard 默认true

最后看看启动一个容器后,该容器的配置是如何组织的。
 
每个容器创建后都会将其基本配置写入到/var/lib/docker/containers/中:

#ls /var/lib/docker/containers/49f19ee979f6bf125c62779dcabf3bdce310b13d22e5c826752db202e509154e -l
total 20
-rw------- 1 root root 0 Nov 18 16:31 49f19ee979f6bf125c62779dcabf3bdce310b13d22e5c826752db202e509154e-json.log
-rw-r--r-- 1 root root 1741 Nov 18 16:31 config.json
-rw-r--r-- 1 root root 368 Nov 18 16:31 hostconfig.json
-rw-r--r-- 1 root root 13 Nov 18 16:31 hostname
-rw-r--r-- 1 root root 175 Nov 18 16:31 hosts
-rw-r--r-- 1 root root 325 Nov 18 16:31 resolv.conf
分配10G空间后会将容器存储配置写入到以下两个文件中:
# cd /var/lib/docker
#cat ./devicemapper/metadata/49f19ee979f6bf125c62779dcabf3bdce310b13d22e5c826752db202e509154e-init
{"device_id":174,"size":10737418240,"transaction_id":731,"initialized":false}
#cat ./devicemapper/metadata/49f19ee979f6bf125c62779dcabf3bdce310b13d22e5c826752db202e509154e 
{"device_id":175,"size":10737418240,"transaction_id":732,"initialized":false}
而容器的rootfs会mount到/var/lib/docker/devicemapper/mnt/container_id下:
#mount | grep 49f1
/dev/mapper/docker-253:1-138011042-49f19ee979f6bf125c62779dcabf3bdce310b13d22e5c826752db202e509154e on /var/lib/docker/devicemapper/mnt/49f19ee979f6bf125c62779dcabf3bdce310b13d22e5c826752db202e509154e type ext4 (rw,relatime,discard,stripe=16,data=ordered)
 
 
参考文档
 

docker存储结构解析的更多相关文章

  1. Java的HashMap键值对存储结构解析

    容器总体结构 Map存储键值对的数据结构是“数组+链表”的结构,结合了数组查询数据快和链表增删数据快的优点:用Entry[]存储键值对,Entry为类类型,类里面有四个属性:hash.K.V.next ...

  2. Docker镜像文件存储结构

    docker相关文件存放在:/var/lib/docker目录下 镜像的存储结构主要分两部分,一是镜像ID之间的关联,一是镜像ID与镜像名称之间的关联,前者的结构体叫Graph,后者叫TagStore ...

  3. SQL SERVER大话存储结构(5)_SQL SERVER 事务日志解析

          本系列上一篇博文链接:SQL SERVER大话存储结构(4)_复合索引与包含索引    1 基本介绍 每个数据库都具有事务日志,用于记录所有事物以及每个事物对数据库所作的操作. 日志的记录 ...

  4. Hadoop HDFS本地存储目录结构解析

    转自:https://blog.csdn.net/superman_xxx/article/details/51689398 HDFS metadata以树状结构存储整个HDFS上的文件和目录,以及相 ...

  5. 理解Docker(8):Docker 存储之卷(Volume)

    (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 (4)Docker 容器的隔离性 - 使用 ...

  6. 理解Docker(7):Docker 存储 - AUFS

    (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 (4)Docker 容器的隔离性 - 使用 ...

  7. InnoDB引擎的索引和存储结构

    在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的.而MySql数据库提供了多种存储引擎.用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据 ...

  8. SQL Server 表和索引存储结构

    在上一篇文章中,我们介绍了SQL Server数据文件的页面类型,系统通过96个字节的头部信息和系统表从逻辑层面上将表的存储结构管理起来,具体到表的存储结构上,SQL Server引入对象.分区.堆或 ...

  9. H.264码流结构解析

    from:http://wenku.baidu.com/link?url=hYQHJcAWUIS-8C7nSBbf-8lGagYGXKb5msVwQKWyXFAcPLU5gR4BKOVLrFOw4bX ...

随机推荐

  1. VS2010,Qt插件安装使用

    用了几次的QtCreateor,不习惯. 果断换回VS 基本步骤: 1.安装VS2010 2.安装Qt Creator5 3.安装Qt插件 qt-vs-addin-1.2.2-opensource 就 ...

  2. http://zh.lucida.me/

    一个很厉害的在美国Google的学长的博客

  3. google vr开源 cardboard

    https://developers.google.com/cardboard/android/ 待续

  4. 探索软件工程道路上的我 IV (Θ∀Θ#)

    开发语言:Java 开发工具:UltraEdit 小伙伴博客:http://www.cnblogs.com/hyating/ github地址:https://github.com/JUNYU217/ ...

  5. 如何在MATLAB R2010a 中使用Visual C++ 2010编译器

    安装补丁VS2012MEXSupport.zip http://www.mathworks.com/matlabcentral/answers/93013-how-can-i-use-microsof ...

  6. Html 开发工具 之Hbulider

    下载地址 : 百度搜索该名字即可 或 点击此处 选择  文件->新建Web项目 输入项目名称即可  如下图 它会自动生成一些 文件夹 或文件,不需要的删除即可.

  7. Pyhon环境搭建-window

    1.安装python3.4.3版本 地址:(64位)https://www.python.org/ftp/python/3.4.3/python-3.4.3.amd64.msi (32位)http:/ ...

  8. Device eth0 does not seem to be present, delaying initialization(解决克隆CentOS6.3虚拟机后网卡设备无法启动问题)

    1.删除 /etc/udev/rules.d/70-persistent-net.rules 后重启机器 2.重新启动之后,把/etc/udev/rules.d/70-persistent-net.r ...

  9. 用UltraEdit软件替换回车换行的窍门

    转载:http://www.zhuantilan.com/jiqiao/46518.html 方法/步骤 1.打开一个原始文档,在文档中各个人物名称是以逗号分隔的,我们下面来尝试把逗号替换为换行符. ...

  10. Qt qtextstream读取文件

    今天发现一个很有用的类:qtextstream 这个类可以以文件句柄为构造函数 然后用readAll函数返回一个QString的字符串