0x00 镜像如何炼成
在深入学习镜像之前我们需要知道镜像是如何(炼制/搓)
成的(等同于构建镜像),当然是通过我们DockerFile一条条指令为镜像生成每一层,按照执行顺序镜像文件系统复写封装从下到上;
1.OCI 标准协议
关于容器镜像的OCI标准协议,那什么又是OCI标准协议?
答: Open Container Initiative(打开集装箱倡议)旨在围绕容器格式和运行时制定一个开放的工业化标准;
参考地址:容器开放接口规范(CRI OCI)
Docker 公司与 CoreOS 和 Google 共同创建了 OCI (Open Container Initial),并提供了三种规范
- 镜像规范 image-spec : 制定镜像格式、操作等 (https://github.com/opencontainers/image-spec)
- 运行时规范 runtime-spec : 描述如何运行filesystem bundle (https://github.com/opencontainers/runtime-spec)
- 镜像仓库规范 distribution-spec (
不常见
)
关于 OCI 规范的作用说明:
- 1.制定容器格式标准的宗旨就提高镜像通用性以便
不限于某种特定操作系统、硬件、CPU架构、公有云
等; 概括来说就是不受上层结构的绑定,如特定的客户端、编排栈
等
- 2.两个协议通过
OCI runtime filesytem bundle
的标准格式连接在一起,OCI 镜像可以通过工具转换成bundle然后OCI容器引擎能够识别这个 bundle 来运行容器, 其优点如下;
- 操作标准化:容器的标准化操作包括使用标准容器创建、启动、停止容器,使用标准文件系统工具复制和创建容器快照,使用标准化网络工具进行下载和上传。
- 内容无关:内容无关指不管针对的具体容器内容是什么,容器标准操作执行后都能产生同样的效果。如容器可以用同样的方式上传、启动,不管是PHP应用还是MySQL数据库服务。
- 基础设施无关:无论是个人的笔记本电脑还是AWS S3,亦或是OpenStack,或者其它基础设施,都应该对支持容器的各项操作。
- 为自动化量身定制:制定容器统一标准,是的操作内容无关化、平台无关化的根本目的之一,就是为了可以使容器操作全平台自动化。
- 工业级交付:制定容器标准一大目标,就是使软件分发可以达到工业级交付成为现实
参考来源:
- 1.OCI 镜像规范的主要由以下几个 markdown 文件组成:
├── 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 | 描述的类型,元数据和引用的内容的内容地址的引用
- 2.OCI 规范是免费的哦,不像大多数 ISO 规范还要交钱才能看(︶^︶)哼。
image-spec - 镜像规范
描述:它决定了我们镜像按照什么标准来构建
,以及构建完镜像之后如何存放
,接着下文提到的 Dockerfile 则决定了镜像的 layer 内容以及镜像的一些元数据信息。
直白的说一个镜像规范 image-spec 和一个 Dockerfile 就指导着我们构建一个镜像;
总结以上几个 markdown 文件 OCI 容器镜像规范主要包括以下几块内容:
# 比较接近我们使用 docker inspect <image|id> 看到的内容
{
"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"]
}
}
//Manifest List
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": &#