一 背景

本文针对镜像的本质从文件系统到内部结构,已经相关开发库进行研究,为后期相关定制性操作进行技术预研。

二 镜像本质

1.1 Base镜像

base镜像的两层含义

容器镜像的那点事_容器

  • 不依赖其他镜像,从 scratch 构建。
  • 其他镜像可以之为基础进行扩展。

所以,能称作 base 镜像的通常都是各种 Linux 发行版的 Docker 镜像,比如 Ubuntu, Debian, CentOS 等,​​docker pull centos​​获取一个CentOS的镜像。

  • 内核空间是 kernel,Linux 刚启动时会加载 bootfs 文件系统,之后 bootfs 会被卸载掉。
  • 用户空间的文件系统是 rootfs,包含我们熟悉的 /dev, /proc, /bin 等目录。

对于Docker的 base 镜像来说,底层直接用 Host 的 kernel,自己只需要提供 rootfs 就行了。

而对于一个精简的 OS,rootfs 可以很小,只需要包括最基本的命令、工具和程序库就可以了。

所以,base 镜像提供的是最小安装的 Linux 发行版。

1.2 不同的镜像

不同的Base镜像,区别在于,支持运行不同的 Linux OS,就是其中rootfs不同容器镜像的那点事_容器_02比如 Ubuntu 14.04 使用 upstart 管理服务,apt 管理软件包;而 CentOS 7 使用 systemd 和 yum。这些都是用户空间上的区别,Linux kernel 差别不大

所以 Docker 可以同时支持多种 Linux 镜像,模拟出多种操作系统环境。Debian 和 BusyBox(一种嵌入式 Linux)上层提供各自的 rootfs,底层共用 Docker Host 的 kernel。

查看镜像信息

mkdir /registry
docker run -p 5000:5000 --restart=always --name registry -v /registry/:/var/lib/registry -d registry
[root@img-tools registry]# docker pull centos:latest
[root@img-tools registry]# docker tag centos:latest 127.0.0.1:5000/mycentos:latest
[root@img-tools registry]# docker push 127.0.0.1:5000/mycentos:latest
The push refers to repository [127.0.0.1:5000/mycentos]
2653d992f4ef: Pushed
latest: digest: sha256:dbbacecc49b088458781c16f3775f2a2ec7521079034a7ba499c8b0bb7f86875 size: 529
[root@img-tools registry]# curl -X GET http://127.0.0.1:5000/v2/_catalog -k
{"repositories":["mycentos"]}
// 查看获取到镜像的Digest
[root@img-tools harbor]# curl -I -H "Accept: application/vnd.docker.distribution.manifest.v2+json" localhost:5000/v2/mycentos/manifests/latest
HTTP/1.1 200 OK
Content-Length: 529
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:dbbacecc49b088458781c16f3775f2a2ec7521079034a7ba499c8b0bb7f86875
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:dbbacecc49b088458781c16f3775f2a2ec7521079034a7ba499c8b0bb7f86875"
X-Content-Type-Options: nosniff
Date: Fri, 11 Jun 2021 09:15:55 GMT
// 查看宿主机信息
[root@img-tools ~]# tree /registry/docker/
/registry/docker/
└── registry
└── v2
├── blobs
│ └── sha256
│ ├── 30
│ │ └── 300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55
│ │ └── data
│ ├── 7a
│ │ └── 7a0437f04f83f084b7ed68ad9c4a4947e12fc4e1b006b38129bac89114ec3621
│ │ └── data
│ └── db
│ └── dbbacecc49b088458781c16f3775f2a2ec7521079034a7ba499c8b0bb7f86875
│ └── data
└── repositories
└── mycentos
├── _layers
│ └── sha256
│ ├── 300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55
│ │ └── link
│ └── 7a0437f04f83f084b7ed68ad9c4a4947e12fc4e1b006b38129bac89114ec3621
│ └── link
├── _manifests
│ ├── revisions
│ │ └── sha256
│ │ └── dbbacecc49b088458781c16f3775f2a2ec7521079034a7ba499c8b0bb7f86875
│ │ └── link
│ └── tags
│ └── latest
│ ├── current
│ │ └── link
│ └── index
│ └── sha256
│ └── dbbacecc49b088458781c16f3775f2a2ec7521079034a7ba499c8b0bb7f86875
│ └── link
└── _uploads
27 directories, 8 files
复制代码

三 镜像的唯一性


  • 镜像仓库的功能

对于镜像仓库,其核心功能主要由镜像分发和存储两部分构成。

