136 lines
10 KiB
Markdown
136 lines
10 KiB
Markdown
|
### 一、存储概述
|
|||
|
|
|||
|
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 使用存储池的概念来管理物理存储,你可以轻松地向存储池添加新的存储设备,以扩展容量
|