云原生Kubernetes:CRI 容器运行时接口

这篇具有很好参考价值的文章主要介绍了云原生Kubernetes:CRI 容器运行时接口。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、理论

1.​CRI

2.容器运行时层级

3.容器运行时比较

二、总结


一、理论

1.​CRI

(1)概念

      Kubernetes Node (kubelet) 的主要功能就是启动和停止容器的组件,我们 称之为容器运行时( Container Runtime) ,其中最知名的就是 Docker 。为了 更具扩展性, Kubernetes 1.5 版本开始就加入了容器运行时插件 API, Container Runtime Interface, 简称 CRI。
每个容器运行时都有特点,因此不少用户希望 Kubernetes 能够支持更多的容器运行时。Kubernetes从 1.5 版本开始引入了 CRI 接口规范,通过插件接口模式,Kubernetes 无须重新编译就可以使用更多的容器运行时。

(2)主要组件

      CRI 包含的组件有 Protocol Buffers、gRPC API、运行库支持及开发中的标准规范和工具。

Docker 的 CRI 实现在 Kubernetes1.6 中被更新为 Beta 版本,并在 kubelet启动时默认启动。

  CRI组件(cubelet)主要实现的功能 :

1)镜像管理:镜像拉取、查看和移除
2)pod和容器的生命周期管理,以及与容器的交互(exec/attach/port-forward)

   kubelet 使用 gRPC 框架通过 UNIX Socket 与容器运行时 (或 RI 代理 )进行通信。在 这个过程中 kubelet 是客户端, CRI 代理 (shim) 是服务端,如图 所示:

云原生Kubernetes:CRI 容器运行时接口,云原生,kubernetes,容器

Protocol Buffers API包含两个gRPC服务:ImageService和 RuntimeServiceoImageService提供了从仓库中拉取镜像、查看和移除镜像的功能。

1.镜像管理:镜像拉取、查看和移除
2.pod和容器的生命周期管理,以及与容器的交互(exec/attach/port-forward)

ImageService提供了从仓库中拉取镜像、查看和移除镜像的功能。

RuntimeService负责Pod和容器的生命周期管理,以及与容器的交互( exec/attach/port-forward )。rkt 和 Docker这样的容器运行时可以使用一个Socket同时提供两个服务,在kubelet中可以用--container-runtime-endpoint和--image-service-endpoint参数设置这个Socket。

(3)Pod 和容器的生命周期管理

Pod 由一组应用容器组成,其中包含共有的环境和资源约束,在 CRI 里,这个环境被称为 PodSandbox。

Kubernetes有意为容器运行时留下一些发挥空间,它们可以根据自己的内部实现来解释 PodSandbox。

对于 Hypervisor 类的运行时,PodSandbox 会具体化为一个虚拟机。
其他例如 Docker,会是一个 Linux 命名空间。在 vialpha1 API 中,kubelet 会创建 Pod 级别的 cgroup 传递给容器运行时,并以此运行所有进程来满足 PodSandbox对 Pod 的资源保障。
在启动 Pod 之前,kubelet调用 RuntimeService RunPodSandbox来创建环境。这一过程包括为 Pod 设置网络资源(分配IP等操作)。PodSandbox 被激活之后,就可以独立地创建、启动、停止和删除不同的容器了。kubelet 会在停止和删除 PodSandbox 之前首先停止和删除其中的容器。

kubelet 的职责在于通过 RPC 管理容器的生命周期,实现容器生命周期的钩子、存活和健康监测,以及执行 Pod 的重启策略等。

(4)面向容器级别的设计思路

     CRI 机制能够发挥作用的核心,在于每一个容器项目现在都可以自己实现一个 CRI shim ,自行对 CRI 请求进行处理.这样, Kubernetes 就有了一个统一的容器抽象层,使得下层容器在运行的时候,可以自由地对接,从而进入 Kubernetes 当中去。

从kubernetes 架构图来分析CRI如何工作:

云原生Kubernetes:CRI 容器运行时接口,云原生,kubernetes,容器

作为一个 CRI shim , container 对 CRI 的具体实现, CRI 接口的定义如下:

云原生Kubernetes:CRI 容器运行时接口,云原生,kubernetes,容器

CRI 待实现接口,主要有两类::

RuntimeService .它提供的接口,主要就是和容器有关的操作.比如,创建和启动容器,删除容器,执行 exec 命令等.
ImageService .它提供的接口,主要是和容器镜像相关的操作,比如 拉取镜像,删除镜像等等.

 CRI 设计的一个重要原则,就是确保这个接口本身,只关注容器,不关注 Pod(与pod相关的是SandBox(沙箱)相关API,沙箱即容器本身,是容器而非pod的API,之所以叫PodSandbox是因为创建的沙箱(容器)用于部署pod ).之所以这样涉及,原因有两个:

第一, Pod 是 Kubernetes 的编排概念,而不是容器运行时的概念,所以就不能假设所有的下层容器项目,都能够暴露出可以直接映射为 Pod 的 API .
第二,如果 CRI 里面引入了 Pod 的概念,那么只要 Pod API 对象的字段发生变化,那么 CRI 就很有可能需要变更。

