【containerd 源码分析】containerd image pull 源码分析

2023-05-16

    本文分析 containerd pull 镜像的分析过程,包括 ctr image 命令行以及 containerd daemon 执行 过程,也包含镜像 metadata,content 等内容。

1. 执行如下命令 ctr image pull

    首先分析 ctr 命令,实现在 cmd/ctr 的子命令 listCommand 实现,利用 GRPC 链接到 remote cotainerd 端请求,核心函数 img, err := c.fetch(ctx, fetchCtx, ref, 0)

1.1 fetch 函数

    Resolver.Resolve 向 docker registry 请求 mainifest 文件清单, 本文示例镜像 docker.io/library/nginx:latest, 具体实现就不详细讲解, remotes/docker/resolver.go 中 dockerResolver 结构体实现了 Resolver 接口。

func (c *Client) fetch(ctx context.Context, rCtx *RemoteContext, ref string, limit int) (images.Image, error) {
	store := c.ContentStore()
	name, desc, err := rCtx.Resolver.Resolve(ctx, ref)

   name: 为 docker.io/library/nginx:latest;

   desc 为如下内容, Digest 在 response 的 header 里返回的;

   1.2 dockerResolver 实现 Fetcher 方法

    将镜像进行分析,包括远端 registry 名称, 仓库名称, tag等, 发请求就知道 host 地址

func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetcher, error) {
	base, err := r.resolveDockerBase(ref)
	if err != nil {
		return nil, err
	}

	return dockerFetcher{
		dockerBase: base,
	}, nil
}

   1.3 Dispatch 核心函数

   参数 handler 切片包含多个 handler 函数, descs 镜像的文件清单, 递归把子文件清单也处理了。 接着看几个关键的 handler 函数。

func Dispatch(ctx context.Context, handler Handler, limiter *semaphore.Weighted, descs ...ocispec.Descriptor) error {
	eg, ctx2 := errgroup.WithContext(ctx)
	for _, desc := range descs {
		desc := desc

		eg.Go(func() error {
			desc := desc

			children, err := handler.Handle(ctx2, desc)

			if len(children) > 0 {
				return Dispatch(ctx2, handler, limiter, children...)
			}

			return nil
		})
	}

	return eg.Wait()
}
		handlers := append(rCtx.BaseHandlers,
			remotes.FetchHandler(store, fetcher),
			convertibleHandler,
			childrenHandler,
			appendDistSrcLabelHandler,
		)

2. remotes FetchHandler 

   这里 ingester 是 store 接口, 实现的是 proxyContentStore 结构体, 路径为 content/proxy/content_store.go 文件, 其向 containerd 守护进程发起 GRPC 请求。 接着看 fetch 函数实现。

// FetchHandler returns a handler that will fetch all content into the ingester
// discovered in a call to Dispatch. Use with ChildrenHandler to do a full
// recursive fetch.
func FetchHandler(ingester content.Ingester, fetcher Fetcher) images.HandlerFunc {
	return func(ctx context.Context, desc ocispec.Descriptor) (subdescs []ocispec.Descriptor, err error) {
		switch desc.MediaType {
		default:
			err := fetch(ctx, ingester, fetcher, desc)
			return nil, err
		}
	}
}

   2.1 fetch 函数

    content.OpenWriter 向 containerd 发送 GRPC WriteContentRequest 请求, 包括 ref, total, digest。在看 containerd 处理 WriteContentRequest 请求。 containerd 先写入到 io.containerd.content.v1.content/ingest 下, 最后 commit GRPC WriteContentRequest 请求成功时在移入到 io.containerd.content.v1.content/blobs/sha256 目录下。

    fetcher.Fetch 实现在 remotes/docker/fetcher.go

func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc ocispec.Descriptor) error {
	cw, err := content.OpenWriter(ctx, ingester, content.WithRef(MakeRefKey(ctx, desc)), content.WithDescriptor(desc))

	ws, err := cw.Status()

	rc, err := fetcher.Fetch(ctx, desc)

	return content.Copy(ctx, cw, rc, desc.Size, desc.Digest)
}

