导读:本期聚焦于杨建军创作的《容器镜像格式 OCI 与 Docker 有什么区别?一文讲透镜像规范的演进与差异》,敬请观看详情。容器镜像格式为什么要分 OCI 和 Docker 两套规范?不少人在拉取镜像时见过同名却不同标识的镜像,却说不清背后 OCI 规范与 Docker V2 格式的具体差别。本文从 Docker 镜像格式的历史演进讲起,梳理 OCI Image Specification 的诞生背景,深入对比 manifest、config、layers 三大核心文件的结构差异,分析 media type 命名、镜像分发协议、构建工具兼容性等方面的实际影响,并结合 skopeo、crane 等工具演示如何在不同格式之间转换与检查,帮助你理解镜像在构建、推送、拉取全链路中的格式细节。

容器技术发展至今,镜像格式已经从 Docker 一家独大演变为 OCI 开放标准。很多初学者在使用 podman、buildah 或 containerd 时,会发现这些工具构建出的镜像与 Docker 构建的镜像在结构上略有不同,甚至 registry 中的 manifest 类型也分为 Docker V2 和 OCI 两种。要理解这些差异,需要回到镜像格式的历史演进过程中去看,才能明白 OCI 规范解决了什么问题,以及两者在文件结构、媒体类型、分发协议上的具体区别。

容器镜像格式 OCI 与 Docker 有什么区别?一文讲透镜像规范的演进与差异

一、Docker 镜像格式的演进历史

Docker 早期的镜像格式称为 Schema 1,这是 2013 年 Docker 刚问世时使用的格式。Schema 1 存在很多设计缺陷,比如没有内容寻址机制、镜像签名逻辑混乱、层与层之间的父子关系依赖 manifest 中的引用链来维护。这些缺陷导致镜像在被篡改或损坏时难以校验,也使得多架构镜像几乎无法实现。

2016 年 Docker 推出了 Schema 2,也就是现在常说的 Docker V2 格式。它引入了内容寻址(Content Addressable)机制:镜像的每一层都通过其内容的 SHA256 摘要来标识,manifest 本身也有 digest。这种设计让镜像校验变得简单可靠,同时引入了 manifest list 的概念,为多架构镜像铺平了道路。一个典型的 Docker V2 镜像由三部分组成:manifest 清单文件、config 配置文件和若干 layer 层文件。

Docker V2 的 manifest 使用 application/vnd.docker.distribution.manifest.v2+json 这样的 media type 标识,config 使用 application/vnd.docker.container.image.v1+json,每一层则使用 application/vnd.docker.image.rootfs.diff.tar.gzip。这一命名体系完全是 Docker 私有的,也就埋下了后来标准化的伏笔——如果整个容器生态都依赖 Docker 的私有格式,其他运行时就很难摆脱对 Docker 的依赖。

二、OCI 规范的诞生与核心结构

2015 年,Docker 联合 CoreOS、Google、Red Hat 等公司成立了 OCI(Open Container Initiative)组织,目标是制定开放的容器标准。最初 OCI 只定义了运行时规范 runtime-spec,镜像格式规范 image-spec 直到 2017 年才发布 1.0 版本。OCI 镜像规范在很大程度上借鉴了 Docker V2 的设计,可以说是在其基础上做了一次“去 Docker 化”的标准化整理。

OCI 镜像同样由 manifest、config 和 layers 组成,文件结构几乎一致,最大的区别在于 media type 的命名。OCI 规范将所有媒体类型统一收纳到 application/vnd.oci 命名空间下,例如 manifest 使用 application/vnd.oci.image.manifest.v1+json,config 使用 application/vnd.oci.image.config.v1+json,层文件使用 application/vnd.oci.image.layer.v1.tar+gzip。

一个 OCI manifest 的典型结构如下,可以看到与 Docker V2 的差异主要在 media type 字段上:

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:8f1b3e2c...",
    "size": 1234
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:a1c4e5d6...",
      "size": 34567890
    }
  ]
}

此外,OCI 规范引入了 artifact 类型支持,允许在 manifest 中通过 artifactType 字段声明镜像承载的是任意制品而不仅是容器镜像,比如 Helm Chart、WASM 模块、签名数据等。这是 OCI 1.1 版本的重要扩展,也是如今很多项目把 OCI Registry 当作通用制品仓库的技术基础。

三、两种格式的实际差异与兼容性处理

从文件层面看,Docker V2 与 OCI 镜像的层内容是完全兼容的,都是压缩的 tar 归档,digest 计算方式也一致。也就是说同一个 layer 文件在两种格式下可以复用,区别只在于外层的 manifest 和 config 描述。真正影响使用的是分发环节:当容器引擎向 Registry 拉取镜像时,会根据 Accept 头声明自己支持的 media type,Registry 则返回对应格式的 manifest。

Docker 从 23.0 版本开始默认推送 OCI 格式的镜像,而 containerd、podman 等工具更早就以 OCI 为主要格式。这就带来一个实际问题:如果一个老旧的私有 Registry 只支持 Docker V2,接收 OCI 镜像时可能直接报错,或者把 OCI manifest 当作未知类型处理。反过来,主流公共仓库如 Docker Hub、ghcr.io、quay.io 都已同时支持两种格式,日常使用感知不到差别。

在实际运维中,可以使用 skopeo 或 crane 检查和转换镜像格式。skopeo 的 inspect 命令能够查看远端镜像的真实 media type:

# 查看远端镜像的 manifest 类型
skopeo inspect --raw docker://docker.io/library/nginx:latest | head -5

# 将 Docker V2 镜像转换为 OCI 格式存储到本地目录
skopeo copy docker://docker.io/library/nginx:latest oci:/tmp/nginx-oci:latest

# 将 OCI 布局目录推送到其他 registry 并保持格式
skopeo copy oci:/tmp/nginx-oci:latest docker://registry.ipipp.com/ops/nginx:latest

对于构建工具,BuildKit 和 buildah 都提供了格式控制参数。例如 buildah 可以在构建时明确指定 manifest 类型,避免目标仓库不兼容的尴尬。而 Docker 的 daemon 配置中也可以通过 "features": {"containerd-snapshotter": true} 等方式调整存储行为。

四、如何选择:面向未来还是兼容存量

如果是新搭建的基础设施,推荐全面采用 OCI 格式。OCI 是社区共同维护的开放标准,不存在厂商锁定问题,artifact 扩展也让同一套 Registry 能承载更多类型的制品。Kubernetes 生态中的镜像安全扫描、签名验证工具(如 cosign、trivy)也都以 OCI 规范为优先支持对象。

如果环境中存在大量存量系统,比如旧版本的 Harbor 或自研 Registry 代理,就需要先确认它们对 OCI manifest 的支持情况,必要时用 skopeo 做格式归一化处理。一个常见的实践是在 CI 流水线中统一产出 OCI 格式镜像,并在推送前校验目标 Registry 的能力,出现不兼容时自动降级为 Docker V2 格式重新推送。

总的来说,Docker V2 与 OCI 镜像在核心数据结构上高度相似,层内容完全互通,差异集中在 media type 命名和制品扩展能力上。理解了这一点,遇到格式相关的报错时就能快速定位:多数问题都出在 Registry 对某种 manifest 类型不支持,而不是镜像内容本身损坏。掌握 skopeo、crane 这类工具的检查与转换方法,基本可以应对所有格式兼容场景。

OCI镜像规范Docker镜像容器镜像格式修改时间:2026-09-16 13:34:37

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0916/57971.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。