首页 > 编程语言 >浅入浅出docker run命令源码3-containerd续篇

浅入浅出docker run命令源码3-containerd续篇

时间:2024-12-21 11:55:31浏览次数:6  
标签:容器 run shim 浅入 containerd Create 源码 进程 代码

在这里插入图片描述

1.前情回顾

上一篇我们已经知道如何找到对应的gRPC请求接口的逻辑代码了,但是还没有看具体的代码。
在最初的《浅入浅出docker run命令源码》中

在这里插入图片描述

已知,启动容器还需要启动shim进程以及runc进程。但是具体是如何启动的,还不清楚。这篇文章中,主要解决问题是containerd是如何启动shim、runc进程的。

2.前置知识

接着《浅入浅出docker run命令源码》代码腰斩处继续看dockerd的源码,可知,docker run命令执行的过程中,dockerdcontainerd交互时,主要的三个gRPC请求按顺序排列如下:

  • /containerd.services.containers.v1.Containers/Create创建容器的元数据
  • /containerd.services.tasks.v1.Tasks/Create启动shim进程,调用runc创建容器环境
  • /containerd.services.tasks.v1.Tasks/Start 启动任务对应的容器主进程(我们在容器中跑的程序)

很明显我们要关注的是,第2、3个请求。

该篇直接从接口处代码开始,在前面《浅入浅出docker run命令源码2-containerd篇》中已经说明了知道了gRPC请求路径后,如何找到对应的源码,这里不再赘述。

3.Tasks/Create请求源码阅读

在该请求中,containerd会启动一个shim进程,在shim进程中又调用runc去准备好容器启动所需要的namespace环境。

前面有个概念没有说,在containerd中,插件是有类型的,例如servicegRPC插件,localservice插件。在创建gRPC插件的时候,会查找它所依赖的service插件。下面就是负责处理该请求的Tasks插件
在这里插入图片描述

回到正题,该请求是由containerdtasks插件接收请求并处理,正如前面《浅入浅出docker run命令源码2-containerd篇》中说的,service.go中注册的是gRPC插件,负责对外,真正的处理逻辑在其引用的loacl.go中。

local.Create一眼扫过去,大概就能猜到rtime.Create()就是启动shim进程逻辑的代码入口,左下角是到真正启动shim进程时的调用栈
在这里插入图片描述

3.1部分结构体说明

整个调用的过程,其实就是准备各种参数,为启动shim进程准备。刚看这部分的代码,会有种怎么老是在create或者start什么的,如调用栈中方法名所示。其实这里如果了理解TaskManageShimManagerShimTaskshim这些抽象的意义,代码看起来就很清晰了。

3.1.1 TaskManager

taskManager负责所有容器任务的调度和状态管理。它是上层系统(如 Kubernetes 或 Docker)与 containerd 交互的主要入口,是逻辑层面的抽象。

TaskManager只提供了Create、Delete、Get、Tasks这几个方法,对应了容器的创建、删除、查询单个容器、查询所有容器。
在这里插入图片描述

以Create方法为例,代码折叠后,可以看出TaskManager的逻辑就是

  • 1、先让ShimManager搞个shim
  • 2、创建一个task
  • 3、执行task
    没有shim是如何工作的,也没有task是如何工作的逻辑在里面,只负责流程逻辑的串联。只要流程不变,不会影响到TaskManager,我可不管你shim是怎么保存、task是如何实现的。

3.1.2 ShimManager

从前面的TaskManager的实现逻辑来看,ShimManager的定位就是管理容器的。由于containerd为了解耦,通过shim进程来启动容器,而TaskManager又不管事,所以只能搞个 ShimManager来背锅了。ShimManager职责是 shim 进程管理 的抽象层,负责启动、监控和销毁 shim,以及与 shim 之间的通信。

如下图所示,管理shim,其实就是对shim这个抽象对象进行CRUD。其他的小写方法是服务于TaskManager的初始化以及关闭时候清理环境等操作的。
在这里插入图片描述

Start方法为例,可以看到启动前需要先创建一个Bundle对象,然后调用startShim方法返回一个shim对象,最后将shim对象加入到集合中。再看Delete方法中也差不多,具体的实现都是在shim对象中,ShimManager仅仅只是shim对象的维护。
在这里插入图片描述

3.1.3 shimTask与shim

shim记录了shim进程的相关信息,例如runc需要的bundle信息,以及与shim进程通讯用的rpc连接

type shim struct {  
    bundle *Bundle  
    client any  
}

ShimTask是具体任务的实现类,负责单个容器任务的生命周期操作。
在这里插入图片描述

其本质是一个rpc客户端,通过shimclient去完成容器生命周期操作。之所以要弄个shimTask出来,我的理解是containerd中通过shim进程启动容器这逻辑是基本不会变的,因此shim也是基本不变的,其管理功能也是基本不会变的,但容器生命周期操作这些逻辑代码后续可能会变化,为了修改起来更清晰,才搞了shimTask这个东西出来。要是我自己写,可能就直接在shim里面实现草草了事了。。。

shimttrpc通信,ttrpcgRPC为本地通信的优化版本,各个操作对应的请求路径还要再看shimTasktask对象的代码。task是一个 taskClient结构体实例,是ttrpc代码生成的
在这里插入图片描述

3.2 containerd启动shim进程

这里只讲述关于containerd相关的代码,shim进程的代码,请看后续的《浅入浅出docker run命令源码3-shim篇》。

Tasks/Create入口处跟着代码走,会看到下面代码。这里就是真正去启动一个进程的代码位置
在这里插入图片描述

图中的代码是我为了debug shim进程修改过的,会有些细微不一样,但是圈中的代码是没有改动的。

