早期 kubelet 创建容器工作原理

因为 docker 出生的比 k8s 早,所以 k8s 早期的容器运行时都是基于 docker 的,kubelet 通过 docker 的 api 创建容器。后来,k8s 官方不想绑死在 docker 这架马车上,就把容器运行时抽象出来,定义了一个接口,叫 CRI (container runtime interface),容器运行时接口, 通过这个接口,kubelet 可以和任何容器运行时交互。但是,docker 并没有实现这个接口,k8s 也不想直接失去 docker 的用户,所以 k8s 官方在 kubelet 中实现了一个叫 docker-shim 的组件,这个组件简单来说就是把 cri 接口转换成 docker 的 api,这样 kubelet 就可以和 docker 交互了, 这个组件在 kuberbetes 1.24 版本中已经被移除了。至于实现了 cri 接口的容器运行时,比如 containerd,cri-o 等,kubelet 可以直接和它们交互。

调用架构图如下:

目前 dockershim 组件已经删除,不能使用了,所以 k8s 1.24 版本之后,kubelet 只能和实现了 cri 接口的容器运行时交互,比如 containerd,cri-o 等。

这里建议使用 containerd 因为 containerd 是 docker 官方出品的,而且 containerd 也是 docker 的核心组件,docker 的容器运行时就是基于 containerd 的,所以 containerd 的稳定性和可靠性都是有保障的。

docker containerd runc 的关系

因为 podman 等新兴 container runtime 的崛起,docker 不想失去定义标准的机会,所以 docker 官方把 containerd 从 docker 中分离出来,独立成一个项目,实现了 cri 接口,这种 kubelet 就可以通过 cri 直接调用 containerd 了。然后,docker 官方又把 runc 从 containerd 中分离出来,独立成一个项目,定义了一个叫 OCI (Open Container Initiative) 的标准,这个标准定义了容器的格式和运行时,runc 就是这个标准的实现,目前实现 oci 的还有 crun youki keta 等。

因为 containerd 和 runc 脱胎于 docker,docker 又不能维护两份代码,所以 docker 就通过调用 containerd ,containerd 再 通过配置实现 oci 标准的 runc 来创建容器。 当然,你也可以手动配置其他实现了 oci 标准的容器运行时。

调用架构图如下:

在上图中可以看到 containerd 不是直接调用 runc 的,而是通过 containerd-shim 来调用 runc 的,这个是为什么?

runc

runc 是一款设计精巧的命令行工具,专注于创建和运行符合 Open Container Initiative(OCI)规范的容器。执行 runc start 时,它首先通过 fork 创建一个子进程,在这个新进程中进行一系列容器运行的准备工作,包括准备文件系统、配置 namespaces 和 cgroups 。接着,通过 execve 系统调用,这个子进程变身为容器的首个进程——通常被称作“init”进程——并执行用户指定的首个命令(例如,bash)。

如果首个命令是一个shell(比如 bash),当执行一个shell命令(例如 ls)时,bash 会 fork 并执行相应的子进程。这个新的子进程执行 ls 命令并在完成任务后退出。此后,bash 可能继续接受新的命令,或在结束会话后终止。

当容器的“init”进程终止时,整个容器也会按照规定的生命周期走向结束。不同的命令和应用会在这个基本框架下有不同的具体行为,但总体流程大致一致。

如果这些容器的进的父进程是 containerd ,那么当 containerd 进程挂掉或者重启时,容器的进程也会挂掉,这样就不符合容器的定义了,所以 containerd 通过 containerd-shim 来调用 runc,这样当 containerd 挂掉时,容器的进程还是会继续运行的。

containerd-shim

containerd-shim 是一个轻量级的代理进程,它的主要作用是:

  1. 通过runC命令可以启动、执行容器、进程;
  2. 监控容器进程状态,当容器执行完成后,通过exit fifo文件报告容器进程结束状态;
  3. 当此容器SHIM的第一个实例进程被杀死后,reaper掉所有其子进程;

当 containerd 通过 containerd-shim 来调用 runc 后, 会把 containerd-shim 的挂到 system (pid=1)的进程下,这样当 containerd 挂掉或者重启时,containerd-shim 还是会继续运行的,这样就保证了容器的进程不会挂掉。

验证,这里我随便启动了一下 docker 容器看下效果:

# 启动的nginx 容器
root 19455 19435 0 22:20 ? 00:00:00 nginx: master process nginx -g daemon off;
# nginx 进程的父进程是 containerd-shim
root 19435 1 0 22:20 ? 00:00:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 0af95b326dfc8fee31bd28abb61e5d23a9cee98fada2b32c5ade852a0782f559 -address /run/containerd/containerd.sock
# containerd-shim 的父进程是 systemd

