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 v2s1 | Docker v2s2 | OCI 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-1是 OCI 多架构镜像,包含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 类型
bashdocker 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 ...
总结
- v2s1:废弃过渡格式,不要用
- v2s2:当前最稳、全兼容,推送阿里云首选
- OCI:开放标准、未来趋势,但空清单在 ACR 报错
- 你的问题解法:同步时加
--platform linux/amd64或--format v2s2,跳过 OCI 空清单
