容器镜像的那点事

举报
kaliarch 发表于 2021/09/24 13:11:45 2021/09/24
【摘要】 一 背景本文针对镜像的本质从文件系统到内部结构,已经相关开发库进行研究,为后期相关定制性操作进行技术预研。 二 镜像本质 1.1 Base镜像base镜像的两层含义不依赖其他镜像,从 scratch 构建。其他镜像可以之为基础进行扩展。所以,能称作 base 镜像的通常都是各种 Linux 发行版的 Docker 镜像,比如 Ubuntu, Debian, CentOS 等,docker ...

一 背景

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

二 镜像本质

1.1 Base镜像

base镜像的两层含义

image.png

  • 不依赖其他镜像,从 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不同

比如 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/<name>/tags/list Tags 标签 Fetch the tags under the repository identified by 获取存储库下的标记name.
GET 获取 /v2/<name>/manifests/<reference> 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/<name>/manifests/<reference> Manifest 货物清单 Put the manifest identified by 把清单标识为nameand 及referencewhere 在哪里referencecan be a tag or digest. 可以是标签,也可以是摘要
DELETE 删除 /v2/<name>/manifests/<reference> Manifest 货物清单 Delete the manifest identified by 删除由nameand 及reference. Note that a manifest can 。请注意,清单可以only 只be deleted by 被… 删除digest.
GET 获取 /v2/<name>/blobs/<digest> 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/<name>/blobs/<digest> Blob 一团 Delete the blob identified by 删除由nameand 及digest
POST 邮报 /v2/<name>/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/<name>/blobs/uploads/<uuid> 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/<name>/blobs/uploads/<uuid> Blob Upload 上传 Upload a chunk of data for the specified upload. 为指定的上载上传一个数据块
PUT 放置 /v2/<name>/blobs/uploads/<uuid> Blob Upload 上传 Complete the upload specified by 指定的上载完成uuid, optionally appending the body as the final chunk. ,可以选择将主体附加为最终块
DELETE 删除 /v2/<name>/blobs/uploads/<uuid> 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/image
github.com/containers/image/v5/docker

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

参考链接

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。