我的公众号: 海天二路搬砖工
一、引言
Docker的出现,彻底改变了应用程序开发和部署的方式。Docker技术通过Docker 镜像(Image)、容器(Container)和分层文件系统(Layer)的精妙组合, 使其可以轻松地打包应用程序及其依赖关系,并在不同的环境中以一致的方式运行。
Docker 镜像包含应用程序和其运行所需环境的快照,是静态、不可变的,有多个只读层和一个可写层组成。容器提供了一个隔离的运行环境,允许应用程序在其中运行,并能够读取、写入和存储数据。如何管理容器内的数据,以及如何与主机进行数据交互,则是通过是 Docker 存储驱动来实现。
本文将深入探讨 Docker 存储驱动,从选择适当的存储驱动到它们的工作原理,再到最佳实践和性能优化。我们将重点关注几种常见的存储驱动,如 Overlay2、AUFS 和 Device Mapper,以及其他存储选项,如 Btrfs 和 VFS。
二、Docker 存储驱动简介
什么是 Docker Storage Drivers
Docker 存储驱动是 Docker 中的一个核心组件,它负责管理容器的文件系统和数据。
存储驱动的主要作用是定义了如何组织、存储和检索容器的数据,以便容器可以访问、写入和读取数据。存储驱动决定了容器内部的文件系统层次结构,以及如何与主机文件系统互动。
常见的Docker 存储驱动有哪些
Docker 提供了多种不同的存储驱动选项,以满足不同的使用情境和需求。以下是一些常见的 Docker 存储驱动:
- Overlay2: Overlay2 存储驱动是 Docker 默认的存储驱动,它采用 OverlayFS 技术,支持写时复制(Copy-on-Write),在性能和稳定性方面表现出色,特别适合生产环境。
- AUFS: AUFS 存储驱动采用另一种联合文件系统,也支持写时复制。虽然 AUFS 在一些旧版本的 Docker 中常用,但在新版本中,Overlay2 替代了它。
- Device Mapper: Device Mapper 存储驱动使用底层的块设备,支持高级的存储管理功能,如快照和薄写。它适用于需要高级存储功能的场景,但需要谨慎配置。
- Btrfs: Btrfs 存储驱动利用 Btrfs 文件系统的特性,支持写时复制和快照。它适用于需要先进文件系统功能的环境。
- VFS: VFS 存储驱动是 Docker 的原始存储驱动,提供了基本的文件系统功能。它通常用于测试或开发目的,不适合生产环境。
- ZFS: ZFS 存储驱动使用 ZFS 文件系统,提供高级的数据管理和文件系统功能。它适用于需要高级存储功能的场景,但需要配置和管理的工作较多。
三、Overlay2存储驱动
Overlay2 存储驱动简介
Overlay2 存储驱动 是 Docker 默认的存储驱动,它负责管理容器的文件系统和数据。Overlay2 存储驱动在性能和稳定性方面表现出色,特别适用于生产环境。
Overlay2 存储驱动工作原理
Overlay2 是建立在 OverlayFS 技术之上的
OverlayFS 原理:OverlayFS 是一种联合文件系统,可以将两个目录堆叠在单个 Linux 主机上,并将它们呈现为一个单一的目录。这两个堆叠的目录分别称为“layers”(层),合并它们的过程被称为“union mount”(联合挂载)。在 OverlayFS 中,底层目录被称为“lowerdir”(底层目录),而上层目录被称为“upperdir”(上层目录)。用户可以访问这两个目录的内容,但这个统一的视图是通过单独的目录称为“merged”(合并)来公开。
- 上层图层(upper layer): 这是容器的可写层,包含了容器内部产生的文件和数据。当容器执行写操作时,Overlay2 存储驱动会在上层图层中创建一个新文件或目录,而不直接修改底层图层。这种写时复制(Copy-on-Write)的方式确保了容器的数据隔离和不可变性。
- 底层图层(lower layer): 这是 Docker 镜像的底层,包含了基础文件系统和镜像中的文件。这些文件在所有容器之间共享,因此可以在多个容器之间实现高度的重用,节省存储空间。
当容器启动时,Overlay2 存储驱动会以只读方式挂载底层图层,并在上层图层上创建一个可写的挂载点。这使得容器可以访问底层图层的文件,同时允许它们修改和创建新的文件,这些修改会保存在上层图层中。这种架构确保了容器的数据隔离和快速的启动时间。
Overlay2 存储驱动的优势和不足
Overlay2 存储驱动的优势:
- 高性能:Overlay2是一种轻量级的存储驱动,它通过使用图层存储机制,能够实现高性能和高效的容器操作。
- 快速容器启动:Overlay2的图层堆栈机制允许容器快速启动。 因为基础镜像层是共享的,只有在容器层上添加或修改的文件需要额外的存储空间,而不是整个镜像。
- 可读性好:Overlay2使用标准的Linux文件系统特性,使容器文件系统在主机上可读,这对于调试和监视容器非常有用。
- 容器可移植性:Overlay2允许容器和镜像在不同的Docker主机上可移植,因为它不依赖于底层文件系统的特定实现。
- 稳定性: Overlay2 存储驱动是Docker默认的存储驱动,在稳定性和可靠性方面经过了充分的验证。
Overlay2 存储驱动的不足:
- 兼容性: 在某些旧版本的 Linux 内核中,Overlay2 存储驱动可能不受支持,这可能导致在一些系统上无法使用。因此,在选择 Overlay2 存储驱动时,需要确保主机操作系统和内核版本的兼容性。
- 存储需求:虽然Overlay2是一种轻量级存储驱动,但在容器层数多的情况下,可能会占用较多的磁盘空间。
- 不适合大规模写入:Overlay2在大规模写入文件时可能性能较差,因为它需要将更多的文件写入容器层,而不是原始镜像。
四、其他存储驱动
**BTRFS**
Btrfs(B-tree File System)是一个现代的、先进的Linux文件系统,旨在提供高级别的数据完整性、可扩展性和性能。Btrfs引入了许多先进的特性,包括快照、检查和修复、压缩、在线扩展和多设备支持。它的设计目标是改进文件系统的稳定性和可管理性,以满足现代计算机系统的需求。
使用 Btrfs 存储驱动时,整个 /var/lib/docker/ 目录存储在 Btrfs 卷上。 有关镜像层和可写容器层的信息存储在 /var/lib/docker/btrfs/subvolumes/ 中。该子目录包含每个图像或容器层一个目录,以及从一层及其所有父层构建的统一文件系统。整体的结构就如同一颗B树。
上图显示了 4 个子卷。 “子卷 2”和“子卷 3”是嵌套的,而“子卷 4”显示其自己的内部目录树。
Device Mapper
Device Mapper 是一个基于内核的框架, Docker 的 devicemapper 存储驱动程序利用该框架的精简配置和快照功能来进行映像和容器管理。
devicemapper 驱动程序使用 Docker 专用的块设备,并在块级别(而不是文件级别)运行。可以通过向 Docker 主机添加物理存储来扩展,并且它们的性能比在操作系统 (OS) 级别使用文件系统更好。
使用devicemapper 存储驱动时,/var/lib/docker/devicemapper/metadata/ 目录存放有关 Devicemapper 配置本身以及存在的每个映像和容器层的元数据。devicemapper使用快照,将每一层中引入的差异存储为非常小的、轻量级的精简池。快照信息存储在容器层的元数据中。
**ZFS**
ZFS 是下一代文件系统,支持许多先进的存储技术,例如卷管理、快照、校验和、压缩和重复数据删除、复制等。但是由于 CDDL 和 GPL 之间的许可不兼容,ZFS 无法作为主线 Linux 内核的一部分提供。
ZFS 使用下面三个对象来支撑其工作:
- 文件系统(Filesystem): 文件系统是ZFS的核心对象,它用于组织和管理数据。类似于传统文件系统,ZFS文件系统允许您存储和组织数据,但它具有高级的功能和特性,如数据完整性、容量管理、数据压缩和高级缓存。
- 快照(Snapshot): ZFS支持快照,它是文件系统的只读副本,可以捕获文件系统在某个特定时刻的状态。快照可以用于数据备份、版本控制、数据恢复和测试。ZFS的快照是非常高效的,因为它们不会立即占用额外的磁盘空间,而是利用写时复制技术来保存文件系统状态。
- 克隆(Clones): 克隆是基于现有快照的可写副本。您可以创建克隆来创建一个新的文件系统,该文件系统与原始文件系统的快照相同。克隆可以用于创建环境隔离、测试、开发分支或任何需要与原始数据相关的独立副本的情况。克隆是高效的,因为它们共享与原始文件系统相同的数据块,只有在修改时才会分配额外的磁盘空间。
上图包含ZFS的两个主要步骤:
- 从文件系统创建只读快照。
- 从快照创建可写克隆。这包含与父层的任何差异。
**VFS**
VFS存储驱动程序不是联合文件系统;相反,每一层都是磁盘上的一个目录,并且不支持写时复制。要创建新层,需要对前一层进行“深层复制”,这就使其性能受到极大限制。
VFS 不是联合文件系统。相反,每个镜像层和可写容器层在 Docker 主机上都表示为 /var/lib/docker/ 中的子目录。