OCI 镜像标准 ↔ Docker 镜像分层原理

一、OCI 标准的本质

1. 容器镜像的官方定义

容器镜像是一个分层存储的归档文件(通常为 Tar 格式),包含运行容器所需的所有静态文件和元数据。其核心设计遵循开放容器倡议(OCI)标准,主要包含以下两部分

  • 容器镜像不是 Docker 发明的,而是有全球统一的行业标准(OCI 标准),Docker 只是这个标准的一个实现。
  • 核心对应 :Docker 镜像完全遵循 OCI 标准

2. 镜像的两大核心组成

(1)文件系统层(Rootfs)

提供容器的根文件系统(rootfs),与宿主机的文件系统隔离,是容器内进程看到的文件系统视图。

  • 就是容器里能看到的所有文件(/bin/etc、应用代码、依赖库等),相当于容器的「操作系统文件包」。
  • 和分层的对应 :Rootfs 不是一个大文件,而是由多个分层的layer.tar组成 ,每一个layer.tar就是 Docker 镜像里的一个只读镜像层,对应 Dockerfile 的一条指令。
  • 和 Overlay2 的对应 :这些layer.tar解压后,就是 Overlay2 里的lowerdir(只读镜像层),多个layer.tar通过 Overlay2 联合挂载,合并成容器看到的统一 Rootfs 视图。
(2)配置元数据(JSON 文件)

定义容器的运行时行为,包括进程配置、安全权限、环境变量等。

  • 就是镜像的「启动说明书」,告诉 Docker:用这个镜像启动容器时,要跑什么命令、用什么环境变量、给什么权限。
  • 和分层的对应 :元数据是独立于分层文件系统的配置信息,不属于任何一个镜像层,是整个镜像的「全局配置」。

二、OCI 三大关键文件 ↔ Docker 分层原理

关键文件(OCI 标准)有config.json,包含容器运行时配置;manifest.json,描述镜像的层级结构和配置文件的路径;layer.tar,每个文件系统层对应的压缩包,存储实际文件内容。

1. layer.tar:Docker 镜像分层的「实体」

  • OCI 定义:每个文件系统层对应的压缩包,存储实际文件内容。
  • Docker 对应
    • 每一个layer.tar,就是 Docker 镜像里的一个只读镜像层 ,对应 Dockerfile 的一条指令(比如RUN pip installCOPY . .)。
    • 你用docker history my-ml-app看到的每一层,本质就是一个layer.tar压缩包。
    • 这些layer.tar只读的 ,构建完成后永远不会修改,多个镜像可以共用相同的layer.tar(比如都用python:3.12-slim基础层),这就是 Docker 分层复用的本质。
  • 和 Overlay2 的对应layer.tar解压后,就是 Overlay2 的lowerdir(只读镜像层),多个layer.tar按顺序叠加,组成完整的 Rootfs。

2. manifest.json:Docker 镜像分层的「目录索引」

  • OCI 定义:描述镜像的层级结构和配置文件的路径。
  • Docker 对应
    • 相当于镜像的「目录清单」,记录了这个镜像有多少个layer.tar、每个layer.tar的顺序、config.json的位置。
    • Docker 构建镜像时,会自动生成manifest.json,用来管理分层的顺序和依赖,保证分层按正确的顺序合并。
    • 你用docker inspect my-ml-app看到的Layers字段,就是manifest.json里记录的分层信息。
  • 核心作用 :把零散的layer.tar,按顺序组织成一个完整的镜像,是分层结构的「管理者」。

3. config.json:Docker 镜像的「启动说明书」

  • OCI 定义:包含容器运行时配置。
  • Docker 对应
    • 就是你之前问的「JSON 格式的配置文件」,里面记录了容器启动的所有配置:CMD启动命令、ENV环境变量、WORKDIR工作目录、EXPOSE端口、用户权限等。
    • 这些配置不属于任何一个镜像层,是整个镜像的全局配置,Docker 启动容器时,会读取这个文件,按配置启动容器。
    • 你用docker inspect my-ml-app看到的Config字段,就是config.json里的内容。
  • 核心作用:定义容器的运行时行为,是镜像从「静态分层文件」变成「动态运行容器」的关键。

三、完整链路:OCI 标准 → Docker 分层 → Overlay2 落地

1. 构建镜像时(Dockerfile → OCI 标准 → 分层存储)

  1. 你写 Dockerfile,每一条指令对应一个只读镜像层
  2. Docker 执行docker build,按指令生成多个layer.tar(对应 OCI 的layer.tar);
  3. Docker 自动生成manifest.json(记录分层顺序)和config.json(记录运行配置),符合 OCI 标准;
  4. 所有layer.tarmanifest.jsonconfig.json打包成一个完整的 Docker 镜像,存储在/var/lib/docker/overlay2/目录下。

2. 启动容器时(分层 → Overlay2 → 容器运行)

  1. Docker 读取manifest.json,按顺序加载所有layer.tar(只读镜像层),作为 Overlay2 的lowerdir
  2. Docker 创建一个空的可写层(diff目录),作为 Overlay2 的upperdir
  3. Overlay2 把lowerdir(只读分层)和upperdir(可写层)合并成merged目录(容器的 Rootfs);
  4. Docker 读取config.json,按配置启动容器内的进程,容器看到的就是merged目录里的统一文件系统。

