8.Docker容器镜像仓库存储原理(前世今身)与搬运技巧

文章目录

        • 0x00 镜像如何炼成
          • 1.OCI 标准协议
            • image-spec - 镜像规范
            • runtime-spec 运行时规范
            • distribution-spec 镜像仓库规范
          • 2.Dockerfile
          • 3.基础镜像
        • 0x01 镜像存储原理
          • 本地存储 - Local
          • 镜像仓库 - Registry
        • 0x02 镜像搬运
          • pull - 镜像拉取
          • push - 推送镜像
          • Python Docker-dray
          • skopeo - 镜像搬运神器
        • 0x03 镜像使用

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 容器镜像规范主要包括以下几块内容:

  • 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"]
  }
}
  • manifest : 镜像的config文件索引包括了Layer/Annotation其文件中保存了很多和当前平台有关信息存放于在 registry 中
    您可以在镜像仓库中通过Registry API请求获取镜像Manifest中的信息, 当我们拉取镜像的时候会根据该文件拉取相应的 layer,比如后面实现的不解压镜像拷贝;
    • 镜像的 manifest 文件(图像清单规范)主要有以下三个目标:
    第一个目标是内容可寻址的图像,通过支持的图像模型,其中所述图像的配置可被散列以生成图像和它的组件的唯一ID。
    第二个目标是让多架构的图像,通过“mainfest”,这对于图像的特定于平台的版本参考图像清单。在OCI,这是在图像索引编入。
    第三个目标是要翻译到OCI运行规范。
    
    • 版本: 目前主流的版本是 Manifest Version 2, Schema 2 官方参考说明
    • 注意: manifest 中的 layer 和 config 中的 layer 表达的虽然都是镜像的 layer ,但二者代表的意义不太一样;
    • 注意: registry 中会有个 Manifest List 文件,该文件是为不同处理器体系架构而设计的,通过该文件指向与该处理器体系架构相对应的 Image Manifest;
    • 总结: 容器镜像的 Config,和 Layers 中的每一层,都是以 Blob 的方式存储在镜像仓库中的,它们的 digest 作为 Key 存在。因此在请求到镜像的 Manifest 后,Docker 会利用 digest 并行下载所有的 Blobs,其中就包括 Config 和所有的 Layers。
//Manifest List
{
   
  "schemaVersion": 2,
  "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
  "manifests": [
    {
   
      "mediaType": &#

你可能感兴趣的:(全栈之云原生学习,linux,docker,运维)