Docker为应对不同平台不同场景对存储的要求,提供了不同的存储驱动来管理实际镜像文件。
1.镜像元数据管理
元数据包含repository、image和layer三个层次。
1.1.repository元数据
repository指具有某个功能的Docker镜像的所有迭代版本构成的镜像库。在本地的持久化文件存放于/var/lib/docker/image/some_graph_driver/repositories.json中。文件内容包含repository名称、镜像名称和tag、镜像ID。Docker默认采用SHA256算法根据镜像元数据配置文件计算出镜像ID。
1.2.image元数据
包含镜像架构(如amd64)、操作系统(如Linux)、镜像默认配置、构建该镜像的容器ID和配置、创建时间、创建该镜像的Docker版本、构建镜像的历史信息以及rootfs组成。
Docker根据历史信息和rootfs中的diff_ids计算出构成该镜像的镜像层的存储索引chainID。
持久化文件位于/var/lib/docker/image/[graph_driver]/imagedb/content/sha256/[image_id]中。
1.3.layer元数据
layer对应镜像层的概念。
1.10版本前,layer元数据记录该层的构建信息以及父镜像ID。
1.10版本后,简化layer元数据,只包含一个具体的镜像层文件包。宿主机下载镜像后,Docker会在宿主机上基于镜像层文件包和image元数据构建本地的layer元数据,包括diff、parent、size等。
Docker中定义了Layer和RWLayer两种接口,分别用来定义只读层和可读写层的一些操作。roLayer和mountedLayer分别实现了上述两种接口。
roLayer存储的内容主要有索引该镜像层的chainID、该镜像层的校验码diffID、父镜像层parent、graphdriver存储当前镜像层文件的cacheID、该镜像层的大小size等。元数据存储于/var/lib/docker/image/[graph_driver]/layerdb/sha256/[chainID]/目录下。
mountedLayer存储的内容主要为索引某个容器的可读写层的ID、容器init层在graphdriver中的ID(initID)、读写层在graphdriver中的ID(mountID)、父镜像层的chainID(parent)。持久化文件位于/var/lib/docker/image/[graph_driver]/layerdb/mounts/[container_id]/目录下。
2.存储驱动
Docker提供存储驱动的接口,用于某种文件系统的初始化操作以及对镜像层的增删改查和差异比较等操作。目前有6种接口的实现:aufs、btrfs、devicemapper、vfs、overlay和zfs。
启动Docker服务时,使用docker daemon -s some_driver_name来指定所使用的存储驱动,存储驱动必须被底层操作系统支持。
管理文件系统的驱动为graphdriver。