首页 > 编程语言 >containerd 源码分析:创建 container(三)

containerd 源码分析:创建 container(三)

时间:2024-06-04 20:11:32浏览次数:19  
标签:container err nil containerd ctx Start 源码 return


文接 containerd 源码分析:创建 container(二)

1.2.2.2 启动 task

上节介绍了创建 task,task 创建之后将返回 response 给 ctr。接着,ctr 调用 task.Start 启动容器。

// containerd/client/task.go
func (t *task) Start(ctx context.Context) error {
	r, err := t.client.TaskService().Start(ctx, &tasks.StartRequest{
		ContainerID: t.id,
	})
	if err != nil {
		...
	}
	t.pid = r.Pid
	return nil
}

// containerd/api/services/tasks/v1/tasks_grpc.pb.go
func (c *tasksClient) Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error) {
	out := new(StartResponse)
	err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Start", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

ctr 调用 contaienrd/containerd.services.tasks.v1.Tasks/Start 接口创建 task。进入 containerd 查看提供该服务的插件:

// containerd/plugins/services/tasks/service.go
func (s *service) Start(ctx context.Context, r *api.StartRequest) (*api.StartResponse, error) {
	return s.local.Start(ctx, r)
}

// containerd/plugins/services/tasks/local.go
func (l *local) Start(ctx context.Context, r *api.StartRequest, _ ...grpc.CallOption) (*api.StartResponse, error) {
	t, err := l.getTask(ctx, r.ContainerID)
	if err != nil {
		return nil, err
	}
	p := runtime.Process(t)
	if r.ExecID != "" {
		if p, err = t.Process(ctx, r.ExecID); err != nil {
			return nil, errdefs.ToGRPC(err)
		}
	}
	// 启动 task: shimTask.Start
	if err := p.Start(ctx); err != nil {
		return nil, errdefs.ToGRPC(err)
	}
	state, err := p.State(ctx)
	if err != nil {
		return nil, errdefs.ToGRPC(err)
	}
	return &api.StartResponse{
		Pid: state.Pid,
	}, nil
}

// containerd/core/runtime/v2/shim.go
func (s *shimTask) Start(ctx context.Context) error {
	_, err := s.task.Start(ctx, &task.StartRequest{
		ID: s.ID(),
	})
	if err != nil {
		return errdefs.FromGRPC(err)
	}
	return nil
}

// containerd/api/runtime/task/v2/shim_ttrpc.pb.go
func (c *taskClient) Start(ctx context.Context, req *StartRequest) (*StartResponse, error) {
	var resp StartResponse
	if err := c.client.Call(ctx, "containerd.task.v2.Task", "Start", req, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

经过 containerd 各个插件的层层调用,最终走到 containerd.task.v2.Task.Start ttrpc 服务。提供 containerd.task.v2.Task.Start 服务的是 containerd-shim-runc-v2

// containerd/cmd/containerd-shim-runc-v2/task/service.go
// Start a process
func (s *service) Start(ctx context.Context, r *taskAPI.StartRequest) (*taskAPI.StartResponse, error) {
	// 根据 task 的 StartRequest 获得 container 的 metadata
	container, err := s.getContainer(r.ID)
	if err != nil {
		return nil, err
	}

	...
	p, err := container.Start(ctx, r)
	if err != nil {
		handleStarted(container, p)
		return nil, errdefs.ToGRPC(err)
	}
	...
}

调用 Container.Start 启动容器进程:

// containerd/cmd/containerd-shim-runc-v2/runc/container.go
// Start a container process
func (c *Container) Start(ctx context.Context, r *task.StartRequest) (process.Process, error) {
	p, err := c.Process(r.ExecID)
	if err != nil {
		return nil, err
	}
	if err := p.Start(ctx); err != nil {
		return p, err
	}
	...
}

Container.Start 调用 Process.Start 启动容器进程。启动容器后 runc init 将退出,将容器的主进程交由 runc init 的父进程 shim:

# ps -ef | grep 138915
root      138915       1  0 15:52 ?        00:00:00 /usr/bin/containerd-shim-runc-v2 -namespace default -id nginx1 -address /run/containerd/containerd.sock
root      138934  138915  0 15:52 ?        00:00:00 nginx: master process nginx -g daemon off;

通过这样的处理,容器进程就和 containerd 没关系了,容器不再受 containerd 的影响,仅和它的 shim 有关系,被 shim 管理,这也是为什么要引入 shim 的原因。

1.3 containerd

从上述 containerd 创建 container 的分析可以看出,containerd 中插件之间的调用是分层的。contianerd 架构如下:

image

containerd 创建 container 的示意图如下:

image

ctr 创建的 container 的交互流程图如下:

image

2. 小结

containerd 源码分析系列文章介绍了 contianerd 是如何创建 container 的,完整了从 kubernetes 到容器创建这一条线。



标签:container,err,nil,containerd,ctx,Start,源码,return
From: https://www.cnblogs.com/xingzheanan/p/18231621

相关文章

  • springboot智慧校园管理系统的设计与实现(文档+源码)
    大家好,我是永钊,一个混迹在java圈的码农,今天要和大家聊的是一款基于springboot的智慧校园管理系统,项目源码请联系永钊,目前有各类成品毕设javawebsshssmspringboot等等项目框架,源码丰富,欢迎咨询。 本网站系统采用了Mysql数据库,Java语言,SpringBoot框架等技术进行编程实......
  • springboot的设计与实现(文档+源码)足球青训俱乐部管理后台系统
    大家好,我是永钊,一个混迹在java圈的码农,今天要和大家聊的是一款基于springboot的足球青训俱乐部管理后台系统,项目源码请联系永钊,目前有各类成品毕设javawebsshssmspringboot等等项目框架,源码丰富,欢迎咨询。 本网站系统重点阐述了足球青训俱乐部管理后台系统的开发过程,......
  • 在线考试|基于Springboot的在线考试管理系统设计与实现(源码+数据库+文档)
    在线考试管理系统目录目录基于Springboot的在线考试管理系统设计与实现一、前言二、系统设计三、系统功能设计 1、前台:2、后台管理员功能四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:博主介绍:✌️大厂码农|毕设布道师,......
  • 健身管理小程序|基于微信开发健身管理小程序的系统设计与实现(源码+数据库+文档)
    健身管理小程序目录基于微信开发健身管理小程序设计与实现一、前言二、系统设计三、系统功能设计 小程序端:后台四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风者计划专......
  • 电影交流|基于SprinBoot+vue的电影交流平台小程序系统(源码+数据库+文档)
     电影交流平台目录目录基于SprinBoot+vue的电影交流平台小程序系统 一、前言 二、系统设计三、系统功能设计 1用户信息管理2电影信息管理3公告信息管理4论坛信息管理四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:......
  • 分享一个Python爬虫入门实例带数据分析(有源码,学习使用)
    Python爬虫是一种使用Python编程语言实现的自动化获取网页数据的技术。它广泛应用于数据采集、数据分析、网络监测等领域。以下是对Python爬虫的详细介绍:架构和组成:下载器:负责根据指定的URL下载网页内容,常用的库有Requests和urllib。解析器:用于解析下载的网页内容,提取所......
  • superAGI核心源码分析
    main.pyimportrequestsfromfastapiimportFastAPI,HTTPException,Depends,Request,status,Queryfromfastapi.middleware.corsimportCORSMiddlewarefromfastapi.responsesimportJSONResponsefromfastapi.responsesimportRedirectResponsefromfastapi_......
  • 基于51单片机的RFID密码锁门禁系统设计资料(源码+原理图等)
    目录1、实物图  2、原理图3、PCB4、器件清单5、设计描述6、源码 7、资料清单资料下载地址:基于51单片机的RFID密码锁门禁系统设计资料(源码+原理图+论文等)​​​​​​​1、实物图  2、原理图3、PCB 4、器件清单5、设计描述 本设计采用STC89C52作......
  • 基于Java+Dijkstra算法的地铁线路换乘最短路径项目(免费提供全部源码)
    下载地址如下:基于Java+Dijkstra算法的地铁线路换乘最短路径项目(免费提供全部源码)资源-CSDN文库项目介绍背景随着城市化进程的不断推进,地铁已成为现代大城市公共交通系统的核心组成部分。地铁线路的日益复杂和站点的不断增加,使得乘客在出行时面临换乘路线选择的困扰。为了提......
  • containerd 源码分析:创建 container(二)
    文接containerd源码分析:创建container(一)1.2.2创建容器进程创建container成功后,接着创建task,task将根据containermetadata创建容器进程。1.2.2.1创建task进入tasks.Newtask创建task://containerd/cmd/ctr/commands/tasks/tasks_unix.gofuncNewTask(ctxg......