Docker 入门教程(六):联合文件系统(UnionFS)

文章目录

  • 🐳 Docker 入门教程(六):联合文件系统(UnionFS)
    • 一、联合文件系统(UnionFS)
    • 二、Docker 镜像的层级结构
    • 三、写层(Copy-on-Write)
    • 四、镜像构建缓存机制 = 层级缓存机制
    • 五、从镜像到容器,再到新镜像的完整闭环

🐳 Docker 入门教程(六):联合文件系统(UnionFS)


一、联合文件系统(UnionFS)

联合文件系统(Union File System,简称 UnionFS)是一种支持将多个只读层合并成一个文件系统视图的文件系统技术。Docker 正是通过它,实现了镜像分层构建与容器写层隔离。

换句话说,UnionFS 允许我们把多个只读目录“叠在一起”,让用户看到的是“一个统一的文件系统”。

它是镜像、容器分离的根本支撑。


二、Docker 镜像的层级结构

Docker 镜像并不是一个打包好的压缩文件,而是由多个只读层(layer)按顺序叠加而成的。

每一层都只包含自上一次变更以来的“文件系统差异”(增删改文件),例如:

FROM ubuntu            # 第1层:基础镜像层
RUN apt update         # 第2层:系统更新命令
RUN apt install nginx  # 第3层:安装 nginx
COPY . /app            # 第4层:拷贝项目代码

Docker 会为每一条指令生成一层(layer),每层是只读的,并存储为 SHA256 哈希命名的目录。

镜像分层的意义

  1. 高效复用:多个镜像可以共享相同的底层层(如基础镜像层)
  2. 按需下载:拉取镜像时会分层下载,避免重复传输
  3. 构建缓存:如果上一层没变化,Docker 会重用缓存而非重建镜像层
  4. 只读安全:镜像不能被容器改写,天然具备版本一致性

当你运行一个容器时,Docker 会将镜像层挂载到容器中,并在最上层添加一个“可写层”

容器文件系统结构:[ 写层 ] ← 运行时动态生成,容器唯一
[ 镜像层 4 ] ← COPY 指令
[ 镜像层 3 ] ← 安装依赖
[ 镜像层 2 ] ← 环境配置
[ 镜像层 1 ] ← 基础系统

这个结构就是典型的 UnionFS 挂载叠加形式,最上面一层是写层,其它都是只读的。


三、写层(Copy-on-Write)

容器在运行时的所有写操作(包括新增文件、修改配置、生成日志)都写入最上方的写层

镜像层是只读的,操作都写入写层——或者叫做容器层?

而对文件的读取操作,则从顶层依次向下查找第一个匹配项。

文件删除/修改时的行为(非常重要)

  • 删除文件:其实不会真的从下层删除,而是在写层记录“白名单”(whiteout)屏蔽该文件。
  • 修改文件:先把下层文件复制到写层,再修改(copy-on-write)

因此,镜像层始终保持不变,容器之间互不影响。

*联合文件系统的技术支持

Docker 支持多种联合文件系统驱动(取决于操作系统):

驱动类型系统支持特点
overlay2推荐默认(现代 Linux)高性能,内核直接支持
aufsUbuntu 较老版本最早使用,已过时
btrfs / zfs可选高级驱动支持快照、更复杂的挂载

你可以通过如下命令查看当前使用的存储驱动:

docker info | grep Storage

四、镜像构建缓存机制 = 层级缓存机制

在你执行 docker build 时,每一条 Dockerfile 指令生成的层会被缓存(只要内容没有变化)。

Docker 会根据上下文(比如文件 hash)决定是否使用缓存。

这意味着:

  • 如果你在 Dockerfile 的前几层频繁改动,会导致所有后续层都重新构建
  • 所以我们会说:“尽量把不变的层写在前面”

容器生命周期下的数据命运

操作写层会怎样?镜像层是否保留?
容器运行写层存在镜像只读保留
容器停止写层仍在镜像不变
容器删除写层随容器删除镜像不变
镜像被删除镜像层被移除(如果未被其它容器使用)容器无法重新启动

UnionFS 的局限与演进

  • 写层性能相对较低(尤其是随机写入时)
  • 对高频 IO 的容器(数据库)建议使用挂载卷(Volume)代替
  • 容器中的数据默认是临时的、不持久的

这就是为什么你运行完一个容器后,重启发现数据全没了 —— 因为写层随容器消失了。


五、从镜像到容器,再到新镜像的完整闭环

在理解 UnionFS 分层结构之后,我们可以进一步掌握 Docker 最核心的使用流程:镜像 → 容器 → 新镜像 → 分享

