Docker作为一种容器技术,已经在工程实践中被广泛的应用,这里讲讲其镜像的管理和后端的存储驱动。
1. 什么是Docker镜像
镜像,英文单词为image,在计算机世界的很多领域里都曾经出现,常见的image
有下面这些:
这些不同格式,应用在不同的场景的镜像,都是由数据本身+组织管理信息(元信息)
组成,通过mkimage,mkiso,qemu-img这样的工具来生成不同格式的镜像。Docker
镜像也一样,由根文件系统+元文件组成,通过docker build生成。
Figure -- 1
下面来梳理下容器镜像与普通程序,以及进程与容器的区别。如图Figure-1所示,
程序是个静态的可执行文件,通常在/usr/bin,/usr/sbin目录下,进程是动态的,是运
行中的程序,除了代码段、数据段、堆、栈外,还包括进程控制块这些信息。容器镜像
可说是个静态的根文件系统,以及镜像的元文件组成,通常在/var/lib/docker目录下,
容器是动态的,是运行中的镜像,包括init进程、服务(后台进程)、还包括受限的操
作系统资源(内存、CPU、文件系统、网络)。
2. 存储驱动的作用及其分类
Docker容器镜像,是个静态的根文件系统(linux根目录及其包含的若干子目录组
成),如图Figure-2所示,与普通linux系统的目录结构一样,差别就是不同用途的镜像,
相关目录下文件有所差别。显而易见Docker容器镜像并不像虚拟机镜像是个单一的qcow2文件,其就是一堆在各自目录下的文件,容器通过后端的存储技术,以一定的权限,可读、可写、可执行访问,docker镜像的技术如分层等,正是基于后端存储驱动来实现的。
Figure -- 2
存储驱动技术,大致上有下面几类:AUFS、Btrfs、Device mapper、OverlayFS、
ZFS,其都在linux内核实现。
在文件/etc/sysconfig/docker-storage,有后端驱动配置项:
DOCKER_STORAGE_OPTIONS="--storage-driver overlay2 "
其对应于dockerd服务进程的参数: --storage-driver overlay2,本文后面章节的描述,
都是基于overlay2存储驱动。
3. Docker镜像设计技术
Docker镜像大致有下面的一些特点:分层、写时拷贝、内容寻址、联合挂载。
4. Docker镜像元文件和存储文件
Docker镜像的元数据都存放在/var/lib/docker/image/overlay2目录下:
------- imagedb 存储所有镜像的元数据
------- layerdb 存储所有镜像层和容器层的元数据
------- repositories.json 记录镜像仓库中所有镜像的repository和tag名
------- distribution
repositories.json记录了下载到本地镜像的源仓库名称和生成的tag,通过命令
docker images列出的镜像信息里,会有一栏“IMAGEID”,这个ID对应于其中的一个tag。
5. 镜像内容寻址
镜像的内存寻址,是根据镜像的ID来索引,通过层层寻址,最终找到其存储目录。整个过程如图Figure-3所示。
整个过程,可以分为三个步骤,step-1通过image-id寻址到分层,step-2通过分层id寻址到镜像层,最后step-3,/var/lib/overlay2目录下,就是以id为索引的镜像层存储目录。
5. 镜像分层/联合挂载
Figure -- 4
如Figure--4所示,lowerdir是镜像层,upperdir是容器层,merged是容器看到的统一视图,通过mount命令可以查看到相关的信息。
6. 容器文件的读写
镜像层的文件,都是只读的,修改这些文件,如passwd命令时,会把镜像层的文件先拷贝到容器层,再修改相应的文件,容器层目录,原始状态只有一个run目录。文件同时存在容器层和镜像层,有效的是容器层的文件,镜像层的文件被屏蔽。
删除一个文件时,如果这个只存在镜像层,容器会在容器层创建一个whiteout文件,镜像层的这个文件并不会被删除,但是whiteout文件会隐藏镜像层的文件。