在深入学习镜像之前我们需要知道镜像是如何(炼制/搓)
成的(等同于构建镜像),当然是通过我们DockerFile一条条指令为镜像生成每一层,按照执行顺序镜像文件系统复写封装从下到上;
关于容器镜像的OCI标准协议,那什么又是OCI标准协议?
答: Open Container Initiative(打开集装箱倡议)旨在围绕容器格式和运行时制定一个开放的工业化标准;
参考地址:容器开放接口规范(CRI OCI)
Docker 公司与 CoreOS 和 Google 共同创建了 OCI (Open Container Initial),并提供了三种规范
不常见
)关于 OCI 规范的作用说明:
不限于某种特定操作系统、硬件、CPU架构、公有云
等; 概括来说就是不受上层结构的绑定,如特定的客户端、编排栈
等OCI runtime filesytem bundle
的标准格式连接在一起,OCI 镜像可以通过工具转换成bundle然后OCI容器引擎能够识别这个 bundle 来运行容器, 其优点如下;
参考来源:
├── annotations.md # 注解规范
├── config.md # image config 文件规范
├── considerations.md # 注意事项
├── conversion.md # 转换为 OCI 运行时
├── descriptor.md # OCI Content Descriptors 内容描述
├── image-index.md # manifest list 文件
├── image-layout.md # 镜像的布局
├── implementations.md # 使用 OCI 规范的项目
├── layer.md # 镜像层 layer 规范
├── manifest.md # manifest 规范
├── media-types.md # 文件类型
├── README.md # README 文档
├── spec.md # OCI 镜像规范的概览
- Image Manifest - a document describing the components that make up a container image | 描述了构成容器的图像的部件的文档
- Image Index - an annotated index of image manifests | 图像清单的带注释索引
- Image Layout - a filesystem layout representing the contents of an image | 表示图像的内容的文件系统布局
- Filesystem Layer - a changeset that describes a container’s filesystem | 描述一个容器的文件系统中的变更
- Image Configuration - a document determining layer ordering and configuration of the image suitable for translation into a runtime bundle | 文档确定层的排序和适合翻译的图像的配置到运行时的束
- Conversion - a document describing how this translation should occur | 描述应该是如何发生这种转换的文档
- Descriptor - a reference that describes the type, metadata and content address of referenced content | 描述的类型,元数据和引用的内容的内容地址的引用
描述:它决定了我们镜像按照什么标准来构建
,以及构建完镜像之后如何存放
,接着下文提到的 Dockerfile 则决定了镜像的 layer 内容以及镜像的一些元数据信息。
直白的说一个镜像规范 image-spec 和一个 Dockerfile 就指导着我们构建一个镜像;
总结以上几个 markdown 文件 OCI 容器镜像规范主要包括以下几块内容:
Layer : Docker 以 layer (镜像层) 保存的文件系统以及每个Layer保存与上层之间变化部分,以及对保存哪些文件,怎么表示增加、修改和删除的文件等进行描述;
Image-Config : 保存了文件系统的层级信息(每个层级的 hash 值,以及历史信息
)以及容器运行时需要的一些信息(比如环境变量、工作目录、命令参数、mount 列表),指定了镜像在某个特定平台和系统的配置:
# 比较接近我们使用 docker inspect 看到的内容
{
"architecture": "amd64",
"config": {
"Hostname": "",
"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": ["bash"],
"Image": "sha256:ba8f577813c7bdf6b737f638dffbc688aa1df2ff28a826a6c46bae722977b549",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": null
},
"container": "38501d5aa48c080884f4dc6fd4b1b6590ff1607d9e7a12e1cef1d86a3fdc32df",
"container_config": {
"Hostname": "38501d5aa48c",
"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": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"bash\"]"
],
"Image": "sha256:ba8f577813c7bdf6b737f638dffbc688aa1df2ff28a826a6c46bae722977b549",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
}
},
"created": "2020-06-07T01:59:47.348924716Z",
"docker_version": "19.03.5",
"history": [{
"created": "2020-06-07T01:59:46.877600299Z",
"created_by": "/bin/sh -c #(nop) ADD file:a82014afc29e7b364ac95223b22ebafad46cc9318951a85027a49f9ce1a99461 in / "
},{
"created": "2020-06-07T01:59:47.348924716Z",
"created_by": "/bin/sh -c #(nop) CMD [\"bash\"]",
"empty_layer": true
}],
"os": "linux",
"rootfs": {
"type": "layers",
"diff_ids": ["sha256:d1b85e6186f67d9925c622a7a6e66faa447e767f90f65ae47cdc817c629fa956"]
}
}
Layer/Annotation
其文件中保存了很多和当前平台有关信息存放于在 registry 中
。第一个目标是内容可寻址的图像,通过支持的图像模型,其中所述图像的配置可被散列以生成图像和它的组件的唯一ID。
第二个目标是让多架构的图像,通过“mainfest”,这对于图像的特定于平台的版本参考图像清单。在OCI,这是在图像索引编入。
第三个目标是要翻译到OCI运行规范。
registry 中会有个 Manifest List 文件
,该文件是为不同处理器体系架构而设计的,通过该文件指向与该处理器体系架构相对应的 Image Manifest;Docker 会利用 digest 并行下载所有的 Blobs
,其中就包括 Config 和所有的 Layers。//Manifest List
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType":