早期 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. 摆脱鼠标系列 - 浏览器操作 - Vimium C 插件 f 显示链接字母 jk上下移动

    为什么 摆脱鼠标系列 - 浏览器操作 - Vimium C 插件 f 显示链接字母 jk上下移动 百度搜索资料的时候,争取少用鼠标 关闭当前页签 x 左边页签 J 右边页签 K 搜索 /关键字回车 n

  2. 安装VMware——Unable to install all modules.See log /tmp/vmware-han/vmware-6098.log for detalls.(Exit code 1)的解决方法(模块加载失败)

    这是编译失败的原因在VM社区有这样一种解决方案,亲测有效,帮助我自己解决的麻烦,所有在这分享,希望能够帮助到小伙伴:不要被接下来的代码吓倒因为这是github上项目,所以要先在ubuntu上安装git ...

  3. GDB调试之多线程

    1.set scheduler-locking off/on/step 调试时除了当前线程在运行,要想规定其他线程的运行情况用这个命令,有三个选择: set scheduler-locking off ...

  4. Windows 环境使用 Xshell 连接 VMware 虚拟机上的 CentOS 系统

    1.VMware 点击虚拟机的设置,打开弹窗,网络使用 NAT 模式 2.VMware 菜单栏:点击 编辑>>>虚拟网络编辑器 (1)选择 VMnet8 (2)选择 NAT 模式 ( ...

  5. 编码ascii码,unicode码,utf-8编码

    1. ASCII ASCII 只有127个字符,表示英文字母的大小写.数字和一些符号,但由于其他语言用ASCII 编码表示字节不够,例如:常用中文需要两个字节,且不能和ASCII冲突,中国定制了GB2 ...

  6. 为什么延迟删除可以保证MYSQL 与redis的一致性?

    看过很多保持MYSQL 与redis保持一致性的文章都提到了延迟删除,其实脱离任何业务场景的设计都是不切实际的,所以我会本着一个通用的读写场景去分析为什么延迟删除大概率可以保证MYSQL与redis的 ...

  7. 记录--vue3实现excel文件预览和打印

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 在前端开发中,有时候一些业务场景中,我们有需求要去实现excel的预览和打印功能,本文在vue3中如何实现Excel文件的预览和打印 ...

  8. 记录--前端换肤方案 - element+less无感换肤(无需页面刷新)

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前端换肤方案 - element+less无感换肤(无需页面刷新) 前言 前不久在改造一个迭代了一年多的项目时,增加了一个换肤功能.通过自 ...

  9. Java对象序列化和反序列化

    Java类的序列化和反序列化 序列化:指将对象转换为字节序列的过程,也就是将对象的信息转换成文件保存. 反序列化:将字节序列转换成目标对象的过程,也就是读取文件,并转换为对象. 几个关键点: 必须实现 ...

  10. 链表栈(LinkedListStack)

      链式栈:就是一种操作受限的单向链表,每次入栈一个元素,向链表中添加一个节点,出栈一个元素,释放一个节点.因为栈具有"后进先出"的特点,如果每次在链表的尾部进行插入和删除,就要遍 ...