3. 容器运行时(分层隔离 + 写时复制)

  • 容器读文件:Overlay2 从upperdir(可写层)往下找lowerdir(只读分层),返回最上层的文件;
  • 容器写文件:Overlay2 把文件从lowerdir复制到upperdir,修改upperdir的文件,不影响lowerdir的只读分层(写时复制 CoW);
  • 容器删除:upperdir(可写层)被删除,lowerdir(只读分层)完全保留,下次启动容器直接复用。

四、一张表彻底对应

OCI 标准概念 对应 Docker 镜像分层原理 对应 Overlay2 存储
分层存储的归档文件 Docker 镜像的分层结构,每一层对应 Dockerfile 一条指令 Overlay2 的lowerdir(只读镜像层)
文件系统层(Rootfs) 容器的根文件系统,由多个只读分层合并而成 Overlay2 的merged目录(容器根目录)
配置元数据(JSON) 镜像的运行时配置,config.json 独立于分层,Docker 启动容器时读取
layer.tar 每个只读镜像层的压缩包,存储实际文件 lowerdir里的分层文件,解压后使用
manifest.json 镜像分层的目录索引,记录分层顺序和配置路径 管理lowerdir的分层顺序,保证合并正确
config.json 容器的启动说明书,记录运行时配置 Docker 启动容器时的配置依据

五、总结

1. 一句话打通关系

OCI 标准定义了容器镜像的本质:分层存储的归档文件,由layer.tar(分层文件)、manifest.json(分层索引)、config.json(运行配置)组成;Docker 镜像分层是 OCI 标准的落地实现,Overlay2 是把分层文件合并成容器 Rootfs 的底层存储驱动,三者是「标准→实现→落地」的关系。
容器镜像遵循 OCI 开放容器标准,本质是分层存储的 tar 归档文件,主要分两部分:第一部分是文件系统层(Rootfs),由多个layer.tar组成,每个layer.tar对应 Docker 镜像的一个只读层,对应 Dockerfile 的一条指令,通过 Overlay2 联合挂载成容器的根文件系统;第二部分是配置元数据,包含config.json(容器运行时配置)和manifest.json(分层结构索引),config.json定义容器启动命令、环境变量等,manifest.json管理分层顺序,保证分层按正确顺序合并。Docker 镜像分层就是 OCI 标准的落地,Overlay2 是实现分层合并的底层技术,这就是容器镜像的完整原理。


六、补充:实战验证

1. 查看镜像的 OCI 标准文件

你可以把 Docker 镜像导出,直接看到 OCI 标准的三个文件:

复制代码
# 导出镜像为tar包
docker save my-ml-app -o my-ml-app.tar
# 解压tar包
tar -xvf my-ml-app.tar
# 查看解压后的文件
ls

你会看到:

  • 多个layer.tar(对应每个只读镜像层)
  • manifest.json(分层索引)
  • xxx.json(就是config.json,文件名是镜像 ID)

2. 查看config.json的内容

复制代码
cat <镜像ID>.json

你会看到里面的CmdEnvWorkingDir等字段,完全对应 Dockerfile 的配置,就是图里说的「配置元数据」。

3. 查看manifest.json的内容

复制代码
cat manifest.json

你会看到里面的Layers数组,记录了每个layer.tar的路径,就是图里说的「描述镜像的层级结构」。


七、常见误区纠正(彻底消除混淆)

  1. 误区config.json是镜像分层的一部分。✅ 纠正:config.json是独立于分层的元数据,不属于任何一个layer.tar,是整个镜像的全局配置。
  2. 误区layer.tar是可写的。✅ 纠正:layer.tar是只读的,容器的修改只会存在于 Overlay2 的upperdir(可写层),不会修改layer.tar
  3. 误区manifest.json是 Docker 特有的。✅ 纠正:manifest.json是 OCI 标准的一部分,所有符合 OCI 标准的容器镜像(比如 Podman、CRI-O 的镜像)都有这个文件,不是 Docker 专属。
  4. 误区 :Rootfs 就是一个大的 tar 包。✅ 纠正:Rootfs 是多个layer.tar分层合并的结果,不是一个大 tar 包,分层是 OCI 标准的核心设计。
相关推荐
斯普信云原生组2 小时前
Docker 开源软件应急处理方案及操作手册——日常维护与监控命令集
docker·容器·eureka
迷路爸爸1802 小时前
Docker 入门学习笔记 01:它到底解决了什么问题,镜像和容器又是什么
服务器·笔记·学习·docker·容器
闻哥2 小时前
Docker Swarm 负载均衡深度解析:VIP vs DNSRR 模式详解
java·运维·jvm·docker·容器·负载均衡
正经教主15 小时前
【docker基础】第一课、从零开始理解容器技术
docker·云原生·容器·eureka
萌萌哒草头将军16 小时前
CloudDock(云仓):新一代开源NAS网络代理工具
服务器·网络协议·docker
正经教主18 小时前
【docker基础】0、系统学习docker之总计划
学习·docker·容器
Yang三少喜欢撸铁18 小时前
【Centos7通过kubeadm方式部署kubernetes1.30版本【一主两从】】
docker·kubernetes·container
杨浦老苏21 小时前
开源宠物健康护理追踪器EinVault
docker·群晖·宠物·健康管理
@土豆21 小时前
基于Docker部署Squid正向代理文档
运维·docker·容器