总结:

    拉取镜像, 首先获取到 mainifest 文件清单, 在递归将子层下载到 content中, 最后将每一层解压到 snapshotter 下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【containerd 源码分析】containerd image pull 源码分析 的相关文章

  • setImageCompressionQuality 与 setCompressionQuality 之间有什么区别 - Imagick

    我在Imagick中找到了两种设置图像压缩质量的方法 A 设置图像压缩质量 B 设置压缩质量 所以我想知道哪一个是最好的以及为什么在以下条件下 我读到了setCompressionQuality方法仅适用于新图像 我正在尝试压缩文件 jpe
  • 如何将图像显示为缩略图

    我有一个QTreeView显示硬盘驱动器和目录 我也有一个QListView显示图像文件如下 但我想将图像显示为缩略图 如下所示 My code mainWidget mainWidget QWidget parent QWidget pa
  • 在 SQL Server 2005 IMAGE 列中存储 20 Meg 文件的最有效方法

    我们将文档存储在 SQL Server 2005 数据库表中 列格式为 Image 每次我尝试存储大于 1 Meg 的 PDF 文件时 它都会以某种方式损坏 NET 中是否有任何特别有效的方法来序列化大文件 10megs 并将其存储到数据库
  • Matlab 图像数据的 hist 函数

    我是 Matlab 新手 我想制作自己的函数 与 imhist 显示图像数据的直方图 完成相同的工作 但我对此完全是新手 我不知道如何做开发这样的功能 我开始做一些东西 但它非常不完整 function output args myhist
  • 使用 ImageMagick/convert 创建半透明 PNG

    我有 PNG 文件 我想将整个图像转换为半透明 该图像将在 KML 文件中引用为 Google 地球 地图中使用的图标叠加层 使用 ImageMagick 向我建议了以下示例convert命令 但似乎都不起作用 第一个示例会导致错误 usr
  • Javascript - 检测 Youtube 默认缩略图

    有什么方法可以查看 Youtube 缩略图是否真的存在 或者 Youtube 只是用默认缩略图替换了它 例如 没有此缩略图的视频 http img youtube com vi G75WApUdYJ4 maxresdefault jpg h
  • JavaFX 图像未在舞台中显示

    我尝试了很多次 尝试了很多方法 但都无法让自己的形象在舞台上如我所愿 我认为这可能与java寻找资源的路径有关 但我不确定 因为我刚刚开始使用视觉库 在本例中为JavaFX 这是我的目录结构 MyProject assets img myI
  • Java-如何将黑白图像加载到二进制中?

    我在 FSE 模式下使用 Java 和 swing 我想将完全黑白图像加载为二进制格式 最好是二维数组 并将其用于基于掩码的每像素碰撞检测 我什至不知道从哪里开始 过去一个小时我一直在研究 但没有找到任何相关的东西 只需将其读入Buffer
  • 如何垂直对齐div内的图像

    如何在包含的内容中对齐图像div Example 在我的示例中 我需要将 img in the div with class frame div class frame style height 25px img src http jsfi
  • 将图像编码为base64有什么效果?

    如果我将图像 jpg 或 png 转换为 base64 那么它会更大 还是具有相同的大小 会大多少呢 是否建议在我的网站上使用 Base64 编码的图像 大约会大 37 非常粗略地说 Base64 编码的二进制数据的最终大小等于原始数据大小
  • 如何提高包含大量小图像的 UCollectionView 的性能?

    在我的 iOS 应用程序中我有UICollectionView显示大约 1200 个小 35x35 点 图像 图像存储在应用程序包中 我正确地重用了UICollectionViewCell但仍然存在性能问题 具体取决于我处理图像加载的方式
  • 数学/算法使图像适合屏幕保留纵横比

    我需要数学 算法方面的帮助来拍摄已知尺寸的图像并适合两个屏幕尺寸之一 720 x 480 或 1280 x 1024 图像尺寸来自 XML 文件 但这些尺寸是 Web 尺寸 我还从 XML 中选择了一些图像 这些图像的分辨率可能比 Web
  • 下载后从谷歌照片库检索图像

    我正在发起从图库中获取照片的意图 当我在图库中使用 Nexus 谷歌照片应用程序时 一切正常 但如果图像不在手机上 在 Google Photos 在线服务上 它会为我下载 选择图像后 我将图像发送到另一个活动进行裁剪 但在下载的情况下 发
  • 取消html5浏览器中的单图请求

    我正在动态加载 大 图像以绘制到 html5 画布中 如下所示 var t new Image t onload t src http myurl 但每隔一段时间就会想取消图片请求完全地 我想出的唯一方法是设置src to i e t sr
  • 如何以编程方式将多个 JPEG 合并为无损 wav 中的更大 JPEG (.net)

    我有几张 JPEG 图像 我想将它们组合成一张大 JPEG 图像 我可以通过创建一个来做到这一点Bitmap然后将它们组合在一起 但这样如果我再次将其保存为 JPEG 图像将会恶化 那么 有没有什么方法可以在解码 编码时在不损失质量的情况下
  • 我可以在没有 http 处理程序的情况下隐藏 ASP.NET 页面上的图像路径吗?

    我的网站结构中的目录下有许多静态图像 并且我不关心图像的热链接或复制保护 由于多种原因 我需要做的不是在网站上显示图像路径 或显示假路径 有什么方法可以在不求助于 http 处理程序或辅助 asp net 页面的情况下执行此操作吗 你可以使
  • Java中读取图像文件的方式有什么区别?

    在java中读取图像文件有多种方法 例如BufferedImage and ImageIcon仅举几例 我想知道这些情况有什么区别 它们是否依赖于上下文 在特定情况下只能使用其中一个 阅读所选图像的最佳方式是什么JFileChooser由用
  • GNUPLOT:尝试提高质量

    如何提高 gnuplot 的质量 看起来这是一个非常低分辨率的图像 这是我正在使用的文件的内容 linkage plot set terminal pdf set out linkage pdf set title Distribution
  • 考虑到我的图像链接存储在MySQL数据库中,如何通过php显示存储在文件夹中的图像

    作为良好的做法 我只将图像链接存储在数据库中 问题是 我应该如何存储图像的链接 假设它在 c 上 c image jpg 我应该使用哪段 PHP 代码来显示该图像 我只显示路径 我该怎么做才能显示图像 我可以用这个吗 query SELEC
  • 使用 Pillow 和 Numpy 进行图像推导

    I have two images and 我想导出一个只有红色 Hello 的图像 例如 所以我正在运行一个简单的推导python脚本 from PIL import Image import numpy as np root root

随机推荐