1. 容器存储背景
1.1、容器 VS 虚拟机
容器技术是目前云计算中不可或缺的一部分,相比于传统虚拟机而言,容器技术在操作系统级别为虚拟化提供了一种更轻量化的选择。传统虚拟机(VM)在虚拟化硬件和主机操作系统之上通过hypervisor管理层运行客户端操作系统的完整副本,运行过程占用大量空间,限制了单台物理主机上可部署的虚拟机数量,而启动时间长使得虚拟机托管短生命周期的应用程序代价过高。下图为虚拟机和Docker容器的系统层次结构对比图。
基于容器的虚拟化技术通过在应用程序之间共享主机操作系统的库和内核来解决这些问题,它不再需要运行整个臃肿的客户端操作系统,而是通过命名空间namespace机制使每个应用程序都运行在一个独立的命名空间,也就是容器中。简单理解来看,容器就是通过namespace机制打包隔离运行的一组“容器化”进程。运行在主机操作系统之上的后台进程Docker守护进程则取代了Hypervisor,它可以直接与主机操作系统通信,负责管理Docker容器为其分配资源,而应用的所有依赖包括源代码都打包在Docker镜像。相比于虚拟机而言,容器产生的开销更小,占用的空间更少,启动的速度更快。
1.2、镜像与层
Docker 镜像作为Docker容器的基础,由一系列层堆叠组成,每个层代表镜像的Dockerfile中的一条指令。除了最上层容器层之外,每个层都是只读了,每个层与之前的层只有一部分差异。当创建并启动一个新的容器时,Docker会加载只读镜像层并在其上(即镜像栈顶部)添加一个可读写层,这个层通常被称为“容器层”。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏。当删除Docker容器,并通过该镜像重新启动时,之前的更改将会丢失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System(联合文件系统)。下图显示了一个基于 Ubuntu 15.04 镜像的容器。
1.3、容器与层
容器和镜像之间的主要区别是顶部的可写层。所有对容器添加新的或修改现有数据的内容都存储在该可写层中。当容器被删除时,可写层也被删除,底层镜像则保持不变。由于每个容器都有自己的可写的容器层,并且所有更改都存储在此容器层中,因此多个容器可以共享对相同基础镜像的访问权限,并且拥有自己的数据状态。下图显示了共享相同 Ubuntu 15.04 镜像的多个容器。Docker 使用存储驱动程序来管理镜像层和可写容器层的内容。每个存储驱动程序都处理实现的方式不同,但所有驱动程序都使用可堆叠的镜像层和写入时复制(CoW)策略。存储驱动程序处理有关这些层相互交互方式的详细信息,不同的存储驱动程序可以使用,在不同情况下各有优缺点。
由于容器灵活、高效、易于扩展,并面向云计算,因此希望将其应用范围扩展到徽服务之外,例如大型的容器化的数据库、甚至存储系统,但是通过容器设计企业级的、长期存储数据的应用目前仍是困难的。