基于以上原因, CRI 设计中,并没有一个直接创建 Pod 或者启动 Pod 的接口.

(5)Streaming API实现exec、log等功能

CRI shim 还有一个重要的工作,就是如何实现 exec , logs 等接口.这些接口不同在于, gRPC 接口调用期间, kubelet 需要和容器项目维护一个长连接来传输数据.这种 API ,就称之为 Streaming API 。

CRI shim 中对 Streaming API 的实现,依赖于一套独立的 Streaming Server 机制,如下:

云原生Kubernetes:CRI 容器运行时接口,云原生,kubernetes,容器

       当对一个容器执行 kubectl exec 命令时,这个请求首先会交给 API Server , 然后 API Server 就会调用 kubelet 的 Exec API .此时, kubelet 会调用 CRI 的 Exec 接口,而负责响应这个接口的,就是 CRI shim .但是在这一步, CRI shim 并不会直接去调用后端的容器项目(比如 Docker )来进行处理,而只会返回一个 URL 给 kubelet .这个 URL ,就是该 CRI shim 对应的 Streaming Server 的地址和端口。 kubelet 在拿到这个 URL 之后,就会把它以 Redirect 的方式返回给 API Server .所以这个时候, API Server 就会通过重定向来向 Streaming Server 发起真正的 /exec 请求,和它建立长连接.
Stream Server 这一部分具体怎么实现,完全可以由 CRI shim 的维护者自行决定。
       所以, CRI 这个接口的设计,实际上还是比较宽松的.这就意味着,作为容器项目的维护者,在实现 CRI 的具体接口时,往往拥有着很高的自由度,这个自由度不仅包括了容器的生命周期管理,也包括了如何将 Pod 映射成自己的实现,还包括了如何调用 CNI 插件来为 Pod 设置网络的过程。
        基于此,当维护者对容器这一层有特殊的需求时,优先建议考虑实现一个自己的 CRI shim 。

2.容器运行时层级

Container Runtime 分为高低两个层级。

(1)  高层级运行时
Dockershim、containerd 和 CRI-O 都是遵循 CRI 的容器运行时,属于高层级运行时,主要是面向外部提供 gRPC 调用。

注意这里是 Dockershim,并不是 Docker,Docker 至今也没有遵循 CRI。

OCI
OCI(OPen Container Initiative)定义了创建容器的格式和运行时的开源行业标准,包括镜像规范和运行时规范。

高层级运行时会下载一个 OCI 镜像,并把它解压成 OCI 运行时文件系统包(filesystem bundle)。

(2)低层级运行时
低层级运行时定义如何为新容器设置 Linux namespaces 和 cgroups,以及 rootfs 等操作, runC 就是具体的参考实现。除了 runC 外,还有很多其他的运行时遵循 OCI 标准,例如 kata 以及 gVisor。

3.容器运行时比较

Docker 的多层封装和调用,导致其在可维护性上略逊一筹。containerd 和 CRI-O 的方案比 Docker 简洁很多。
云原生Kubernetes:CRI 容器运行时接口,云原生,kubernetes,容器

dockershim 遵循 CRI,并把请求转为 dockerd 可处理的请求,其代码集成在 kubelet 中,这也是 k8s 急于摆脱 Docker 的原因之一。

真正的启动容器是通过 containerd-shim 去调用 runC 来启动容器的,runC 启动完成后会直接退出,containerd-shim 会成为容器进程的父进程,负责收集容器进程的状态,上报给 containerd,并在容器中 pid 为 1 的进程退出后接管容器中的子进程,确保不会出现僵尸进程。同时也避免了宿主机上 containerd 进程挂掉的话,所有容器进程都退出。

(1) containerd 和 Docker 细节差异


云原生Kubernetes:CRI 容器运行时接口,云原生,kubernetes,容器

 Docker 作为容器运行时,k8s 其实根本没有使用 docker 本身的存储、网络等功能,只是用了 Docker 的 Image 功能,来满足 CRI 中的镜像服务。

(2)containerd 和 CRI-O

CRI-O是由红帽发起并开源的一款容器运行时,本身比较新,没有太多的生产实践。而且在社区的测试结果中,在操作容器方面的性能以及延时都没有 containerd 优秀。

云原生Kubernetes:CRI 容器运行时接口,云原生,kubernetes,容器

二、总结

 CRI组件(cubelet)主要实现的功能 :

1)镜像管理:镜像拉取、查看和移除
2)pod和容器的生命周期管理,以及与容器的交互(exec/attach/port-forward)

runtime容器运行时:

 1)高层级运行时(Dockershim、containerd 和 CRI-O ),主要是面向外部提供 gRPC 调用。
 2)低层级运行时(runC、kata和gVisor ),定义如何为新容器设置 Linux namespaces 和 cgroups,以及 rootfs 等操作。

CRI 设计的一个重要原则:文章来源地址https://www.toymoban.com/news/detail-704189.html

