zoukankan      html  css  js  c++  java
  • Docker容器和镜像存储机制—images—目录树结构

    http://ju.outofmemory.cn/entry/114344


    Docker的存储机制采用了非常灵活的模块化设计,目前支持5种存储引擎,分别为aufs、btrfs、device mapper、vfs和overlay。它们的共同特点都是实现了graphdriver.Driver接口:

    点击(此处)折叠或打开

    1. type ProtoDriver interface {
    2.   String() string
    3.   //创建layer
    4.   Create(id, parent string) error
    5.   //删除layer
    6.   Remove(id string) error
    7.   //mount, 获取容器挂载点
    8.   Get(id, mountLabel string) (dir string, err error)
    9.   //umount文件系统
    10.   Put(id string)
    11.   Exists(id string) bool
    12.   Status() [][2]string
    13.   Cleanup() error
    14. }
    15.  
    16. type Driver interface {
    17.   ProtoDriver
    18.   Diff(id, parent string) (archive.Archive, error)
    19.   Changes(id, parent string) ([]archive.Change, error)
    20.   ApplyDiff(id, parent string, diff archive.ArchiveReader)(size int64,err error)
    21.   DiffSize(id, parent string) (size int64, err error)
    22. }

    所以,只要实现了存储驱动接口定义的方法,就可以扩展出一种存储引擎。想要更换存储引擎有两种方法:
    1. docker daemon进程启动时指定-s参数:docker –s aufs。
    2. 修改配置文件:DOCKER_OPTS=”–storage-driver=aufs”。

    在Docker存储模型中,bootfs同宿主机,rootfs则是由多个镜像层和一个容器层构成,其中镜像层只读,容器层可读写,多个镜像层之间有父子关系,下层作为上层镜像的父镜像,最下面的镜像称为base images(基础镜像),相关定义可以参考官网解释
    docker image layer

    aufs是Docker最早支持的一种存储引擎,它的工作机制和优缺点在前文『aufs文件系统』中已有介绍,aufs能将不同的目录挂载到某一目录下,将各个源目录下的内容联合到目标目录下,并可对不同目录进行权限控制。这个特性非常契合Docker的存储模型:
    1. 镜像分层模型对应aufs中的分支(源目录)。
    2. 镜像层对应aufs的ro分支,只读;容器层对应aufs的rw分支,可读写。

    默认配置下,Docker镜像和容器存储路径($DOCKROOT)位于/var/lib/docker,如果选择的是aufs文件系统作为存储引擎,那么它的子目录树结构(基于docker 1.4.1)应该如下:


    点击(此处)折叠或打开

    1. # tree .
    2. ├── aufs
    3. │ ├── diff 镜像和容器每层的差异内容
    4. │ ├── layers 镜像和容器每层的继承关系
    5. │ └── mnt 容器挂载点
    6. ├── containers 容器配置文件,环境变量和日志文件
    7. ├── graph 镜像详情、大小等
    8. └── repositories-aufs 镜像摘要

    举例说明,当前本地镜像库有一个ubuntu:14.04的镜像,它的层级关系如下:


    点击(此处)折叠或打开

    1. # docker images -t
    2. └─511136ea3c5a Virtual Size: 0 B
    3.   └─3b363fd9d7da Virtual Size: 192.5 MB
    4.     └─607c5d1cca71 Virtual Size: 192.7 MB
    5.       └─f62feddc05dc Virtual Size: 192.7 MB
    6.         └─8eaa4ff06b53 Virtual Size: 192.7 MB Tags: ubuntu:14.04

    那么在aufs/diff目录(相对于$DOCKROOT,下同)下会有以各个层级id命名的目录,每个目录存储着与它父镜像之间的差异:


    点击(此处)折叠或打开

    1. # ls -l aufs/diff/
    2. total 20
    3. drwxr-xr-x 21 3b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
    4. drwxr-xr-x 2 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
    5. drwxr-xr-x 6 607c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
    6. drwxr-xr-x 2 8eaa4ff06b53ff7730c4d7a7e21b4426a4b46dee064ca2d5d90d757dc7ea040a
    7. drwxr-xr-x 3 f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73

    aufs/layers目录下有以各个层级id命名的文件,文件内容为该层所有的祖先镜像id。例如


    点击(此处)折叠或打开

    1. # cat aufs/layers/8eaa4ff06b53ff7730c4d7a7e21b4426a4b...
    2. f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73
    3. c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
    4. b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
    5. ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158

    graph目录中存储的是每一层镜像的详细信息和大小:


    点击(此处)折叠或打开

    1. # tree graph/
    2. graph/
    3. ├── 3b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
    4. │ ├── json
    5. │ └── layersize
    6. ├── 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
    7. │ ├── json
    8. │ └── layersize
    9. ├── 607c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
    10. │ ├── json
    11. │ └── layersize
    12. ├── 8eaa4ff06b53ff7730c4d7a7e21b4426a4b46dee064ca2d5d90d757dc7ea040a
    13. │ ├── json
    14. │ └── layersize
    15. └── f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73
    16.     ├── json
    17.     └── layersize

    其中,json为该层元信息,layersize为该层大小。

    此时用ubuntu:14.04镜像起一个容器:


    点击(此处)折叠或打开

    1. # docker run -it -d ubuntu:14.04 /bin/bash
    2. b0311350933de15936136b4c9142635782f8fd1a015d2fd2d6c54ed05efb

    新建容器的操作会在aufs下三个子目录中分别新建两个以容器id为名的文件/目录,例如4262b031135…和4262b031135…- init,其中4262b031135…-init表示容器的初始层,它记录的信息和ubuntu:14.04镜像的最上层一致。所有在新建容器中的文件 操作最终都会记录到aufs/diff/4262b031135…目录中,比如:
    1. 新建文件,修改文件。
    2. 删除文件和目录,以.wh.{obj}标记。在联合文件系统中被称为除白(Whiteout)对象。
    3. 删除目录后新建,以.wh..wh..opq标记。在联合文件系统中被称为不透明(Opaque directory)对象。

    aufs/mnt目录是容器的挂载点,通过df命令和mount -v命令进行确认,另外容器的操作日志、环境变量、元信息等也会在containers目录以容器id命名的目录中。容器运行后,可以在sysfs目录中 找到对应的从上到下的镜像层次结构,读写权限一目了然(si可以通过mount -v查询):


    点击(此处)折叠或打开

    1. # cat /sys/fs/aufs/si_13ac476258e8c5e8/br*
    2. /var/lib/docker/aufs/diff/4262b031135...=rw
    3. /var/lib/docker/aufs/diff/4262b031135...-init=ro
    4. /var/lib/docker/aufs/diff/8eaa4ff06b5...=ro
    5. /var/lib/docker/aufs/diff/f62feddc05d...=ro
    6. /var/lib/docker/aufs/diff/607c5d1cca7...=ro
    7. /var/lib/docker/aufs/diff/3b363fd9d7d...=ro
    8. /var/lib/docker/aufs/diff/511136ea3c5...=ro

    aufs为Docker镜像存储带来了可重用性、权限分明、层次清晰等优点后,也带来了它的固有缺陷:
    1. 写时复制(Copy On Write),性能不够好。
    2. 最大层数限制(127层)。

    关于绕开最大层数限制,在『aufs文件系统』中已有讨论,这里针对Docker的使用场景再进行一次归纳:
    1. 更换docker存储驱动类型:device mapper, btrfs …
    2. 重新编译aufs: CONFIG_AUFS_BRANCH_MAX_32767=y
    3. 精简Dockerfile指令:RUN指令合并,脚本化
    4. docker export & docker import

    EOF

















    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(70) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    p2psearcher绿色版使用方法
    P2PSearcher云点播设置和使用技巧
    怎么看电脑有没有安装USB3.0驱动
    USB3.0驱动与2.0有什么区别
    win7 64位 安装java jdk1.8 ,修改配置环境变量
    jdk是什么?jdk1.8安装配置方法
    adb工具包究竟能帮我们做什么?
    web.xml中load-on-startup有和用处
    Spring Aop
    Struts2中的properties文件详解
  • 原文地址:https://www.cnblogs.com/ztguang/p/12649582.html
Copyright © 2011-2022 走看看