文接 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 架构如下:

containerd 创建 container 的示意图如下:

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

2. 小结

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



containerd 源码分析:创建 container(三)的更多相关文章

  1. 手机自动化测试:appium源码分析之bootstrap三

    手机自动化测试:appium源码分析之bootstrap三   研究bootstrap源码,我们可以通过代码的结构,可以看出来appium的扩展思路和实现方式,从中可以添加我们自己要的功能,针对app ...

  2. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

  3. Spring IOC 容器源码分析 - 创建原始 bean 对象

    1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...

  4. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

  5. Netty源码分析之NioEventLoop(三)—NioEventLoop的执行

    前面两篇文章Netty源码分析之NioEventLoop(一)—NioEventLoop的创建与Netty源码分析之NioEventLoop(二)—NioEventLoop的启动中我们对NioEven ...

  6. jQuery-1.9.1源码分析系列(三) Sizzle选择器引擎——词法解析

    jQuery源码9600多行,而Sizzle引擎就独占近2000行,占了1/5.Sizzle引擎.jQuery事件机制.ajax是整个jQuery的核心,也是jQuery技术精华的体现.里面的有些策略 ...

  7. linux中断源码分析 - 中断发生(三)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 回顾 上篇文章linux中断源码分析 - 初始化(二)已经描述了中断描述符表和中断描述符数组的初始化,由于在初始 ...

  8. 【LiteOS】LiteOS任务篇-源码分析-创建任务函数

    目录 前言 链接 参考 笔录草稿 部分源码分析 源码分析 LOS_TaskCreate函数 LOS_TaskCreateOnly函数 宏 OS_TCB_FROM_PENDLIST 和 宏 LOS_DL ...

  9. InnoDB源码分析--缓冲池(三)

    转载请附原文链接:http://www.cnblogs.com/wingsless/p/5582063.html 昨天写到了InnoDB缓冲池的预读:<InnoDB源码分析--缓冲池(二)> ...

  10. springMVC源码分析--SimpleControllerHandlerAdapter(三)

    上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...

随机推荐

  1. 使用OpenMMLab系列的开源库时,常用的脚本合集。

    使用OpenMMLab系列的开源库时,常用的脚本合集. 开源仓库:gy-7/mmlab_scripts 脚本解释: anchor_visiual.py 生成的锚框可视化 aug_test.py 自动数 ...

  2. ESXI 6.5 零基础从安装到批量生成/管理虚拟机简易教程

    制造U盘安装盘 1 先提前下载好,ESXI 6.5 ISO文件. 2 下载制作U盘安装工具,RUFUS. Rufus非常小巧的绿色EXE文件,默认配置选中ISO文件就可以,点击开始,就自动制作,非常方 ...

  3. EMAS移动测试-远程真机篇

    简介: 导读:本文将介绍申请远程真机以及在远程真机上执行测试任务的详细操作,包括申请远程真机.安装应用.扫码.定位.性能测试等. 一.移动测试概览 移动测试服务(Mobile Testing)是为企业 ...

  4. IPv6时代,中小企业该如何布局?

    ​简介:IPv6要为全世界的每一粒沙子都分配一个IP,你的企业跟上了吗? 11月中旬,中央网信办等部门联合印发了<关于开展IPv6技术创新和融合应用试点工作的通知>,联合组织开展IPv6技 ...

  5. 数据智能构建管理平台Dataphin V2.9.4.3版本发布

    简介: Dataphin发布V2.9.4.3版本升级多项产品能力,该版本在产品功能和用户体验上都进行了优化和提升,旨在为用户提供更完善的产品能力和体验,以加速企业数据中台建设进程. -更多关于数智化转 ...

  6. [FAQ] 对于 Puppeteer 和 Chromium 在 Linux 上的安装,需要安装哪些依赖库

      比如 puppeteer/chrome/linux-114.0.5735.133/chrome-linux64/chrome 到底要装哪些依赖. 一般根据报错提示,安装缺少的即可,以下是一般需要的 ...

  7. [MySQL] 原生全文检索 fulltext 的简单应用

    在目标字段上添加全文检索:alter table 表名 add fulltext(字段) with parser ngram 查询语句:select * from xxx where match(字段 ...

  8. 从右边开始寻找整数的第k位

    从右边开始寻找整数的第k位 Implement match_k, which takes in an integer k and returns a function that takes in a ...

  9. 超级好用的 IEC104 主站/客户端模拟器

    目录 超级好用的 IEC104 主站/客户端模拟器 主要功能 软件截图 超级好用的 IEC104 主站/客户端模拟器 官网下载地址:http://www.redisant.cn/iec104clien ...

  10. 不只有 Spring,这四款 Java 基础开发框架同样值得关注! 审核中

    Java 开发不只有 Spring ,今天给大家推荐几个同样优秀的 Java 基础开发框架,为日常项目开发提供更多的选择.答应我,请不要再叫我 Spring 小子了,​好吗? 项目概览: Guice: ...