这个过程遵循如下原则:

  1. 镜像层始终只读:任何 docker pull 拉下来的镜像都是不可变的,它就像一个快照模板,不会因为运行或改动而被修改。

  2. 容器运行时增加一个可写层:当我们执行 docker run 时,Docker 会在镜像顶部叠加一个写层(Writable Layer),所有运行时的变动(文件操作、配置更改等)都记录在这一层中。

  3. 容器运行中的更改,仅影响写层:即使你在容器中删除、修改了镜像文件,实际上只是对写层进行“遮盖”或“拷贝修改”,镜像层依然保持原样不动。

  4. 通过提交或构建形成新镜像:一旦你在容器中完成了配置或开发,可以使用如下方式生成新的镜像:

    • docker commit 容器ID 新镜像名:将当前容器快照为新的镜像层
    • docker build:从 Dockerfile 定义新的镜像构建流程
  5. 新镜像仍由只读层组成:无论你是 commit 还是 build,最终产生的镜像都是只读层的组合,底层机制依旧是 UnionFS。

  6. 镜像可分发、复用:将新镜像 docker push 到远程仓库后,其他人可以 docker pull 下来,并基于你提交的状态继续运行容器、做进一步更改。

工作流图示(逻辑流程):

    [ 原始镜像层 ]          ← docker pull↓+------------------+| 容器写层(可写) |   ← docker run(运行时修改)+------------------+↓[ 新镜像层 ]             ← docker commit / build↓推送到远程仓库           ← docker push↓其他人拉取并运行         ← docker pull + run(再加写层)

示例说明

你运行一个 Python 镜像,安装 Flask,然后发布成镜像:

docker pull python:3.10
docker run -it python:3.10  # 安装 flask...
docker commit 容器ID my-python:flask
docker push my-python:flask

其他人:

docker pull my-python:flask
docker run -it my-python:flask  # 在这个基础上继续开发

这就形成了一个典型的“从模板 → 修改 → 发布新模板 → 再次复用”的开发链路。

这一机制正是 Docker 能够高效实现镜像复用、层级缓存、团队协作和 CI/CD 自动化的核心。

镜像层只读、可复用;容器层临时、可变动;新镜像则是将变动固化为新只读层,构成可传播的构建快照。

这一设计体现了 Docker 对文件系统和资源管理的高度抽象能力,是其轻量、高效、模块化的关键所在。
各级开发人员、运维人员、CI 系统可以在同一个基础镜像之上,逐层构建、逐层定制、逐层复用,实现真正的模块化构建流程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/86577.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/86577.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL在一个表中所有列查询某个值

使用场景:知道表名,同时知道这个表中含有某个字符串,但是不知道这个字符串是在表的哪些列,在列比较多的情况下,查询很麻烦,通过以下语句或者封装的存储可以查出字符串在哪些列出现。结果集里 ContainsValue…

【Outline】纯Docker部署指南

本文介绍了使用Docker部署Outline知识管理系统的完整流程。 主要内容包括: 部署PostgreSQL 12数据库并创建用户;安装Redis 6缓存服务;配置Minio对象存储服务替代AWS S3;搭建SSO单点登录服务器;准备Outline容器镜像和环…

终止分区表变更操作时误删数据字典缓存导致MySQL崩溃分析

终止分区表变更操作时误删数据字典缓存导致MySQL崩溃分析 1. 问题简述 在 MySQL 中,当终止一个处于 committing alter table to storage engine 阶段的分区表操作时,InnoDB 会尝试进行回滚并清理数据字典缓存。不幸的是,过程中发生了误删表…

进程关系与守护进程全解析

进程关系和守护进程 进程组 每一个进程除了有一个进程ID(PID)之外还属于一个进程组。进程组是一个或者多个进程的集合, 一个进程组可以包含多个进程,每一个进程组也有一个唯一的进程组ID(PGID), 并且这个PGID 类似于进程ID, 同样…

PyAutoGUI 测试框架

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】

Git安装避坑指南

Git高速下载 程序员面试资料大全|各种技术书籍等资料-1000G 一、安装前准备:避免环境冲突 1. 检查系统残留(Windows) # 检查旧版Git残留 where git where git.exe# 检查环境变量 $env:PATH -split ; | Select-String git# 清理…

MATLAB中的并行加速技术与工具

文章目录 MATLAB中的并行加速技术与工具1. 多线程计算(隐式并行)2. Parallel Computing Toolbox (并行计算工具箱)2.1 parfor (并行for循环)2.2 spmd (单程序多数据)2.3 parfeval (异步并行执行) 3. GPU计算4. 分布式计算 (MATLAB Parallel Server)5. 批…

GR00T N1.5 技术报告 -- Nvidia -- 2025.6.11 -- 开源