首先cmd.CombineOutput()中会执行启动shim进程的命令并返回了out对象获取命令的输出。
然后parseStartResponse()会处理输出的内容返回下面的结构体

type BootstrapParams struct {  
	Version int `json:"version"`
	Address string `json:"address"`
	Protocol string `json:"protocol"`}

makeConnection()使用结构体中的Address去连接shim进程得到一个ttrpc连接对象
然后返回一个shim对象给shimManger保存起来,然后再返回给TaskManager。

TaskManager得到shim后会创建一个ShimTask,并用ShimTaskshim进程发出请求

shimTask, err := newShimTask(shim)  
if err != nil {  
    return nil, err  
}  
  
t, err := shimTask.Create(ctx, opts)

在shimTask.Create中会通过ttrpc,让shim进程去干活了
在这里插入图片描述

请求的路径如下,执行服务containerd.task.v2.TaskCreate方法
在这里插入图片描述

该请求就是让shim进程去启动runc进程,剩下的逻辑,需要关注的在shim进程的代码里面了。

4.Tasks/Start请求源码阅读

Start方法中,其实就是获取Create方法中创建的shimTask,然后调用它的start方法,最终触发ttrpc请求,让shim进程启动容器,最终返回启动结果给dockerd,涉及的知识点已经在Create方法中写了,这里就不再赘述了。
在这里插入图片描述

在这里插入图片描述

5.总结

本来想叫shim篇的,结果发现要把shim进程的逻辑也放这写,感觉还得费不少时间,还是拆开写吧。擦,本来我只是想随便看看docker run的代码,意思一下得了,怎么给我干到这来了。。

标签:容器,run,shim,浅入,containerd,Create,源码,进程,代码
From: https://blog.csdn.net/wy53111/article/details/144589533

相关文章

  • 免费送源码:Java+B/S+MySQL springboot电影推荐系统 计算机毕业设计原创定制
             摘 要随着互联网与移动互联网迅速普及,网络上的电影娱乐信息数量相当庞大,人们对获取感兴趣的电影娱乐信息的需求越来越大,个性化的电影推荐系统成为一个热门。然而电影信息的表示相当复杂,己有的相似度计算方法与推荐算法都各有优势,导致单一的相似度计算方......
  • ssm毕设青少年编程课程教学评价源码+程序+论文
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容选题背景随着信息技术的迅猛发展,编程教育在青少年群体中的普及率日益提高,成为培养其创新思维和解决问题能力的重要途径。关于青少年编程课程的教学评价,现有研......
  • ssm毕设青少年公共卫生教育平台源码+程序+论文
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容选题背景青少年公共卫生教育作为提升全民健康素养的关键环节,近年来在国内外受到了广泛关注。现有研究主要集中在公共卫生教育的内容设计、教学方法以及效果评......
  • 同城上门喂遛宠物系统(源码+数据库+报告)
    357.基于SpringBoot的同城上门喂遛宠物系统,系统包含两种角色:管理员、用户,系统分为前台和后台两大模块二、项目技术编程语言:Java数据库:MySQL项目管理工具:Maven前端技术:Vue后端技术:SpringBoot三、运行环境操作系统:Windows、macOS都可以JDK版本:JDK1.8以上都可以开发工......
  • java ssm基于Android流动人口管理系统uniapp出租屋户籍迁移(源码+文档+运行视频+讲解视
     文章目录系列文章目录前言一、开发介绍二、详细视频演示三、项目部分实现截图四、uniapp介绍五、系统测试六、代码参考源码获取目的摘要:基于JavaSSM和Android的流动人口管理系统为城市管理提供了有效的工具。该系统借助UniApp实现多平台访问,涵盖了出租屋管......
  • java ssm基于Android旅游信息查询系统uniapp旅游景点(源码+文档+运行视频+讲解视频)
     文章目录系列文章目录前言一、开发介绍二、详细视频演示三、项目部分实现截图四、uniapp介绍五、系统测试六、代码参考源码获取目的摘要:基于JavaSSM和Android的旅游信息查询系统为游客提供了便捷的旅游信息查询服务。该系统通过UniApp实现多平台应用,涵盖了......
  • 免费送源码:Java+ssm+MySQL springboot 商铺租赁管理系统 计算机毕业设计原创定制
    摘要本论文主要论述了如何使用springboot商铺租赁管理系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构JAVA技术,面向对象编程思想进行项目开发。在引言中,作者将论述商铺租赁管理系统的当前背景以及系统开发的目的,后续章节将严格按照软件开发流程,对系统......
  • php毕业设计宠物商城php的宠物购物商城的设计与实现php毕业设计课程设计在线购物商城
     一,功能介绍        前台主要包括网站首页、商品推荐、最新商品、新闻咨询、商品分类、商品资讯、评论、登录、注册、加入购物车、结算、个人中心等功能模块商品推荐、最新商品在商品推荐、最新商品模块,用户可以查看全部商品信息,选择商品进行添加购物车等操作,购......
  • 一对一视频聊天源码,Java实现跨域方式
    一对一视频聊天源码,Java实现跨域方式一、返回新的CorsFilter(全局跨域)packageorg.chuancey.config;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.cors.Cors......
  • 基于SpringBoot+Vue的林业产品推荐管理系统设计与实现毕设(文档+源码)
    目录一、项目介绍二、开发环境三、功能介绍四、核心代码五、效果图六、源码获取:         大家好呀,我是一个混迹在java圈的码农。今天要和大家分享的是一款基于SpringBoot+Vue的林业产品推荐管理系统,项目源码请点击文章末尾联系我哦~目前有各类成品毕设JavaW......