一、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 install、COPY . .)。
    • 你用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.tar、manifest.json、config.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

你会看到里面的Cmd、Env、WorkingDir等字段,完全对应 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 标准的核心设计。

更多推荐