由于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安装后出现无法使用帮助的解决方案

    安装完VS2010后 再安装MSDN 打开“Help Library 管理器 - Microsoft Help 查看器 1.0” 提示“请为本地内容选择位置” 默认的位置是在“C:/Documents ...

  2. 查出重复的数据---------oracle

    select chcod, count(1) from a group by chcod having count(1) > 1

  3. C++ 11 Template ... 与Decltype 测试

    #include <iostream> #include "string" using namespace std; template<typename T> ...

  4. 初学SQL常用到的一些指令

    一.库 查看有哪些库:show databases; 进入某个库:use 库名; 新增库:create database atm; (atm为库名) 删除库:drop database if exis ...

  5. core Bluetooth(蓝牙4.0)

    蓝牙4.0以低功耗著称,一般也叫BLE(Bluetooth Low Energy). 目前主要应用的场景有:智能家居.运动手环和室内导航等. 利用core Bluetooth框架可以实现苹果设备与第三 ...

  6. Thinkpad T420 指纹开机 win10 解决方案

    以前没感觉笔记本上的指纹有什么用,后来无意看到了指纹能开机.便尝试把这个功能给用起来.果然麻烦了些. 1.官网上没有win10的指纹应用软件. 下载了win8的版本,安装后没有问题,可以登录win10 ...

  7. Those who are not capable of Control their moods are not supposed to be ready for their baby.

    I hate these Stupid Selfish People. We need Children Caring Organization.

  8. SQL server2000更改数据库名称

    如果是SQL Server 2005可以直接右键重命名,但是SQL Server 2000中不能直接改,可以用sp_renamedb. 1.方法一(物理法): 把Old数据库改为New数据库 打开“企 ...

  9. PHP Web Shell in browser

    /************************************************************************************* * PHP Web She ...

  10. Java编程经验——Long等包装类型判断

    int等基本数据类型的值是可以通过=或者!=进行比较的,但是对于Long等包装类型想比较其和某个值是否相等是不能通过=或者!=来比较的,那究竟要怎么样进行比较呢? if (null != projec ...