docker containerd runc containerd-shim等组件的关系的更多相关文章

  1. 关于docker创建容器报错-docker: Error response from daemon: runtime "io.containerd.runc.v2" binary not installed

    今天在对一台服务器(docker相关的业务服务器)进行OS补丁时,默认使用的 yum update -y 对所有的安装包进行了升级 升级完成后,让应用方检查确认应用及功能是否一切正常,如果不正常,严重 ...

  2. Kubernetes将弃用Docker!与 containerd容器引擎

    时间戳:2022-06-07 20:32:19 星期二 撰写文档参考:(阿良-腾讯课堂)Kubernetes将弃用Docker 参考博客k8s入坑之路(3)containerd容器 container ...

  3. Centos下使用containerd管理容器:5分钟从docker转型到containerd

    目录 一.系统环境 二.前言 三.containerd 四.部署containerd 4.1 安装containerd 4.2 containerd配置文件 4.3 配置containerd阿里云镜像 ...

  4. 泛型编程、STL的概念、STL模板思想及其六大组件的关系,以及泛型编程(GP)、STL、面向对象编程(OOP)、C++之间的关系

    2013-08-11 10:46:39 介绍STL模板的书,有两本比较经典: 一本是<Generic Programming and the STL>,中文翻译为<泛型编程与STL& ...

  5. 在Visual Studio中使用组件图描述项目组件依赖关系

    如果想描述项目组件的关系,可以考虑使用UML组建图. 在建模项目下添加一个名称为"Applicaiton Component Structure"的UML组建图. 添加各个组件,并 ...

  6. 线程、进程概念与Android系统组件的关系

    Android系统是Google公司基于Linux内核开发的开源手机操作系统.通过利用 Linux 内核的优势,Android 系统使用了大量操作系统服务,包括进程管理.内存管理.网络堆栈.驱动程序. ...

  7. Vue_(组件通讯)父子组件简单关系

    Vue组件 传送门 在Vue的组件内也可以定义组件,这种关系成为父子组件的关系 如果在一个Vue实例中定义了component-a,然后在component-a中定义了component-b,那他们的 ...

  8. Spring Boot版本,Spring Cloud版本与组件版本关系

    我们在学习Spring Cloud时,可能总是碰到以下问题: 1.Spring Boot版本与Spring Cloud版本关系 2.启动时,报莫名其妙的错,稀里糊涂的换个版本就好了 3.这么多版本,用 ...

  9. 从 docker 到 runC

    笔者在前文<RunC 简介>和<Containerd 简介>中分别介绍了 runC 和 containerd.本文我们将结合 docker 中的其它组件探索 docker 是如 ...

  10. docker是PaaS,与openstack是IaaS的关系

    个人理解Docker的每一个虚机其实是宿主操作系统中的一个进程.主要是一种虚拟化技术.OpenStack主要解决的是基础架构云的云服务问题.OpenStack是在虚拟化技术之上的一层,主要解决系统部署 ...

随机推荐

  1. 基于STM32F407MAC与DP83848实现以太网通讯四(STM32F407MAC数据收发与DMA描述符)

    上一章实现的MAC数据包的基础收发功能,但是只是简单的操作了ETH外设的收发包函数并没有深入了解其中的原理逻辑,本章结合STM32F40x文档与STM32F4x7_ETH_Driver驱动库了解MAC ...

  2. immutable 不可改变的 mut ≈ to move = to change - 单词学习

    immutable im-不,非 + mut-改变 + -able. im 通 in able 有能力的 重点是 mut 的含义是 to change t 就是to mu 就是 change (*拉丁 ...

  3. 基于 XAF Blazor 的规则引擎编辑器 - 实战篇

    示例项目:https://gitee.com/easyxaf/recharge-rules-engine-sample 前言 继上一篇文章对规则引擎编辑器进行了初步介绍之后,本文将通过实际应用案例深入 ...

  4. springboot增加slf4j

    参考:https://blog.csdn.net/qq_27706119/article/details/104977666(主要) https://www.liaoxuefeng.com/wiki/ ...

  5. Java递归实现全排列改进(一)---利用HashSet实现去重

    import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iter ...

  6. 移远EC20 4G模块Linux驱动移植和测试

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  7. Java课堂

    import java.awt.*; import java.awt.event.*; import java.util.*; public class Main{ public static dou ...

  8. 从null-ls归档再看nvim的代码格式化与lint方案

    由于null-lsp的归档和暂停更新,我们需要重新审视并思考还有哪些架构简单易于理解的插件配置方案.本文将介绍脱离null-ls插件体系下的代码格式化和lint的插件配置方案. 在之前的文章中< ...

  9. 引领文旅新体验!3DCAT实时云渲染助力打造“永不落幕”的湾区文采会元宇宙

    2022年11月25日至27日,2022年粤港澳大湾区公共文化和旅游产品(东莞)采购会(简称"湾区文采会")在广东省东莞市文化馆举行. 文采会期间,文采会元宇宙线上虚拟展厅全新亮相 ...

  10. Docker部署之使用docker-compose部署(全新的干净的服务器,从0开始搭建)

    部署环境准备 安装yum # 安装yum工具 yum install -y yum-utils device-mapper-persistent-data lvm2 --skip-broken 安装d ...