0. 前言 GR00T N1 的详细介绍 Isaac-GR00T 在6.11 进行了全面升级,从 N1 进化为 N1.5,但基本还是基于之前的架构,官方发布了一个技术报告,并更新了github库,之前的N1也做了独立版本 N1 N 1.5 github 技术报告 model…

SRS WebRTC 入门

什么是 SRS WebRTC? SRS (Simple Realtime Server) 是一个支持 WebRTC 流媒体的开源媒体服务器。它允许你建立基于 WebRTC 的低延迟直播和实时通信应用。 快速开始 1. 安装 SRS bash # 使用 Docker 快速安装 docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080…

从手机随拍到标准扫描件:AI如何智能校正证件照片(Python+OpenCV)

目录 一、概述二、解决方案2.1 核心挑战:AI眼中的“三座大山”2.2 设计思路:给AI一个“智能提示”2.3 实现流程:四步搞定 三、代码实现3.1 依赖库3.2 代码 四、结语 一、概述 在当今的线上业务中,要求用户上传身份证、驾驶证等证…

基于OpenCV图像分割与PyTorch的增强图像分类方案

在图像分类任务中,背景噪声和复杂场景常常会对分类准确率产生负面影响。为了应对这一挑战,本文介绍了一种结合OpenCV图像分割与PyTorch深度学习框架的增强图像分类方案。通过先对图像进行分割提取感兴趣区域(Region of Interest,R…

华为云对象存储OBS 支持安卓/iOS/鸿蒙UTS组件

华为云对象存储OBS 支持安卓/iOS/鸿蒙UTS组件 介绍使用前须知vue代码调用示例权限说明API调用说明初始化配置(openClient)创建桶(createBucket)列举桶(listBuckets)删除桶(deleteBucket&#xf…

Buildroot 2025.05 中文手册【AI高质量翻译】

译文在 Github 仓库 和 Gitee 仓库 保持最新,其它平台发的文档可能不会与之同步。 希望能够共同维护这个 仓库的 Buildroot 手册 中文译文,帮助更多人真正深入学习理解,更好的工作、生活和创造。 关于 AI 提示词 以及 更多工具 的收集&#…

采用ArcGIS10.8.2 进行插值图绘制

一、最终成果图展示 二、软件下载 链接: 百度网盘 请输入提取码 密码:azay 三、软件安装 1、在安装之前需要关闭电脑的防火墙及杀毒软件 设置-隐私和安全性-Windows安全中心-防火墙和网络保护 2、软件解压 (1)【ArcGIS_Desktop_1082_180......】“以管理员身份运行”…

Python网安-zip文件暴力破解(仅供学习)

目录 源码在这里 需要的模块 准备一个密码本和需要破解的ZIP文件 一行一行地从密码文件中读取每个密码。 核心部分 注意,需要修改上段代码注释里的这段具有编码问题的代码: 源码在这里 https://github.com/Wist-fully/Attack/tree/cracker 需要的…

如何让ChatGPT模仿人类写作,降低AIGC率?

在AI技术日益普及的当下,ChatGPT 等大语言模型已成为许多学术与写作任务中的得力助手。然而,学境思源,随着各类“AI检测系统”的出现,一键生成论文初稿!我们也遇到一个新的问题:如何让AI写作看起来不像AI写…

科大讯飞2025AI开发者大赛-用户新增赛道时间规则解析

根据训练集中的时间规则,对测试集中的数据推断用户标签(新用户或老用户)。 时间规则如下: 针对训练集和测试集中都存在的did: 找到在训练集中标记为新用户最晚的时间点,则测试集中对应did的数据在此时间点前全部为新用…

.NET C# async/定时任务的异步线程池调度方案最大线程数‌ = 处理器核心数 × 250

关于.NET中Threading.Timer的线程机制,结合线程池特性和异步协作原理分析如下: 一、线程复用机制 ‌共享进程级线程池‌ Threading.Timer的回调任务‌不会每次新建线程‌,而是提交到.NET进程全局线程池统一调度,该线程池与async/…

Redis 高可用分片集群:主从模式与哨兵机制详解

一、为何需要分片集群? 在讨论具体方案之前,我们先明确分片集群要解决的问题: 单节点瓶颈:无论是内存容量还是处理能力(QPS),单个 Redis 实例都有物理上限。高可用性需求:单点故障…

Qt readyRead信号避坑:不产生readyRead信号的解决方法

Qt readyRead信号避坑:不产生readyRead信号的解决方法 引言一、QSerialport的readyRead1.1 版本问题1.2 缓存问题1.3 阻塞问题 二、Q(Tcp)Socket的readyRead2.1 阻塞问题2.2 运行一段时间,突然不发信号2.3 和具体数据有关? 引言 目前没遇到相…