整篇文章还没有润色,条理性还不够强,Image Layerd的规范还没来得及写。还只是半成品,先放出来给有兴趣的同学看一下。
从一个比较高层次的角度来看这个规范,主要有以下内容:
Manifest 包括镜像内容的元信息和镜像层的摘要信息,这些镜像层可以解包部署成最后的运行环境。
Configuration 则包含了应用的参数环境。
Index 则从更高的角度描述了Manifest,主要应用于镜像跨平台。
application/vnd.oci.descriptor.v1+json
: Content Descriptor(内容描述文件)application/vnd.oci.layout.header.v1+json
: OCI Layout(布局描述文件)application/vnd.oci.image.index.v1+json
: Image Index(高层次的镜像元信息文件)application/vnd.oci.image.manifest.v1+json
: Image Manifest(镜像元信息文件)application/vnd.oci.image.config.v1+json
: Image Config(镜像配置文件)application/vnd.oci.image.layer.v1.tar
: Image Layer(镜像层文件)application/vnd.oci.image.layer.v1.tar+gzip
: Image Layer(镜像层文件), gzip压缩application/vnd.oci.image.layer.nondistributable.v1.tar
: Image Layer, 非内容寻址管理application/vnd.oci.image.layer.nondistributable.v1.tar+gzip
: Image Layer, gzip压缩,非内容寻址管理当获取块文件时,可以返回文件的Media Type,比如Http请求的返回头中设置Content-Type字段。镜像规范的实现也可能会有预期的Media Type。
mediaType
stringdigest
stringsize
int64urls
array of stringsannotations
string-string mapdata
string 保留字段digest属性是Descriptor的核心,扮演了内容的标识符的角色。digest使用了防碰撞的哈希算法唯一的标识了内容。如果标识符能够以安全的获取。那么就算内容通过了不安全的来源获取,也能独立计算出标识符对内容的正确性进行确认。
digest的格式要求与示例:(sha256已经是一个广泛使用的Hash算法)
digest := algorithm ":" hex
algorithm := /[a-z0-9_+.-]+/
hex := /[a-f0-9]+/
sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b
这个 Content Descriptor 描述了一个Manifest
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 7682,
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
}
镜像布局有以下部分组成:
blobs
directory oci-layout
file imageLayoutVersion
字段index.json
file $ find . -type f
./index.json
./oci-layout
./blobs/sha256/3588d02542238316759cbf24502f4344ffcc8a60c803870022f335d1390c13b4
./blobs/sha256/4b0bc1c4050b03c95ef2a8e36e25feac42fd31283e8c30b3ee5df6b043155d3c
./blobs/sha256/7968321274dc6b6171697c33df7815310468e694ac5be0ec03ff053bb135e768
blobs//
目录。Image Index
$ cat ./blobs/sha256/9b97579de92b1c195b85bb42a11011378ee549b02d7fe9c17bf2a6b35d5cb079 | jq
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 7143,
"digest": "sha256:afff3924849e458c5ef237db5f89539274d5e609db5db935ed3959c90f1f2d51",
"platform": {
"architecture": "ppc64le",
"os": "linux"
}
},
...
Image Manifest
$ cat ./blobs/sha256/afff3924849e458c5ef237db5f89539274d5e609db5db935ed3959c90f1f2d51 | jq
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 32654,
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f"
},
...
Image Config
$ cat ./blobs/sha256/5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270 | jq
{
"architecture": "amd64",
"author": "Alyssa P. Hacker " ,
"config": {
"Hostname": "8dfe43d80430",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": null,
"Image": "sha256:6986ae504bbf843512d680cc959484452034965db15f75ee8bdd1b107f61500b",
...
Image Layer Blob
$ cat ./blobs/sha256/e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f
[tar stream]
在镜像规范中,这个文件特别简单,只有一个布局版本的字段。
{
"imageLayoutVersion": "1.0.0"
}
index.json文件相当于整个镜像的入口。从这个文件可以获取整个镜像依赖到的所有文件的信息。
每一个在manifests
字段中的descriptor
都指向一个 application/vnd.oci.image.index.v1+json 或 application/vnd.oci.image.manifest.v1+json 类型的文件。
一个通用的做法,org.opencontainers.image.ref.name注解被认为是镜像Tag的含义。表示镜像的不同版本。
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.index.v1+json",
"size": 7143,
"digest": "sha256:0228f90e926ba6b96e4f39cf294b2586d38fbb5a1e385c05cd1ee40ea54fe7fd",
"annotations": {
"org.opencontainers.image.ref.name": "stable-release"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 7143,
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
"platform": {
"architecture": "ppc64le",
"os": "linux"
},
"annotations": {
"org.opencontainers.image.ref.name": "v1.0"
}
},
{
"mediaType": "application/xml",
"size": 7143,
"digest": "sha256:b3d63d132d21c3ff4c35a061adf23cf43da8ae054247e32faa95494d904a007e",
"annotations": {
"org.freedesktop.specifications.metainfo.version": "1.0",
"org.freedesktop.specifications.metainfo.type": "AppStream"
}
}
],
"annotations": {
"com.example.index.revision": "r124356"
}
}
官网中列举了Manifest的三大主要目标,但我觉得Manifest的主要任务就只有一个。
通过内容描述的方式,记录一个镜像的元信息,包括Image Config和Image Layers。
2
(为了兼容老版本的Docker)。application/vnd.oci.image.config.v1+json
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
"digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7"
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 32654,
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f"
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 16724,
"digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b"
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 73109,
"digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736"
}
],
"annotations": {
"com.example.key1": "value1",
"com.example.key2": "value2"
}
}
Image Index是一个更高层次的Manifest,一般在一个镜像需要提供多个平台支持时使用。
MediaType:application/vnd.oci.image.index.v1+json
2
(为了兼容老版本的Docker)。application/vnd.oci.image.manifest.v1+json
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 7143,
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
"platform": {
"architecture": "ppc64le",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 7682,
"digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270",
"platform": {
"architecture": "amd64",
"os": "linux",
"os.features": [
"sse4"
]
}
}
],
"annotations": {
"com.example.key1": "value1",
"com.example.key2": "value2"
}
}
对于大部分前文中描述的结构,基本都可以添加Annotations。对于Annotations的使用主要有以下一些内容。
org.opencontainers
前缀的键是OCI规范的,不要随便用。org.opencontainers.image
前缀的键是OCI镜像规范的,不要随便用。org.opencontainers.image.created
镜像构建的日期 (string, RFC 3339).org.opencontainers.image.authors
镜像的负责人或组织 (string)org.opencontainers.image.homepage
镜像相关信息地址 (string, URL)org.opencontainers.image.documentation
镜像帮助文档地址 (string, URL)org.opencontainers.image.source
镜像源代码地址 (string, URL)org.opencontainers.image.ref.name
镜像名称(Tag) (string)为了保证可扩展性。使用该规范的实现,不能因为获取到了一些规范之外的属性,而产生错误或者是异常。