Docker容器和镜像存储机制—images—目录树结构
2016-02-01 00:00
627 查看
http://ju.outofmemory.cn/entry/114344
Docker的存储机制采用了非常灵活的模块化设计,目前支持5种存储引擎,分别为aufs、btrfs、device mapper、vfs和overlay。它们的共同特点都是实现了graphdriver.Driver接口:
点击(此处)折叠或打开
type ProtoDriver interface {
String() string
//创建layer
Create(id, parent string) error
//删除layer
Remove(id string) error
//mount, 获取容器挂载点
Get(id, mountLabel string) (dir string, err error)
//umount文件系统
Put(id string)
Exists(id string) bool
Status() [][2]string
Cleanup() error
}
type Driver interface {
ProtoDriver
Diff(id, parent string) (archive.Archive, error)
Changes(id, parent string) ([]archive.Change, error)
ApplyDiff(id, parent string, diff archive.ArchiveReader)(size int64,err error)
DiffSize(id, parent string) (size int64, err error)
}
所以,只要实现了存储驱动接口定义的方法,就可以扩展出一种存储引擎。想要更换存储引擎有两种方法:
1. docker daemon进程启动时指定-s参数:docker –s aufs。
2. 修改配置文件:DOCKER_OPTS=”–storage-driver=aufs”。
在Docker存储模型中,bootfs同宿主机,rootfs则是由多个镜像层和一个容器层构成,其中镜像层只读,容器层可读写,多个镜像层之间有父子关系,下层作为上层镜像的父镜像,最下面的镜像称为base images(基础镜像),相关定义可以参考官网解释。
aufs是Docker最早支持的一种存储引擎,它的工作机制和优缺点在前文『aufs文件系统』中已有介绍,aufs能将不同的目录挂载到某一目录下,将各个源目录下的内容联合到目标目录下,并可对不同目录进行权限控制。这个特性非常契合Docker的存储模型:
1. 镜像分层模型对应aufs中的分支(源目录)。
2. 镜像层对应aufs的ro分支,只读;容器层对应aufs的rw分支,可读写。
默认配置下,Docker镜像和容器存储路径($DOCKROOT)位于/var/lib/docker,如果选择的是aufs文件系统作为存储引擎,那么它的子目录树结构(基于docker 1.4.1)应该如下:
点击(此处)折叠或打开
# tree .
├── aufs
│ ├── diff 镜像和容器每层的差异内容
│ ├── layers 镜像和容器每层的继承关系
│ └── mnt 容器挂载点
├── containers 容器配置文件,环境变量和日志文件
├── graph 镜像详情、大小等
└── repositories-aufs 镜像摘要
举例说明,当前本地镜像库有一个ubuntu:14.04的镜像,它的层级关系如下:
点击(此处)折叠或打开
# docker images -t
└─511136ea3c5a Virtual Size: 0 B
└─3b363fd9d7da Virtual Size: 192.5 MB
└─607c5d1cca71 Virtual Size: 192.7 MB
└─f62feddc05dc Virtual Size: 192.7 MB
└─8eaa4ff06b53 Virtual Size: 192.7 MB Tags: ubuntu:14.04
那么在aufs/diff目录(相对于$DOCKROOT,下同)下会有以各个层级id命名的目录,每个目录存储着与它父镜像之间的差异:
点击(此处)折叠或打开
# ls -l aufs/diff/
total 20
drwxr-xr-x 21 3b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
drwxr-xr-x 2 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
drwxr-xr-x 6 607c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
drwxr-xr-x 2 8eaa4ff06b53ff7730c4d7a7e21b4426a4b46dee064ca2d5d90d757dc7ea040a
drwxr-xr-x 3 f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73
aufs/layers目录下有以各个层级id命名的文件,文件内容为该层所有的祖先镜像id。例如
点击(此处)折叠或打开
# cat aufs/layers/8eaa4ff06b53ff7730c4d7a7e21b4426a4b...
f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73
c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
graph目录中存储的是每一层镜像的详细信息和大小:
点击(此处)折叠或打开
# tree graph/
graph/
├── 3b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
│ ├── json
│ └── layersize
├── 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
│ ├── json
│ └── layersize
├── 607c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
│ ├── json
│ └── layersize
├── 8eaa4ff06b53ff7730c4d7a7e21b4426a4b46dee064ca2d5d90d757dc7ea040a
│ ├── json
│ └── layersize
└── f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73
├── json
└── layersize
其中,json为该层元信息,layersize为该层大小。
此时用ubuntu:14.04镜像起一个容器:
点击(此处)折叠或打开
# docker run -it -d ubuntu:14.04 /bin/bash
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查询):
点击(此处)折叠或打开
# cat /sys/fs/aufs/si_13ac476258e8c5e8/br*
/var/lib/docker/aufs/diff/4262b031135...=rw
/var/lib/docker/aufs/diff/4262b031135...-init=ro
/var/lib/docker/aufs/diff/8eaa4ff06b5...=ro
/var/lib/docker/aufs/diff/f62feddc05d...=ro
/var/lib/docker/aufs/diff/607c5d1cca7...=ro
/var/lib/docker/aufs/diff/3b363fd9d7d...=ro
/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–
Docker的存储机制采用了非常灵活的模块化设计,目前支持5种存储引擎,分别为aufs、btrfs、device mapper、vfs和overlay。它们的共同特点都是实现了graphdriver.Driver接口:
点击(此处)折叠或打开
type ProtoDriver interface {
String() string
//创建layer
Create(id, parent string) error
//删除layer
Remove(id string) error
//mount, 获取容器挂载点
Get(id, mountLabel string) (dir string, err error)
//umount文件系统
Put(id string)
Exists(id string) bool
Status() [][2]string
Cleanup() error
}
type Driver interface {
ProtoDriver
Diff(id, parent string) (archive.Archive, error)
Changes(id, parent string) ([]archive.Change, error)
ApplyDiff(id, parent string, diff archive.ArchiveReader)(size int64,err error)
DiffSize(id, parent string) (size int64, err error)
}
所以,只要实现了存储驱动接口定义的方法,就可以扩展出一种存储引擎。想要更换存储引擎有两种方法:
1. docker daemon进程启动时指定-s参数:docker –s aufs。
2. 修改配置文件:DOCKER_OPTS=”–storage-driver=aufs”。
在Docker存储模型中,bootfs同宿主机,rootfs则是由多个镜像层和一个容器层构成,其中镜像层只读,容器层可读写,多个镜像层之间有父子关系,下层作为上层镜像的父镜像,最下面的镜像称为base images(基础镜像),相关定义可以参考官网解释。
aufs是Docker最早支持的一种存储引擎,它的工作机制和优缺点在前文『aufs文件系统』中已有介绍,aufs能将不同的目录挂载到某一目录下,将各个源目录下的内容联合到目标目录下,并可对不同目录进行权限控制。这个特性非常契合Docker的存储模型:
1. 镜像分层模型对应aufs中的分支(源目录)。
2. 镜像层对应aufs的ro分支,只读;容器层对应aufs的rw分支,可读写。
默认配置下,Docker镜像和容器存储路径($DOCKROOT)位于/var/lib/docker,如果选择的是aufs文件系统作为存储引擎,那么它的子目录树结构(基于docker 1.4.1)应该如下:
点击(此处)折叠或打开
# tree .
├── aufs
│ ├── diff 镜像和容器每层的差异内容
│ ├── layers 镜像和容器每层的继承关系
│ └── mnt 容器挂载点
├── containers 容器配置文件,环境变量和日志文件
├── graph 镜像详情、大小等
└── repositories-aufs 镜像摘要
举例说明,当前本地镜像库有一个ubuntu:14.04的镜像,它的层级关系如下:
点击(此处)折叠或打开
# docker images -t
└─511136ea3c5a Virtual Size: 0 B
└─3b363fd9d7da Virtual Size: 192.5 MB
└─607c5d1cca71 Virtual Size: 192.7 MB
└─f62feddc05dc Virtual Size: 192.7 MB
└─8eaa4ff06b53 Virtual Size: 192.7 MB Tags: ubuntu:14.04
那么在aufs/diff目录(相对于$DOCKROOT,下同)下会有以各个层级id命名的目录,每个目录存储着与它父镜像之间的差异:
点击(此处)折叠或打开
# ls -l aufs/diff/
total 20
drwxr-xr-x 21 3b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
drwxr-xr-x 2 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
drwxr-xr-x 6 607c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
drwxr-xr-x 2 8eaa4ff06b53ff7730c4d7a7e21b4426a4b46dee064ca2d5d90d757dc7ea040a
drwxr-xr-x 3 f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73
aufs/layers目录下有以各个层级id命名的文件,文件内容为该层所有的祖先镜像id。例如
点击(此处)折叠或打开
# cat aufs/layers/8eaa4ff06b53ff7730c4d7a7e21b4426a4b...
f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73
c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
graph目录中存储的是每一层镜像的详细信息和大小:
点击(此处)折叠或打开
# tree graph/
graph/
├── 3b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
│ ├── json
│ └── layersize
├── 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
│ ├── json
│ └── layersize
├── 607c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
│ ├── json
│ └── layersize
├── 8eaa4ff06b53ff7730c4d7a7e21b4426a4b46dee064ca2d5d90d757dc7ea040a
│ ├── json
│ └── layersize
└── f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73
├── json
└── layersize
其中,json为该层元信息,layersize为该层大小。
此时用ubuntu:14.04镜像起一个容器:
点击(此处)折叠或打开
# docker run -it -d ubuntu:14.04 /bin/bash
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查询):
点击(此处)折叠或打开
# cat /sys/fs/aufs/si_13ac476258e8c5e8/br*
/var/lib/docker/aufs/diff/4262b031135...=rw
/var/lib/docker/aufs/diff/4262b031135...-init=ro
/var/lib/docker/aufs/diff/8eaa4ff06b5...=ro
/var/lib/docker/aufs/diff/f62feddc05d...=ro
/var/lib/docker/aufs/diff/607c5d1cca7...=ro
/var/lib/docker/aufs/diff/3b363fd9d7d...=ro
/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–
相关文章推荐
- Docker 使用总结
- Docker推出了Docker云
- 创建 Docker 镜像
- How To Install Docker on Fedora 23
- (OK) Fedora23——Docker——CORE—testing
- Running docker on Android
- Docker命令参考
- 如何创建一个安全的Docker基础镜像
- (OK) running CORE—Common Open Research Emulator—docker
- 对于OpenStack ,Docker1.0意味着什么?
- How To Install Docker on CentOS 7
- Docker—从入门到实践—Welcome to the Docker user guide
- Core and Docker Together at Last——Docker on Core 4.7
- (OK) CentOS7/Fedora23——Installing Docker——core—pip
- Install Pip with Curl and Python—core—docker
- 使用 Docker 搭建 Java Web 运行环境
- DockerTool在Windows上的配置和运行
- docker容器的网络连接
- docker容器的数据管理
- docker(一):安装