### 一、存储概述

Docker 支持多种存储类型用于容器和镜像的存储。以下是一些常见的 Docker 存储类型：

- Overlay 存储驱动
- Aufs 存储驱动
- Device Mapper 存储驱动
- VFS（Virtual File System）
- Btrfs 存储驱动
- ZFS 存储驱动

[Docker官方存储驱动文档](https://docs.docker.com/storage/storagedriver/)



### 二、Overlay 存储驱动

#### 1. 基本原理

- 层次结构： Docker 镜像是由多个文件系统层（layers）组成的。每个层都包含文件和目录，并且每个层都是只读的。这些层通过联合文件系统（Union File System）的概念组合在一起，形成一个统一的文件系统

- Overlay 文件系统：** Overlay 存储驱动使用 OverlayFS 文件系统，它是一个联合文件系统，通过将多个文件系统层叠加在一起，为用户提供一个单一的文件系统视图。这使得容器能够访问所有层的文件和目录，而实际上这些层是分开存储的

- Upper、Lower 和 Work 目录： OverlayFS 包括三个关键的目录：

  - Upper 目录： 包含了容器运行时的可写层，任何对文件系统的写操作都将在这个目录中进行。这使得容器可以在运行时修改文件

  - Lower 目录： 包含了只读的基础镜像层，即 Docker 镜像的各个层次

  - Work 目录： 用于存储 OverlayFS 内部的工作文件

#### 2. Upper,Lower和worker目录

- **Upper 目录：**

  - **位置：** `upper` 目录包含 OverlayFS 的可读写层。这是容器内部所做更改的存储位置

  - **功能：** 容器内部对文件系统的任何修改或添加都会存储在 `upper` 目录中。这个目录允许在其他层之上创建一个可写层

- **Lower 目录：**

  - **位置：** `lower` 目录包含 OverlayFS 的只读层。这些层代表了基础镜像和任何额外的只读层

  - **功能：** `lower` 目录中的内容是 Docker 镜像中的初始文件和目录集。这些层叠加在一起，而上层提供了一个可写表面用于进行更改

- **Work 目录：**

  - **位置：** `work` 目录在 OverlayFS 的内部使用，用于进行覆盖过程中的操作

  - **功能：** 在覆盖过程中，例如合并和复制操作，`work` 目录充当某些 OverlayFS 操作的工作空间。操作完成后，更改将应用到上层

![iT 邦幫忙::一起幫忙解決難題，拯救IT 人的一天](https://blog-heysq-1255479807.cos.ap-beijing.myqcloud.com/halo2/202401221032111.png)

#### 3. Overlay2相比Overlay优化点

- **并发写操作：** Overlay2 引入了对并发写操作的更好支持。这意味着在多个容器同时对文件系统进行写操作时，Overlay2 能够更有效地管理并发性，减少冲突和性能下降。

- **硬链接：** Overlay2 在硬链接的处理上进行了优化。硬链接是一种在文件系统中创建文件的方法，Overlay2 利用硬链接的方式减少重复的文件存储，进一步降低存储开销。

- **SELinux 支持：** Overlay2 更好地支持 SELinux（Security-Enhanced Linux），提供了更强大的安全性选项。这对于需要强调容器安全性的生产环境非常重要。

- **复制操作的优化：** 在 Overlay2 中，复制操作经过优化，减少了复制数据的需求，提高了效率。这有助于加速容器的构建和启动过程。

- **可读性和可维护性：** Overlay2 的存储结构更加清晰和模块化，使得整个系统更易于理解和维护。每个容器有自己的独立文件夹，包含了与该容器相关的所有数据。



#### 4. overlay copy-up

- 试图修改一个只读层的文件时，会发生一个称为 “copy-up” 的操作。因为每个镜像层都是只读的，而容器运行时对文件的任何修改都必须发生在容器的顶层，也就是可写层
- 简化的 copy-up 操作流程:
  - **查找文件**：当一个进程请求修改一个文件时，OverlayFS 首先会在堆栈的各个层中从上到下查找该文件
  - **复制文件**：如果该文件位于一个只读层，OverlayFS 会将该文件（包括其元数据）复制到最上层的可写层中。这个过程称为 “copy-up”
  - **修改文件**：一旦文件被复制到可写层，进程就可以在这个副本上执行修改操作
- Copy-up 操作使得容器可以在不更改下层镜像的情况下修改文件，保持了镜像的不可变性，并确保了容器间的文件隔离。容器可以基于同一个镜像启动，但它们的文件系统状态可以是独立且不同的

### 三、Aufs 存储驱动简介

- Advanced Multi-Layered Unification Filesystem
- 允许将多个目录层（layers）叠加（overlay）在一起，形成一个单一的、统一的文件系统视图
- AUFS 最初是为了提高容器技术（如 Docker）的效率而设计的，它通过允许文件系统层的重用和共享，来减少磁盘占用和提高文件操作的效率
- 随着 OverlayFS 的出现和成熟（特别是 `overlay2` 驱动），以及 AUFS 的一些限制（如对 Linux 内核的补丁需求和一些性能问题），Docker 社区和 Docker 官方推荐的存储驱动已逐渐从 AUFS 过渡到了 `overlay2`
- OverlayFS 提供了类似的功能，但通常与 Linux 内核更兼容，且性能更优。AUFS 在某些 Linux 发行版中可能不是默认安装的，它可能需要额外的内核支持或第三方模块

### 四、**Device Mapper**

- 一个 Linux 内核的存储驱动，它使用了设备映射框架（Device Mapper）来管理层（layer）和快照。在 Docker 中，`devicemapper` 曾经是一个用于管理容器和镜像存储的流行选择
- `devicemapper` 的工作原理是通过创建虚拟的磁盘设备（称为逻辑卷），为容器和镜像提供存储空间。这些逻辑卷由 Device Mapper 来管理，它可以动态地创建、删除和调整大小
- 运行模式：
  - **Loop-lvm**：这是 `devicemapper` 的默认模式，它使用已存在的文件（loopback 文件）作为逻辑卷。这种模式不需要额外的分区或物理磁盘，但性能较差，因为它没有直接访问底层存储设备
  - **Direct-lvm**：这种模式提供了更好的性能，因为它使用物理磁盘的分区（通常是 LVM 卷组）作为存储的后端。在 Direct-lvm 模式中，每个容器和镜像都有自己的逻辑卷，这些逻辑卷可以进行快照操作以支持 Docker 镜像层
- `devicemapper` 还支持许多高级功能，例如：
  - **存储配额**：可以为每个容器设置磁盘空间配额，防止容器使用过多的磁盘空间
  - **快照和克隆**：支持创建逻辑卷的快照，这可以用于备份或在容器之间共享数据
  - **薄置备**：薄置备（Thin Provisioning）允许在物理存储资源不足的情况下创建逻辑卷，这可以提高存储的灵活性和效率
- 缺点：
  - 配置的复杂性和相对较高的维护要求
  - 需要仔细的存储管理和监控，以防止存储空间耗尽

### 五、VFS

- 一种简单的存储机制，它不会尝试去重用或共享层之间的数据
- 在 VFS 中，每个容器都有自己的完整文件系统副本，即使是相同的文件或目录也会在每个容器中分别存储多份副本
- 每次启动新容器或构建新镜像层时，VFS 都会创建一个完整的文件系统副本，导致磁盘空间的快速消耗和性能下降
- 特点：
  - **简单性**：VFS 驱动非常简单，没有复杂的配置和依赖关系，因此它通常用于测试和调试
  - **不依赖特定文件系统**：VFS 不依赖任何底层的文件系统特性，因此它可以在任何文件系统上运行
  - **不进行层共享**：由于没有层共享，每个容器的文件系统都是独立的，这意味着每个容器的存储是完全隔离的

### 六、btrfs

- 一种Linux 文件系统
- 支持以下高级功能：
  - **Copy-on-Write（COW）**：`btrfs` 使用 COW 技术，这意味着当文件被修改时，只有更改的部分会被写入新的位置，原有数据保持不变
  - **快照**：`btrfs` 支持快速创建文件系统的快照，这对于 Docker 镜像和容器的版本控制非常有用
  - **子卷**：`btrfs` 支持创建子卷，这些子卷可以被用来为 Docker 容器和镜像提供独立的文件系统环境
  - **透明压缩**：`btrfs` 支持在文件系统级别进行数据压缩，这有助于减少磁盘空间的使用
  - **去重**：`btrfs` 支持数据去重，这可以进一步提升存储效率，尤其是在存储大量重复数据时
  - **内置 RAID 支持**：`btrfs` 支持多种 RAID 级别，包括 RAID 0、1、10、5 和 6，这些都是通过软件实现的
  - **动态卷管理和扩展**：`btrfs` 支持在线动态调整卷的大小，这使得在现有文件系统上添加更多存储空间变得非常简单

- 在 Docker 中使用 `btrfs` 存储驱动时，每个容器和镜像层都可以映射到 `btrfs` 的子卷和快照。这允许 Docker 高效地创建和管理容器数据



### 七、ZFS

- ZFS（Zettabyte File System）是一个高级的文件系统和逻辑卷管理器，设计用来处理大量数据并提供极高的数据完整性。它集成了文件系统和卷管理器的功能，意味着你可以直接在 ZFS 池上创建文件系统，而不需要单独的卷管理器
- 先进特性：
  - **Copy-on-Write (COW)**：ZFS 是一个 COW 文件系统，这意味着当数据被修改时，原始数据不会被覆盖，而是会将改变的部分写入新位置
  - **快照和克隆**：ZFS 支持无性能损失的快照功能，快照是文件系统的只读版本。基于快照，你可以创建克隆，即快照的可写副本
  - **数据完整性**：ZFS 使用校验和来确保数据的完整性，它可以自动检测和修复数据损坏，即使在单磁盘系统上也是如此
  - **内建 RAID 支持**：ZFS 支持多种级别的 RAID 配置，包括 RAID-Z（类似于 RAID-5 或 RAID-6），无需额外的硬件或软件
  - **动态条带化**：在 ZFS 中，数据自动分布在所有可用磁盘上，提高了性能和空间利用率
  - **透明压缩**：ZFS 支持在文件系统级别的数据压缩，这有助于节省空间
  - **存储池**：ZFS 使用存储池的概念来管理物理存储，你可以轻松地向存储池添加新的存储设备，以扩展容量