Skip to content

Docker 镜像清单 Manifest 详解

Docker 镜像清单(Manifest)主要有 v2s1 (Schema 1)v2s2 (Schema 2)OCI 三种核心类型,它们是容器镜像的“元数据描述文件”,定义了镜像层、配置、架构等关键信息。

Docker V2 Schema 1 (v2s1)

  • 全称:Docker Image Manifest V2, Schema 1
  • 媒体类型application/vnd.docker.distribution.manifest.v1+json
  • 诞生背景:Docker 1.3~1.9 时代的过渡格式,兼容旧版 V1 镜像
  • 核心特点
    • 兼容旧版 Docker 客户端(1.9 及以下)
    • 基于层 ID 父子关系描述,非内容寻址
    • 结构冗余、体积大、安全性低、无多架构支持
    • 已废弃:2017 年后主流仓库(Docker Hub、ACR)逐步停止支持

Docker V2 Schema 2 (v2s2)(主流标准)

  • 全称:Docker Image Manifest V2, Schema 2
  • 媒体类型
    • 单架构:application/vnd.docker.distribution.manifest.v2+json
    • 多架构(Manifest List):application/vnd.docker.distribution.manifest.list.v2+json
  • 诞生背景:Docker 1.10+ 启用,现代 Docker 镜像默认格式
  • 核心特点
    • 内容寻址:层与配置用 SHA256 摘要标识,内容相同 ID 相同
    • 支持多架构镜像(fat manifest),一个 Tag 对应多平台(amd64/arm64)
    • 结构精简、分层清晰、兼容性强、安全性高
    • 当前主流:Docker、K8s、主流镜像仓库(Docker Hub、ACR、ECR)全兼容

OCI (Open Container Initiative)(行业开放标准)

  • 全称:OCI Image Manifest Specification v1
  • 媒体类型
    • 单架构:application/vnd.oci.image.manifest.v1+json
    • 多架构(Index):application/vnd.oci.image.index.v1+json
    • 空清单:application/vnd.oci.empty.v1+json(你报错的类型)
  • 诞生背景:2017 年基于 Docker v2s2 制定的开放容器标准,厂商中立
  • 核心特点
    • 与 v2s2 90% 结构兼容,媒体类型、字段命名不同
    • 支持空清单vnd.oci.empty)、OCI Artifacts(非容器镜像存储)
    • 更开放、可扩展,适配 Podman、containerd、K3s 等工具
    • 兼容性问题:部分旧版仓库(如阿里云 ACR 旧版)不支持 OCI 空清单

核心区别对比

维度Docker v2s1Docker v2s2OCI v1
媒体类型vnd.docker.distribution.manifest.v1+json单架构:v2+json
多架构:list.v2+json
单架构:oci.image.manifest.v1+json
多架构:index.v1+json
内容寻址❌ 不支持(层 ID 关联)✅ 支持(SHA256 摘要)✅ 支持(SHA256 摘要)
多架构❌ 不支持✅ 支持(Manifest List)✅ 支持(Image Index)
空清单❌ 无❌ 无✅ 支持(vnd.oci.empty
Docker 兼容1.9-1.10+17.06+
仓库兼容逐步废弃全兼容(含 ACR)主流兼容(ACR 旧版不支持空清单)
状态❌ 废弃✅ 主流稳定✅ 未来标准(有兼容坑)

结构与关键字段(精简示例)

v2s2 单架构 Manifest

json
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
  "config": {
    "mediaType": "application/vnd.docker.container.image.v1+json",
    "digest": "sha256:xxx",
    "size": 7023
  },
  "layers": [
    {
      "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
      "digest": "sha256:yyy",
      "size": 283456
    }
  ]
}

OCI 单架构 Manifest

json
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:xxx",
    "size": 7023
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:yyy",
      "size": 283456
    }
  ]
}

OCI 空清单(vnd.oci.empty

json
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.empty.v1+json"
}
  • 作用:OCI 规范兼容占位,无实际镜像数据
  • 问题阿里云 ACR 拒绝接收 OCI 空清单,会抛出 unknown manifest class 错误

兼容性与踩坑指南

为什么阿里云 ACR 报错?

  • 同步的 moby/buildkit:buildx-stable-1OCI 多架构镜像,包含 vnd.oci.empty.v1+json 空清单
  • 阿里云容器服务 旧版/安全策略 不识别/拒绝 OCI 空清单类型
  • 结论:ACR 兼容 OCI 标准镜像,但不兼容 OCI 空清单

不同场景选型建议

  • 生产推送阿里云 ACR优先用 v2s2,或同步时指定 --platform 跳过 OCI 空清单

    bash
    # skopeo 强制 v2s2 格式推送
    skopeo copy --format v2s2 ......
  • 本地/自建仓库:OCI 更灵活,支持多架构与 Artifacts

  • CI/CD 跨仓库同步:用 --format v2s2 兼容所有云厂商(阿里云、腾讯云、AWS)

常用命令

  • 查看镜像 Manifest 类型

    bash
    docker manifest inspect moby/buildkit:buildx-stable-1
    # 或
    skopeo inspect docker://moby/buildkit:buildx-stable-1 --raw | jq .mediaType
  • 强制转换为 v2s2

    bash
    # 拉取 → 重新打标 → 推送(自动转 v2s2)
    docker pull --platform linux/amd64 moby/buildkit:buildx-stable-1
    docker tag ... registry.cn-hangzhou.aliyuncs.com/...
    docker push ...

总结

  1. v2s1:废弃过渡格式,不要用
  2. v2s2当前最稳、全兼容,推送阿里云首选
  3. OCI:开放标准、未来趋势,但空清单在 ACR 报错
  4. 你的问题解法:同步时加 --platform linux/amd64--format v2s2,跳过 OCI 空清单