Open Container Initiative(OCI)
镜像格式规范
Open Container Initiative(开放容器倡议,简称:OCI)
Image Format Specification(镜像格式规范)
该规范定义了一个 OCI 镜像,它由一个镜像清单(image manifest)、一个镜像索引(image index)(可选)、一组文件系统层(文件系统层)和一个配置(configuration)组成。
此规范的目标是创建可互操作的工具,用于构建、传输和准备要运行的容器映像。
Table of Contents
- Notational Conventions(符号约定)
- Overview(概览)
- Understanding the Specification(理解规范)
- Media Types(媒体类型)
- Content Descriptors(内容描述符)
- Image Layout(镜像布局)
- Image Manifest(镜像清单)
- Image Index(镜像索引)
- Filesystem Layers(文件系统层)
- Image Configuration(镜像配置)
- Annotations(注解)
- Conversion(转换)
- Considerations(注意事项)
- Extensibility(可拓展性)
- Canonicalization(规范化)
Notational Conventions(符号约定)
关键词 MUST
, MUST NOT
, REQUIRED
, SHALL
, SHALL NOT
, SHOULD
, SHOULD NOT
, RECOMMENDED
, NOT RECOMMENDED
, MAY
, 和 OPTIONAL
应按照RFC 2119中的描述进行解释(Bradner,S.,“用于在 RFC 中指示要求级别的关键词”,BCP 14,RFC 2119,1997 年 3 月)。
关键词 unspecified
, undefined
, 和 implementation-defined
应按照 C99 标准的基本原理中所述进行解释。
如果某个实现无法满足其实现的协议的MUST
, MUST NOT
, REQUIRED
, SHALL
, 或 SHALL NOT
中的一个或多个要求,则该实现不合规。如果实现满足其实现的协议的所有MUST
, MUST NOT
, REQUIRED
, SHALL
, 和SHALL NOT
的要求,则该实现是合规的。
Overview(概览)
从高层次来看,镜像清单包含有关镜像内容和依赖项的元数据,其中包括一个或多个文件系统层差异集(filesystem layer changeset)存档的内容可寻址标识,这些存档将被解压以构成最终可运行的文件系统。镜像配置包括应用程序参数、环境等信息。镜像索引是一个更高级别的清单,指向清单和描述符的列表。通常,这些清单可能提供镜像的不同实现,可能因平台或其他属性而异。
一旦构建,OCI 映像就可以通过名称发现、下载、通过哈希验证、通过签名信任,并解压到 OCI 运行时包(OCI Runtime Bundle.)中。
Understanding the Specification(理解规范)
OCI 镜像媒体类型(OCI Image Media Types)文档是理解规范整体结构的起点。
该规范的高级组成部分包括:
- Image Manifest(镜像清单) - 描述容器镜像组成组件的文档
- Image Index(镜像索引) - 带注释的清单
- Image layout(镜像布局) - 表示镜像内容的文件系统布局、
- Filesystem Layer(文件系统层) - 描述容器文件系统的差异集
- Image Configuration(镜像配置) - 确定适合转换为运行时包的镜像的层顺序和配置的文档
- Conversion(转换) - 描述如何进行翻译的文档
- Artifact Guidance() - 一份描述如何使用该规范打包除 OCI 镜像之外的内容的文档
- Descriptor() - 描述引用内容的类型、元数据和内容地址的引用
本规范的未来版本可能包括以下可选功能:
- 基于签名镜像内容地址的签名
- 基于 DNS 联合且可委托的命名
OCI Image Media Types(OCI 镜像媒体类型)
以下媒体类型标识了此处描述的格式及其引用的资源:
application/vnd.oci.descriptor.v1+json
: Content Descriptorapplication/vnd.oci.layout.header.v1+json
: OCI Layoutapplication/vnd.oci.image.index.v1+json
: Image Indexapplication/vnd.oci.image.manifest.v1+json
: Image manifestapplication/vnd.oci.image.config.v1+json
: Image configapplication/vnd.oci.image.layer.v1.tar
: “Layer”, as a tar archiveapplication/vnd.oci.image.layer.v1.tar+gzip
: “Layer”, as a tar archive compressed with gzipapplication/vnd.oci.image.layer.v1.tar+zstd
: “Layer”, as a tar archive compressed with zstdapplication/vnd.oci.empty.v1+json
: Empty for unused descriptors
以下媒体类型标识具有分发限制的“层”,但已被弃用并且不建议在将来使用:
application/vnd.oci.image.layer.nondistributable.v1.tar
: “Layer”, as a tar archiveapplication/vnd.oci.image.layer.nondistributable.v1.tar+gzip
: “Layer”, as a tar archive with distribution restrictions compressed with gzipapplication/vnd.oci.image.layer.nondistributable.v1.tar+zstd
: “Layer”, as a tar archive with distribution restrictions compressed with zstd
Media Type Conflicts(媒体类型冲突)
Blob
检索方法MAY
返回媒体类型元数据。例如,HTTP 响应可能会返回 Content-Type
标头设置为 application/vnd.oci.image.manifest.v1+json
的清单。实现可能还对 blob
的媒体类型和摘要有期望(例如来自引用 blob
的描述符)。
- 没有 Blob 预期媒体类型的实现
SHOULD
尊重返回的媒体类型。 - 具有与返回的媒体类型匹配的预期媒体类型的实现
SHOULD
尊重匹配的媒体类型。 - 如果实现的预期媒体类型与返回的媒体类型不匹配,则
SHOULD
:- 如果
blob
与预期摘要匹配,则遵循预期的媒体类型。实现MAY
会警告媒体类型不匹配。 - 如果
blob
与预期摘要不匹配,则返回错误(如描述符所建议的那样)。 - 如果他们没有预期的摘要,则返回错误。
- 如果
Compatibility Matrix(兼容性矩阵)
OCI 镜像规范力求尽可能地向前和向后兼容。破坏与现有系统的兼容性会给用户带来负担,无论它们是构建系统、分发系统、容器引擎等。本节展示 OCI 镜像规范与 OCI 镜像外部格式以及本规范的不同版本的兼容情况。
application/vnd.oci.image.index.v1+json
类似/相关的架构:
application/vnd.docker.distribution.manifest.list.v2+json
.annotations
: 仅存在于 OCI 中.[]manifests.annotations
: 仅存在于 OCI 中.[]manifests.urls
: 仅存在于 OCI 中
application/vnd.oci.image.manifest.v1+json
类似/相关的架构:
application/vnd.docker.distribution.manifest.v2+json
.annotations
: 仅存在于 OCI 中.config.annotations
: 仅存在于 OCI 中.config.urls
: 仅存在于 OCI 中.[]layers.annotations
: 仅存在于 OCI 中
application/vnd.oci.image.layer.v1.tar+gzip
可互换且完全兼容的 MIME 类型:
application/vnd.docker.image.rootfs.diff.tar.gzip
application/vnd.oci.image.config.v1+json
类似/相关的架构:
application/vnd.docker.container.image.v1+json
(Docker Image Spec v1.2).config.Memory
: 仅存在于 Docker 中,并在 OCI 中保留.config.MemorySwap
: 仅存在于 Docker 中,并在 OCI 中保留.config.CpuShares
: 仅存在于 Docker 中,并在 OCI 中保留.config.Healthcheck
: 仅存在于 Docker 中,并在 OCI 中保留
- Moby/Docker
.config.ArgsEscaped
: Windows 特定的 Moby/Docker 扩展,在 OCI 中已弃用,可用于与旧图像兼容。.config.StopSignal
和.config.Labels
在 Docker Image Spec v1.2 中意外未记录,但这些字段不是 OCI 特定的概念。
Relations(关系)
下图显示了上述媒体类型如何相互引用:
描述符用于所有引用。镜像索引是“胖清单”,它引用每个目标平台的镜像清单列表。镜像清单只引用一个目标配置,也可能引用多个层。
OCI Content Descriptors(OCI内容描述符)
- OCI 镜像由几个不同的组件组成,以 Merkle 有向无环图 (DAG) 排列。
- 图中组件之间的引用通过内容描述符来表达。
- 内容描述符(或简称描述符)描述目标内容的配置。
- 内容描述符包括内容类型、内容标识符(摘要)和原始内容的字节大小。它还可以包括其描述的工件类型。
- 描述符
SHOULD
嵌入其他格式以安全地引用外部内容。 - 其他格式
SHOULD
使用描述符来安全地引用外部内容。
本节定义 application/vnd.oci.descriptor.v1+json
媒体类型。
属性
描述符由一组封装在键值对字段中的属性组成。
以下字段包含构成描述符的主要属性:
mediaType
string
此REQUIRED
属性包含所引用内容的媒体类型。值MUST
符合 RFC 6838,包括其第 4.2 节中的命名要求。
digest
string
此REQUIRED
属性是目标内容的摘要,符合摘要中概述的要求。通过不受信任的来源使用时,SHOULD
根据此摘要验证检索到的内容。
size
int64
此REQUIRED
属性指定原始内容的大小(以字节为单位)。此属性的存在是为了使客户端在处理之前了解内容的预期大小。如果检索到的内容的长度与指定的长度不匹配,则SHOULD NOT
信任该内容。
urls
array of strings此
OPTIONAL
属性指定可从中下载此对象的 URI 列表。每个条目MUST
符合 RFC 3986。条目SHOULD
使用 RFC 7230 中定义的http
和https
方案。annotations
string-string map
此OPTIONAL
属性包含此描述符的任意元数据。此OPTIONAL
属性MUST
使用注释规则。
data
string
此OPTIONAL
属性包含所引用内容的嵌入表示。值MUST
符合 Base 64 编码,如 RFC 4648 中所定义。
artifactType
string
当描述符指向工件时,此OPTIONAL
属性包含工件的类型。当描述符引用镜像清单时,这是配置描述符 mediaType
的值。如果定义了,该值MUST
符合 RFC 6838,包括其第 4.2 节中的命名要求,并且可以向 IANA 注册。
指向 application/vnd.oci.image.manifest.v1+json
的描述符SHOULD
包括扩展字段platform
,详情请参阅图像索引属性描述。
Reserved
其他 OCI 规范中提出的扩展描述符字段添加SHOULD
首先考虑添加到本规范中。
Digests
描述符的摘要属性充当内容标识符,实现内容可寻址性。它通过对字节进行抗碰撞哈希处理来唯一地标识内容。如果摘要可以以安全的方式进行传达,则可以通过独立重新计算摘要来验证来自不安全来源的内容,确保内容没有被修改。
digest
属性的值是一个由算法部分和编码部分组成的字符串。算法指定用于摘要的加密哈希函数和编码;编码部分包含哈希函数的编码结果。
摘要字符串MUST
符合以下语法:
|
|
请注意,算法可能会对编码部分的语法施加特定于算法的限制。另请参阅注册算法。
一些示例摘要字符串包括以下内容:
digest | algorithm | Registered |
---|---|---|
sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b | SHA-256 | Yes |
sha512:401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b372742... | SHA-512 | Yes |
multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 | Multihash | No |
sha256+b64u:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564 | SHA-256 with urlsafe base64 | No |
请参阅注册算法以获取注册算法的列表。
如果符合上述语法,实现SHOULD
允许具有无法识别的算法的摘要通过验证。虽然 sha256 只使用十六进制编码的摘要,但算法中的分隔符和编码中的字母数字都包含在内,以允许扩展。举例来说,我们可以将编码和算法参数化为 multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8
,这将被视为有效但未根据本规范注册。
Verification
在使用来自不受信任来源的描述符所针对的内容之前,SHOULD
根据摘要字符串验证字节内容。
在计算摘要之前,SHOULD
验证内容的大小以减少哈希冲突空间。SHOULD
避免在计算哈希之前进行大量处理。实现MAY
采用底层内容的规范化来确保内容标识符的稳定。
Digest calculations
摘要通过以下伪代码计算,其中 H
是选定的哈希算法,由字符串 <alg>
标识:
|
|
上面,我们将内容标识符定义为ID(C)
,从Descriptor.digest
字段中提取。内容 C
是一串字节。函数 H
返回 C
的哈希值(以字节为单位),并将其传递给函数 Encode
并加上算法前缀以获得摘要。验证结果为真,若ID(C)
等于D
,确认C
为D
所标识的内容。经验证,以下内容为真:
|
|
通过独立计算摘要,确认摘要为内容标识符。
Registered algorithms
虽然摘要字符串的算法部分允许使用多种加密算法,但兼容的实现SHOULD
使用 SHA-256
。
本规范当前定义了以下算法标识符:
algorithm identifier | algorithm |
---|---|
sha256 | SHA-256 |
sha512 | SHA-512 |
如果有用的算法没有包含在上表中,则SHOULD
将其提交给本规范进行注册。
SHA-256
SHA-256 是一种抗碰撞哈希函数,因其普及性、合理大小和安全特性而被选中。实现MUST
实现 SHA-256
摘要验证以供在描述符中使用。
当算法标识符为 sha256
时,编码部分必须匹配 /[a-f0-9]{64}/
。请注意,此处不得使用 [A-F]
。
SHA-512
SHA-512 是一种抗碰撞哈希函数,在某些 CPU 上可能比 SHA-256 性能更好。实现MAY
实现 SHA-512 摘要验证以用于描述符。
当算法标识符为 sha512
时,编码部分必须匹配 /[a-f0-9]{128}/
。请注意,此处不得使用 [A-F]
Embedded Content
在许多情况下,例如通过网络下载内容时,将描述符解析为其内容具有可测量的固定“往返(roundtrip)”延迟成本。对于较大的 blob
,固定成本通常微不足道,因为大部分时间都花在实际获取内容上。对于非常小的 blob
,固定成本可能相当高。
实现MAY
选择将小块内容直接嵌入描述符中以避免往返。
在这样做会修改现有内容标识符的情况下,实现MUST NOT
填充data
字段。例如,注册中心MUST NOT
任意填充已上传清单中的data
字段,因为这会修改这些清单的内容标识符。相反,客户端MAY
在上传清单之前填充data
字段,因为清单在注册表中还没有内容标识符。
在决定是否嵌入数据时,实现SHOULD
考虑可移植性,因为有些提供商已知会拒绝接受或解析超过一定大小的清单。
Examples
以下示例描述了内容标识符为sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270
且大小为 7682 字节的 Manifest
:
|
|
在以下示例中,描述符指示可以从特定 URL 检索所引用的清单:
|
|
在以下示例中,描述符指示了其引用的工件类型:
|
|
OCI Image Layout Specification(OCI 镜像布局规范)
OCI 镜像布局是 OCI 内容可寻址
blob
和位置可寻址引用 (refs) 的目录结构。此布局
MAY
用于各种不同的传输机制:存档格式(例如 tar、zip)、共享文件系统环境(例如 nfs)或网络文件获取(例如 http、ftp、rsync)。
给定一个图像布局和引用,工具可以通过以下方式创建 OCI 运行时规范包:
- 按照 ref 查找清单(manifest),可能是通过镜像索引(image index)
- 按指定顺序应用文件系统层
- 将镜像配置转换为 OCI 运行时规范
config.json
Content
镜像布局如下:
blobs
目录- 包含内容可寻址的
blob
blob
没有架构,SHOULD
被视为不透明- 目录
MUST
存在,且MAY
为空 - 请参阅
blob
部分
- 包含内容可寻址的
oci-layout
文件- 它
MUST
存在 - 它
MUST
是 JSON 对象 - 它
MUST
包含imageLayoutVersion
字段 - 请参阅
oci-layout
文件部分 - 它
MAY
包含其他字段
- 它
index.json
文件- 它
MUST
存在 - 它
MUST
是图像索引 JSON 对象。 - 请参阅
index.json
部分
- 它
Example Layout
这是一个示例镜像布局:
|
|
Blob 根据其内容命名:
|
|
Blobs
blobs
子目录中的对象名称由每个哈希算法的目录组成,其子目录将包含实际内容。blobs/<alg>/<encoded>
的内容MUST
与摘要<alg>:<encoded>
匹配(每个描述符引用)。例如,blobs/sha256/da39a3ee5e6b4b0d3255bfef95601890afd80709
的内容MUST
与摘要sha256:da39a3ee5e6b4b0d3255bfef95601890afd80709
匹配。<alg>
和<encoded>
的条目名称的字符集MUST
与描述符中描述的各自语法元素匹配。blobs
目录MAY
包含未被任何 refs 引用的blob
blobs
目录MAY
缺少引用的 Blob,在这种情况下,缺少的blob
SHOULD
由外部blob
存储区补充。
Example Blobs
|
|
|
|
|
|
|
|
oci-layout file
此 JSON 对象作为开放容器镜像布局基础的标记,并提供正在使用的镜像布局的版本。在对布局进行更改时,imageLayoutVersion
值将与 OCI 镜像规范版本保持一致,并且将固定给定版本,直到需要更改镜像布局为止。本节定义 application/vnd.oci.layout.header.v1+json
媒体类型。
oci-layout Example
|
|
index.json file
此REQUIRED
文件是镜像布局的引用和描述符的入口点。镜像索引是一个多描述符入口点。
该索引提供了一个既定的路径(/index.json
)作为镜像布局的入口点并发现辅助描述符。
- 对于描述符的
org.opencontainers.image.ref.name
注释没有给出语义限制。 - 一般来说,
manifests
字段中每个描述符对象的mediaType
将是application/vnd.oci.image.index.v1+json
或application/vnd.oci.image.manifest.v1+json
。 - 该规范的未来版本
MAY
会使用不同的媒体类型(即新版本的格式)。 - 遇到未知的
mediaType
MUST NOT
能产生错误。
实现者者的注意事项:带有org.opencontainers.image.ref.name
注释的描述符的常见用例是表示容器镜像的tag
。例如,一个镜像可能带有软件不同版本或构建的标签。在现实中,您经常会看到v1.0.0-vendor.0
、2.0.0-debug
等tag
。这些标签通常会在镜像布局存储库中表示,并带有匹配的org.opencontainers.image.ref.name
注释,如v1.0.0-vendor.0
、2.0.0-debug
等。
Index Example
|
|
这说明了此镜像布局提供两个命名引用和一个辅助媒体类型的索引。
第一个命名参考(stable-release
)指向另一个索引,该索引可能包含具有不同平台和注释的多个参考。请注意,org.opencontainers.image.ref.name
注释仅在 index.json
上的描述符上才SHOULD
被视为有效。
第二个命名引用(v1.0
)指向特定于 linux/ppc64le
平台的清单。
OCI Image Manifest Specification(OCI镜像清单规范)
镜像清单规范有三个主要目标。第一个目标是内容可寻址图像,通过支持镜像模型,其中可以对镜像的配置进行哈希处理,从而为镜像及其组件生成唯一 ID。第二个目标是通过“胖清单(fat manifest)”允许多架构图像,该清单引用镜像平台特定版本的镜像清单。在 OCI 中,这被编入了镜像索引中。第三个目标是可以转换为 OCI 运行时规范。
本节定义 application/vnd.oci.image.manifest.v1+json
媒体类型。有关此兼容的媒体类型,请参阅matrix。
Image Manifest
与镜像索引不同,镜像索引包含一组可跨越多种体系结构和操作系统的图像的信息,镜像清单为特定架构和操作系统的单个容器镜像提供了配置和一组层。
Image Manifest Property Descriptions
schemaVersion
int
此REQUIRED
属性指定镜像清单架构版本。对于此版本的规范,此版本MUST
为 2
,以确保与旧版本的 Docker 向后兼容。此字段的值不会改变。此字段可能会在规范的未来版本中被删除。
mediaType
string
SHOULD
使用此属性并与本规范的早期版本以及其他类似的外部格式保持兼容。使用时,此字段MUST
包含媒体类型 application/vnd.oci.image.manifest.v1+json
。此字段用法与 mediaType
的描述符用法不同。
artifactType
string
当清单用于工件时,此OPTIONAL
属性包含工件的类型。当 config.mediaType
设置为空值时,必须设置此项。如果定义,则该值MUST
符合 RFC 6838,包括其第 4.2 节中的命名要求,并且MAY
向 IANA 注册。存储或复制图像清单的实现在遇到实现未知的artifactType
时MUST NOT
出错。
config
descriptor
此REQUIRED
属性通过摘要引用容器的配置对象。除了描述符要求外,该值还有以下额外限制:
mediaType
string