早期 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. 对角矩阵try

    \begin{bmatrix}1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1\end{bmatrix}

  2. Linux快速入门(二)Linux基础操作

    绝对路径和相对路径 Linux中绝对路径指从根目录开始,即/目录. 相对路径是指相对于当前路径开始,即./ 目录,../表示上一级目录路径. pwd pwd命令用于查看当前所在目录. gubeiqin ...

  3. 使用Channel传递数据

    上次我们使用了事件异步传递数据,这次我们使用Channel在一个线程通信传递数据 直接上代码 public static class ChannelSample { private static re ...

  4. 记录--vue3 + mark.js | 实现文字标注功能

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 页面效果 具体实现 新增 1.监听鼠标抬起事件,通过window.getSelection()方法获取鼠标用户选择的文本范围或光标的当前位 ...

  5. C# Demo 资源汇总

    1.OCR 相关OCRService Onnx版 https://lw112190.blog.csdn.net/article/details/132082357 OCRService Sdcb.Pa ...

  6. docker部署Prometheus

    1.安装运行Prometheus 下面介绍如何使用Prometheus.Grafana.CAdvisor.node-exporter.mysqld-exporter对本机服务器性能.Docker容器. ...

  7. Flux中的map、flatMap、concatMap的区别

    flatMap.map和concatMap都是在Flux中用于进行数据转换和处理的方法,但它们在处理元素和顺序上有一些区别: map方法: map方法用于对Flux中的每个元素进行一对一的转换. 对于 ...

  8. Docker技术全景:推动云原生架构的关键力量

    本文深入探讨了Docker的发展历程.核心技术.在云服务中的应用以及其庞大生态系统.通过分析Docker如何革新容器化技术.加速云服务的发展,并构建一个多元化的生态系统,本文揭示了Docker在当代云 ...

  9. markdown 常用表情符号 (github emoji)

    markdown 常用表情(emoji) 官网[非笔者维护,仅做引用] Face Smiling 咧嘴笑 grinning 汗颜笑 sweat_smile 爆笑 rofl 眨眼笑 wink innoc ...

  10. C++设计模式 - 职责链模式(Chain of Resposibility)

    数据结构模式 常常有一-些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用.这时候,将这些特定数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无 ...