确保这个接口本身,只关注容器,不关注 Pod(与pod相关的是SandBox(沙箱)相关API,沙箱即容器本身,是容器而非pod的API,之所以叫PodSandbox是因为创建的沙箱(容器)用于部署pod )。

到了这里,关于云原生Kubernetes:CRI 容器运行时接口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【云原生】容器编排工具Kubernetes

    目录 一、 K8S介绍 官网地址: 1.1docker编排与k8s编排相比 1.2特性 1.3功能 二、K8S重要组件 2.1核心组件 (1)Kube-apiserver (2)Kube-controller-manager (3)Kube-scheduler (4)Node ①kubelet ②kube-proxy ③docker (5)etcd 2.2Kubernetes工作原理 三、Pod 3.1 Pod控制器 (1)Deployment (2)ReplicaSet (3)

    2024年02月09日
    浏览(33)
  • 【云原生】Kubernetes容器编排工具

    目录 1. K8S介绍 1.1 k8s的由来 下载地址 1.2 docker编排与k8s编排相比 1.3 传统后端部署与k8s 的对比 传统部署 k8s部署  ​2. k8s的集群架构与组件 (1) Kube-apiserver (2)Kube-controller-manager  (3)Kube-scheduler   2.2 k8s的配置存储中心 2.3  k8s的Node 组件   (1)Kubelet   (2)Kube-Proxy 

    2024年02月10日
    浏览(28)
  • 云原生、容器化、Kubernetes、微服务

    作者:禅与计算机程序设计艺术 云原生(Cloud Native)是一个开放且社区驱动的项目,它定义了一组架构原则、最佳实践和工具集,这些原则、实践和工具围绕业务需求和工程实践而设计,可用于开发人员在构建和运行分布式系统时更加顺畅地交付可靠的软件。云原生可以帮助

    2024年02月07日
    浏览(34)
  • 【云原生】kubernetes中容器的资源限制

    目录 1 metrics-server 2 指定内存请求和限制 3 指定 CPU 请求和限制 资源限制 在k8s中对于容器资源限制主要分为以下两类: 内存资源限制: 内存 请求 (request)和内存 限制 (limit)分配给一个容器。 我们保障容器拥有它请求数量的内存,但不允许使用超过限制数量的内存。 官网参

    2024年02月14日
    浏览(34)
  • 【云原生|Kubernetes】08-Pod中的Init容器

    Init 容器是一种特殊容器,在 Pod内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。 你可以在 Pod 的spec中与用来描述应用容器的 containers 数组平行的位置指定 Init 容器。 Init 容器的状态在 status.initContainerStatuses 字段中以容器状态数组

    2024年02月09日
    浏览(43)
  • 容器和云原生(三):kubernetes搭建与使用

            目录 单机K8S docker containerd image依赖 kubeadm初始化 验证 crictl工具 K8S核心组件 上文安装单机docker是很简单docker,但是生产环境需要多个主机,主机上启动多个docker容器,相同容器会绑定形成1个服务service,微服务场景中多个service会互相调用,那么就需要保证多个servi

    2024年02月11日
    浏览(22)
  • 【云原生-深入理解Kubernetes-1】容器的本质是进程

    大家好,我是秋意零。 😈 CSDN作者主页 😎 博客主页 👿 简介 👻 普通本科生在读 在校期间参与众多计算机相关比赛,如:🌟 “省赛”、“国赛” ,斩获多项奖项荣誉证书 🔥 各个平台, 秋意零/秋意临 账号创作者 🔥 云社区 创建者 点赞、收藏+关注下次不迷路! 欢迎加

    2024年02月02日
    浏览(46)
  • kubernetes--安全沙箱运行容器gVisor

             所知,容器的应用程序可以直接访问Linux内核的系统调用,容器在安全隔离上还是比较弱,虽然内核在不断的增强自身的安全特性,但由于内核自身代码极端复杂,CVE漏洞层出不穷。        所以要想减少这方面安全风险,就是做好安全隔离,阻断容器内程序对

    2024年02月16日
    浏览(41)
  • 云原生小疑问 ⁉️ - Kubernetes 下重启容器会丢失数据吗?

    在 docker 环境下,容器重启后还是原来的容器,数据并没有丢失。那是不是 k8s 环境下,重启也不会丢失呢? 在kubernetes/RainBond环境下, 最小化的管理单元是 Pod 。 对 Pod 的重启,本质上是先删除,然后启动新的容器 。所以原本容器中的数据会丢失。 java程序中一般如下数据需

    2024年04月25日
    浏览(21)
  • 云原生之深入解析Kubernetes中如何使用临时容器进行故障排查

    容器及其周围的生态系统改变了工程师部署、维护和排查工作负载故障的方式。但是,在 Kubernetes 集群上调试应用程序有时可能会很困难,因为可能在容器中找不到所需的调试工具。许多工程师使用基于精简、发行版构建无发行版的基础镜像,其中甚至没有包管理器或shell,

    2024年02月05日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包