1. 容器镜像基础:镜像概念、分层存储原理、UnionFS 与 OverlayFS 工作机制
1.1 容器镜像的核心概念
容器镜像是一个轻量级、可执行的独立软件包,包含运行某个应用所需的一切:代码、运行时、系统工具、系统库和设置。镜像在构建时是静态的,运行时通过容器引擎实例化为容器。
| 特性 | 说明 |
|---|---|
| 不可变性 | 镜像一旦构建完成,其内容不会改变;任何修改都会产生新的镜像层。 |
| 分层结构 | 镜像由多个只读层叠加而成,每层代表一组文件变更(Dockerfile 中的一条指令)。 |
| 可复用性 | 不同镜像可以共享相同的底层基础层,节省存储和网络传输带宽。 |
| 内容寻址 | 每一层通过内容哈希(SHA256)唯一标识,确保完整性和一致性。 |
关键理解:镜像不是一个大文件,而是一组按依赖顺序堆叠的只读层集合。容器运行时会在这个堆叠之上添加一个可写层,所有写入操作都发生在这个顶层。
1.2 分层存储原理
分层存储是容器镜像实现高效分发和存储的核心机制。每一层(Layer)对应 Dockerfile 中的一条指令(如 RUN、COPY、ADD),层与层之间通过增量变更的方式组织。
- 基础层(Base Layer):通常是一个完整的操作系统文件系统(如 Ubuntu、Alpine),位于堆叠最底部。
- 中间层(Intermediate Layers):每一条指令执行后产生的文件系统快照,只包含相对于上一层的变更(新增、修改、删除)。
- 顶层(Top Layer):容器运行时创建的可写层,所有运行时写入的数据都保存在这里,容器删除后该层随之消失。
分层优势:
- 存储效率:相同基础层只需在宿主机上存储一份,多个容器共享。
- 传输效率:推送或拉取镜像时只传输差异层,大幅减少网络流量。
- 构建缓存:Docker 构建时缓存每一层,未变更的层直接复用,加速 CI/CD 流程。
1.3 UnionFS 与 OverlayFS 工作机制
分层存储的底层实现依赖联合文件系统(Union Filesystem)。UnionFS 允许将多个目录(分支)挂载到同一个挂载点,呈现为一个统一的文件系统视图。容器运行时最常用的实现是 OverlayFS(Overlay Filesystem)。
1.3.1 UnionFS 核心概念
- 分支(Branch):参与联合挂载的每个目录称为一个分支,每个分支可以设置读写权限。
- 联合挂载(Union Mount):将多个分支合并为一个逻辑文件系统,用户看到的是合并后的结果。
- 写时复制(Copy-on-Write, CoW):当需要修改下层只读分支中的文件时,先将文件复制到上层可写分支,再执行修改,下层文件保持不变。
1.3.2 OverlayFS 工作原理
OverlayFS 是 Linux 内核原生支持的联合文件系统,相比 AUFS(Another Union File System)性能更优、更稳定。它使用两个主要目录层:lowerdir(下层)和 upperdir(上层),通过 merged 目录呈现合并后的视图。
| OverlayFS 组件 | 对应容器镜像角色 | 说明 |
|---|---|---|
| lowerdir | 镜像只读层(可多层叠加) | 所有镜像层按顺序堆叠,只读挂载,多个容器共享。 |
| upperdir | 容器可写层 | 每个容器独有,记录所有写入、修改、删除操作。 |
| workdir | 临时工作目录 | 用于原子操作和文件属性管理,对用户透明。 |
| merged | 容器文件系统视图 | 用户和进程看到的最终文件系统,upperdir 覆盖 lowerdir。 |
重要行为差异:在 OverlayFS 中,删除下层文件时,upperdir 会创建一个“白out”文件(character device 0/0)来标记删除,而不是真正删除下层文件。这保证了镜像层的不可变性。
1.4 写时复制(CoW)与容器启动效率
写时复制是 OverlayFS 提升容器启动效率的核心机制。当容器启动时,不需要复制整个镜像文件系统,只需创建一个空的 upperdir,所有镜像层作为 lowerdir 直接共享。
启动效率对比:
- 传统虚拟机:启动时需要加载完整操作系统镜像到内存,耗时数秒到数分钟。
- 容器(OverlayFS):启动时仅创建 upperdir 和挂载点,镜像层直接共享宿主机的缓存页缓存,毫秒级启动。
理解分层存储和 OverlayFS 的工作机制,是后续进行镜像分层优化、减少镜像体积、提升节点池升级效率的基础。在后续章节中,我们将基于这些原理,深入探讨如何通过层合并、基础镜像选择、构建缓存策略等手段,实现容器化工作负载的极致效率。