* 镜像分发:并对外提供一套,[HTTP API V2](https://docs.docker.com/registry/spec/api/)
* 镜像存储:镜像仓库中的所有镜像,都是以数据块 (Blob) 的方式存储在文件系统中。[文件系统](https://docs.docker.com/registry/storage-drivers/#provided-drivers)
复制代码

通过测试,目前知道一下结论。

* 通过 Registry API 获得的两个镜像仓库中相同镜像的 manifest 信息完全相同。
* 两个镜像仓库中相同镜像的 manifest 信息的存储路径和内容完全相同。
* 两个镜像仓库中相同镜像的 blob 信息的存储路径和内容完全相同。
复制代码

  • 镜像的两部分构成:

  • 一个json manifest清单
  • blobs层叠文件组成。

  • 镜像拉去过程

  • pull镜像的过程就是检索这两个组件的过程。拉去镜像的第一步就是获取清单。
  • 当获取清单之后,客户端需要验证前面(signature),以确保名称和fsLayers层是有效的。确认后,客户端可以使用digest去下载各个fs层。在V2 api中,层存储在blobs中已digest作为键值。

  • 具体过程

  • 首先拉取镜像清单(pulling an Image Manifest)


$ HEAD /v2/<image/manifests/<reference>#检查镜像清单是否存在
$ GET /v2/<image>/manifests/<reference>#拉取镜像清单



* 开始拉取每个层(pulling a Layer)复制代码
$ GET /v2/<image>/blobs/<digest>复制代码

digest是镜像每个fsLayer层的唯一标识。存在于清单的fsLayers里面。

四 相关API

Method 方法

Path 路径

Entity 实体

Description 描述

GET 获取

/v2/

Base 基地

Check that the endpoint implements Docker Registry API V2. 检查端点是否实现了 Docker Registry API V2

GET 获取

/v2//tags/list

Tags 标签

Fetch the tags under the repository identified by 获取存储库下的标记name.

GET 获取

/v2//manifests/

Manifest 货物清单

Fetch the manifest identified by 获取由nameand 及referencewhere 在哪里referencecan be a tag or digest. A 可以是标签或摘要HEADrequest can also be issued to this endpoint to obtain resource information without receiving all data. 还可以向此端点发出请求,以便在不接收所有数据的情况下获取资源信息

PUT 放置

/v2//manifests/

Manifest 货物清单

Put the manifest identified by 把清单标识为nameand 及referencewhere 在哪里referencecan be a tag or digest. 可以是标签,也可以是摘要

DELETE 删除

/v2//manifests/

Manifest 货物清单

Delete the manifest identified by 删除由nameand 及reference. Note that a manifest can 。请注意,清单可以only 只be deleted by 被... 删除digest.

GET 获取

/v2//blobs/

Blob 一团

Retrieve the blob from the registry identified by 从标识为的注册表中检索 blobdigest. A 。一HEADrequest can also be issued to this endpoint to obtain resource information without receiving all data. 还可以向此端点发出请求,以便在不接收所有数据的情况下获取资源信息

DELETE 删除

/v2//blobs/

Blob 一团

Delete the blob identified by 删除由nameand 及digest

POST 邮报

/v2//blobs/uploads/

Initiate Blob Upload 启动 Blob 上传

Initiate a resumable blob upload. If successful, an upload location will be provided to complete the upload. Optionally, if the 启动一个可恢复的 blob 上载。如果成功,将提供一个上载位置来完成上载digestparameter is present, the request body will be used to complete the upload in a single request. 参数,则请求主体将用于在单个请求中完成上载

GET 获取

/v2//blobs/uploads/

Blob Upload 上传

Retrieve status of upload identified by 检索标识的上传状态uuid. The primary purpose of this endpoint is to resolve the current status of a resumable upload. 。此端点的主要目的是解决可恢复上载的当前状态

PATCH 补丁

/v2//blobs/uploads/

Blob Upload 上传

Upload a chunk of data for the specified upload. 为指定的上载上传一个数据块

PUT 放置

/v2//blobs/uploads/

Blob Upload 上传

Complete the upload specified by 指定的上载完成uuid, optionally appending the body as the final chunk. ,可以选择将主体附加为最终块

DELETE 删除

/v2//blobs/uploads/

Blob Upload 上传

Cancel outstanding upload processes, releasing associated resources. If this is not called, the unfinished uploads will eventually timeout. 取消未完成的上传进程,释放相关资源。如果未调用,未完成的上传最终将超时

GET 获取

/v2/_catalog

Catalog 目录

Retrieve a sorted, json list of repositories available in the registry. 检索注册中心中可用的存储库的排序的 json 列表

五 其他

  • 核心依赖库
github.com/containers/image/v5/imagegithub.com/containers/image/v5/docker复制代码

了解的镜像底层,可以利用核心库对镜像进行定制性操作等,去满足特定业务需求。

参考链接