最小化容器操作系统——containerd、runc

一、前言

**containerd 被设计成嵌入到一个更大的系统中,而不是直接由开发人员或终端用户使用。**当 containerd 和 runC 成为标准化容器服务的基石后,上层的应用就可以直接建立在 containerd 和 runC 之上。我们的目的就是开发一个最小化容器系统,这需要containerd和runC的支持,使得Linux kernel在启动的时候,首先启动containerd而非init,并在容器中包含系统必要组件,如shell。

二、简介

containerd 是一个容器运行时组件,它原本是 Docker 平台的一部分,虽然小巧,但在整个系统里起到很关键的作用。Containerd 被设计成一种低耦合并且很容易与其它工具集成的组件。

containerd 提供了一组运行容器的 API。Docker 引擎通过调用 GRPC API 来启动执行进程,随后会启动管理器和执行器来负责监控和运行容器。容器最后通过runC来运行,runC 也是 Docker的另一个开源项目,它实现了 OCI 运行时标准。(OCI:开放容器协议,OCI开发了runC)。runC 是一套符合OCI标准的容器引擎;其是一个非常独立,真正创建容器的组件,runC可以独立于dockerd创建、操作容器。

containerd独立负责容器运行时和生命周期(如创建、启动、停止、中止、信号处理、删除等)containerd 只是一个守护进程,容器的实际运行时由 runC 控制。containerd 主要职责是镜像管理(镜像、元信息等)、容器执行(调用最终运行时组件执行)。containerd-shim 调用runc启动容器,监控容器进程状态,回收容器中的相关进程等

Docker 如何运行一个容器?

  1. Docker 引擎创建容器映像
  2. 将容器映像传递给 containerd
  3. containerd 调用 containerd-shim
  4. containerd-shim 使用 runC 来运行容器
  5. containerd-shim 允许runC在启动容器后退出

docker结构

  • dockerd是docker engine守护进程,dockerd启动时会启动containerd子进程,dockerd与containerd通过rpc进行通信
  • ctr是containerd的cli
  • containerd通过shim操作runc,runc真正控制容器生命周期,启动一个容器就会启动一个shim进程
  • shim直接调用runc的包函数,shim与containerd之前通过rpc通信
  • 真正用户想启动的进程由runc的init进程启动,即runc init [args ...]
docker        ctr
 |             |
 V             V
 dockerd -> containerd ---> shim -> runc -> runc init -> process
                      |-- > shim -> runc -> runc init -> process
                      +-- > shim -> runc -> runc init -> process

三、组件通信分析

通信

通信流程:

  1. docker daemon 模块通过 grpc 和 containerd模块通信:dockerd 由libcontainerd负责和containerd模块进行交换, dockerd 和 containerd 通信socket文件:docker-containerd.sock

  2. containerd 在dockerd 启动时被启动,启动时,启动grpc请求监听。containerd处理grpc请求,根据请求做相应动作;

  3. 若是start或是exec 容器,containerd 拉起一个container-shim , 并通过exit 、control 文件(每个容器独有)通信;

  4. container-shim被拉起后,start/exec/create拉起runC进程,通过exit、control文件和containerd通信,通过父子进程关系和SIGCHLD监控容器中进程状态;

  5. 若是top等命令,containerd通过runC二级制组件直接和容器交换;

  6. 在整个容器生命周期中,containerd通过epoll 监控容器文件,监控容器的OOM等事件;

四、containerd 组件分析

containerd的主要功能:

  1. 和docker 的libcontainerd通信 —> gRPC
  2. 和container-shim 、runC进行通信 —> 进程返回或epoll系统调用方式
  3. 简单的调度和任务分发

containerd 关键组成部分:

├── api         //gRPC 事件处理
├── containerd  //containerd 命令处理 ---> main 主函数
├── runtime     //以容器为单位,处理状态、事件
├── supervisor  //以整体为单位,处理、转发状态、事件

五、容器进程分析

linux 容器创建的基本流程是runc-create进程中先构建一个linuxFactory,然后根据该Factory的配置创建LinuxContainer, 解析来创建Container的process信息,在开始处理该process–即在runc-create进程中fork出一个进程–runc-init,然后由runc-create将runc-init的cgroup信息进行设置并发送给runc-init进程,该runc-init进程就是linux Container的1号进程。而container 本身只是一个逻辑概念——一组Cgroup限制下的进程的组合体。

参考:runC简介containerd简介docker组件通信机制分析

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值