K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系

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

写在前面


  • 博文内容整体结构为结合 华为云云原生课程 整理而来,部分内容做了补充
  • 课程是免费的,有华为云账户就可以看,适合理论认知,感觉很不错。
  • 有需要的小伙伴可以看看,链接在文末
  • 理解不足小伙伴帮忙指正

对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧 ——赫尔曼·黑塞《德米安》


为什么从 CRI 讲起,因为 k8s 集群使用 kubelet 服务通过 CRI 接口和对应的 runtime(运行时) 交互,从而控制管理容器。

CRI 是什么? CRI 是一个 Kubernetes API,它定义了 Kubernetes 与不同容器运行时交互的方式。因为它在规范中是标准化的,所以可以选择要使用的 CRI 实现或编写自己的实现。

K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系,K8S&CKA&云原生相关笔记,kubernetes

CRI

K8s 生态中通过 CRI 接口来对 容器运行时进行管理,从而实现对容器镜像的管理,具体一点,通过 kubelet 调用容器运行时的 grpc 接口。

面向接口编程,类比在刚学编程时, Java 中,操作数据库,使用 JDBC API 来连接不同的数据库实现 CRUD,这里具体的数据操作通过不同数据库的驱动包来实现。CRI可以单纯理解为JDBC ,CRI 实现类比不同的数据库驱动包 对于 CRI 接口,有下面的一些实现。

dockershim: 由于 docker 没有实现 CRI 接口,所以 kubernetes 在最初对接 docker api的时候提供了 CRI接口适配器, 但是这是一种冗余的行为,k8s 只是需要 docker 中的 containerd,完全可以直接使用 containerd,所以在之后版本中删除了这部分代码, 在 kubernetes 1.21 版本已经将其标注为废弃接口。在 1.24 版本中彻底移除了该部分代码, 不过 如果任然想使用 docker ,可以使用开源项目 cri-docker 来代替。在部署时需要单独指定 socket

K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系,K8S&CKA&云原生相关笔记,kubernetes

docker 的前置依赖,可以看到它依赖 containerd.service

┌──[root@vms100.liruilongs.github.io]-[~/ansible/openkruise]
└─$systemctl list-dependencies docker | head -n 3
docker.service
● ├─containerd.service
● ├─docker.socket

CRI-containerd:基于 containerd 的 CRI 兼容插件,通过 containerd 中的 CRI插件实现了CRI接口,当前使用最广泛的 CRI接口接口实现。性能好,功能全,适合需要利用 containerd 强大功能的场景。

CRI-O:专注于在 kubernetes 运行容器的轻量级 CRl 接口实现(不关注开发态),CRI-O 是基于 Open Container Initiative (OCI) 标准开发的独立容器管理引擎,独立性好,适合注重兼容性和移植性的场景

CRI 接口由两部分组成

CRI 接口由两部分组成:

  • 通过 RuntimeServiceServer 属性来描述管理容器生命周期的相关行为,包括创建、删除、启动、停止等容器操作,
  • 通过 ImageServiceServer 属性来描述管理镜像相关的行为,如拉取、推送镜像等操作。

通过对这两个行为接口委托,实现 CRI 接口,具体来说:

  • RuntimeServiceServer定义了管理容器生命周期需要调用`的通用方法,如CreateContainer、StartContainer、StopContainer等。这些方法主要用于管理容器运行时状态。
  • ImageServiceServer定义了镜像管理需要调用的通用方法,如ListImages、PullImage、RemoveImage等。这些方法主要用于管理容器镜像资源。
type grpcServices interface {
  runtime.RuntimeServiceServer 
  runtime.ImageServiceServer
}
  • 运行时:负责容器的生命周期管理,包括容器创建,启动、停止、日志和性能采集等接口。
  • 镜像:负责容器镜像的管理,包括显示镜像、拉取镜像、删除镜像等接口。

在早期的CRI实现中,Shimv1是最常见的容器运行时接口实现之一。它通过创建一个额外的代理进程(Shim)来管理容器的生命周期,并与容器运行时进行通信。然而,Shimv1存在一些性能和可靠性方面的限制。

为了改进CRI的性能和稳定性,Shimv2被引入作为CRI的改进版本。

CRI Shimv2

Shimv2使用了ttrpc(Tiny Transport Protocol RPC)作为通信协议,通过与容器运行时直接通信而无需创建额外的代理进程。这种直接的通信方式可以提供更高效、更可靠的容器运行时接口。

K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系,K8S&CKA&云原生相关笔记,kubernetes

OCI

CRI 接口实现和容器运行时交互,这里就要讲到 OCI

OCI 组织:Linux基金会于2015年6月成立OCI(Open Container Initiative)组织,旨在围绕容器格式和运行时制定一个开放的工业化标准

K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系,K8S&CKA&云原生相关笔记,kubernetes

目前主要有两个标准文档:容器运行时标准(runtime spec)容器镜像标准(image spec)

Runtime spec容器运行时标准,定义了容器状态和配置文件格式,容器生命周期管理命令格式和参数等。

image spec镜像标准包,定义了容器镜像的文件系统、config 文件、manifest 文件、index 文件等。

容器标准中包含:

容器命令:容器生命周期管理命令、包括创建、启动、停止、删除等。

#runc create <container id>
#runc start <container id>#runc state <container id>
#runc kill <container-id><signal>
#runc delete <container-id>

config.json文件是OCI(Open Container Initiative)规范定义的容器配置文件,它定义了容器运行时需要了解和使用的所有配置信息

  • rootfs:容器内部文件系统挂载点信息
  • mounts:容器内外部挂载的文件系统信息
  • process:容器内第一个进程(pid=1)的设置,如cmd、args等
  • cgroups:容器要加入的cgroup信息
  • namespaces:容器所在的namespace,比如pid、network等
  • caps:容器能使用的Linux capabilities
  • annotations 等其它配置

主流的容器运行时:

这里需要说明一下,我们常讲的 容器运行时是一个 混合概念,包含低级别容器运行时,和高级别容器运行时,

低级容器运行时,比如runc、lxc、gVisor、Kata容器等,它们主要负责真正与内核进行交互,创建和管理容器运行时的内核级别资源,如cgroups、namespaces等。但无法直接管理镜像。

高级容器运行时,比如Docker引擎、Podmancontainerd 等,它们基于低级容器运行时提供了更高层次的管理能力,可以管理容器生命周期并直接调用低级运行时,同时也内置镜像管理能力,能够拉取、推送镜像等。

两者关系是,高级运行时对低级运行时进行抽象,向上提供完整的容器管理接口。高级运行时在内部会调用对应的低级运行时来管理内核级资源和运行容器。

runc

runc: docker 捐献给 OCI 社区的一个 runtime spec 的参考实现,docker 容器也是基于 runc 创建的。

K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系,K8S&amp;CKA&amp;云原生相关笔记,kubernetes

利用 Linux 内核特性,来隔离进程:

  • Namespace:资源和信息的可见性隔离,通过namespace隔离,容器中的应用只能看到分配到该容器的资源、其他主机上的信息在容器中不可见。常用的namespace有PID(进程号)、MNT(挂载点)、NET(网络)、UTS(主机名)和IPC(跨进程通信)等
  • Cgroups:资源使用量的隔离,通过cgroup、限制了容器使用的资源量,通过不同的子系统,限制不同的资源。包括CPU、内存、io带宽、大页、fd 数等等
  • Capability:权限限制(最低特权原则),Capability是Linux系统设计的一种安全机制。它定义了一组特权标记,可以细粒度控制进程对系统资源的访问权限,通过对进程的capability定义,限制容器中的进程调用某些系统调用,以达到容器进程无法逃逸到主机的目的,比如容器中的进程是不具有以下capability的: SYS ADMIN/MKNOD/SYS RESOURCE/SYS MODULES.…

容器主进程

     1   1898   1898   1034 ?            -1 Sl       0   0:34 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 057fb
  1898   1957   1957   1957 ?            -1 Ss   65535   0:00  \_ /pause
     1   2013   2013   1034 ?            -1 Sl       0   2:58 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 7d167
  2013   2080   2080   2080 ?            -1 Ss       0   0:17  \_ haproxy -W -db -f /usr/local/etc/haproxy/haproxy.cfg
  2080   2133   2080   2080 ?            -1 Sl       0  48:48      \_ haproxy -W -db -f /usr/local/etc/haproxy/haproxy.c

K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系,K8S&amp;CKA&amp;云原生相关笔记,kubernetes

Kata-runtime

K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系,K8S&amp;CKA&amp;云原生相关笔记,kubernetes

Kata-runtime:一种基于 虚拟化 的安全隔离的 OCI runtime spec 的实现。

  1. 虚拟化隔离:每个pod都运行在一个独立的虚拟机中,提供虚拟化接口对接不同的虚拟化实现,包括qemu、cloud hypervisor、firecracker 等等
  2. 轻量化:为了达到和容器近似的使用体验,需要对各组件进行裁剪,达到轻量化和启动加速的目的,对于hypervisor,去除通用虚拟化的各种不必要的设备、总线等。对于guestkernel,也裁剪了大量不需要的驱动和文件系统模块。而运行在虚拟机中的1号进程(一般为kata-agent),资源占用可小于1MB。
  3. 主机资源访问:通过virtio、vfio等方式访问主机资源,如virtio-blk(块设备)、virtio-fs(文件)、virtio-net(网络)、vfio(物理设备)、vhost-user(用户态网络或存储)
gVisor

gVisor:是Google开源的一款安全容器运行时,它使用了系统调用拦截(System call filtering)这一技术来实现容器安全隔离。

  • gVisor通过内核模块注入方式,在用户空间和内核空间之间插入一个中间层。
  • 这个中间层对所有从容器发起的系统调用请求进行拦截和filtering。
  • 根据预先定义的安全策略,选择性通过或拒绝这些系统调用请求,限制容器对内核资源的访问。

通过这种方式:

  • gVisor无需真正virtualize内核功能,性能开销小。
  • 但能实现丰富的安全隔离,如文件系统读写限制、网络隔离等。

所以总体来说,gVisor采用轻量级的系统调用过滤技术,在不影响性能的情况下,有效地隔离和限制容器对系统资源的访问,从而有效提升容器安全性。

K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系,K8S&amp;CKA&amp;云原生相关笔记,kubernetes

  1. 虚拟内核:设置进程的4种模式,HRO、HR3、GRO、GR3,通过拦截系统调用,实现了一个虚拟内核,用户进程与host kernel不直接交互
  2. 拦截系统调用的方式:ptrace、kvm
  3. 优点:额外内存消耗小,容器启动速度快
  4. 缺点:系统调用慢,导致I0、网络等性能差,由于是模拟内核,有POSIX兼容性问题

知道了CRI,OCI,可能会有这样一个疑问,容器运行时(runtime)是如何和 Pod 关联起来的? 这里就要讲到 RuntimeClass

RuntimeClass

RuntimeClass 是 Kubernetes 中的一个对象类型,用于定义集群中的特定运行时``。RuntimeClass 允许您通过指定 overhead(开销)nodeSelector(节点选择器)来自定义特定运行时的资源和调度行为

RuntimeClass 的主要作用是将容器运行时与 Pod 关联起来。它定义了一组属性,包括运行时名称、调度器名称、节点选择器和资源限制。通过将 PodRuntimeClassName 字段设置为特定的 RuntimeClass 名称,可以指定该 Pod 使用特定的容器运行时。

K8s:一文认知 CRI,OCI,容器运行时,Pod 之间的关系,K8S&amp;CKA&amp;云原生相关笔记,kubernetes

使用 RuntimeClass,可以针对不同的运行时场景进行资源和调度的优化。例如,您可以定义一个 RuntimeClass,针对 CPU 密集型任务使用资源更多的容器运行时,并通过节点选择器将该 RuntimeClass 的 Pod 调度到具备较高 CPU 资源的节点上。

Runtime Plugin:containerd中的runtime插件配置,定义了runtime名称、二进制路径、传递的annotation、特权容器模式等等。

关于容器引擎和运行时机制原理认知就和小伙伴们分享到这里

博文部分内容参考

文中涉及参考链接内容版权归原作者所有,如有侵权请告知 😃


https://connect.huaweicloud.com/courses/learn/learning/sp:cloudEdu_?courseNo=course-v1:HuaweiX+CBUCNXI041+Self-paced&courseType=1&source=1


© 2018-2023 liruilonger@gmail.com, All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)文章来源地址https://www.toymoban.com/news/detail-698639.html

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

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

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

相关文章

  • 验证K8S集群pod之间传输速度过慢,导致pod之间业务无法正常交互

    原因: K8S部署完成后,但是pod之间无法进行交互访问,导致pod异常 定位思路: 通过启动两个busybox容器,之间进行scp传输文件,验证pod之间tcp连接是否正常 解决方法: 运行第一个busybox 拷贝文件至busybox1 进入第一个busybox1 进入第二个busybox1 结论: 发现1K的文件可以相互拷贝

    2024年03月19日
    浏览(65)
  • k8s 多容器pod进入指定容器

    kubectl exec -it prometheus-prometheus-server-697cccff9c-qtrf7 -c prometheus-server sh

    2024年02月14日
    浏览(62)
  • K8S内部pod之间相互调用案例和详解

    目录 一、部署nginx容器 二、部署tomcat服务 三、使用nginx代理tomcat服务 四、测试 1、service是用于K8S的服务发现的重要组件,pod作为运行业务的承载方式,要想被客户端访问或者集群内部其它服务访问,就需要提供一个访问入口;  2、传统来说ip+端口是普适的访问方式,但是

    2024年02月03日
    浏览(51)
  • k8s 不同node之间pod ip不通

    底层k8s使用calico网络,ipip网络模式,kubevirt启动了2台虚拟机;在这两台虚拟机上再搭建k8s,calico网络,ipip网络模式。 在虚拟机上的k8s上启动了2个pod,分布在不同的node上,这两个pod不能ping通对方的pod ip。 1、calico无问题; 2、主机路由无问题。 修改虚拟机之上的k8s集群的c

    2024年02月13日
    浏览(44)
  • K8S | 容器和Pod组件

    对比软件安装和运行; 作为研发人员,通常自己电脑的系统环境都是非常复杂,在个人的习惯上,是按照下图的模块管理电脑的系统环境; 对于「基础设施」、「主机操作系统」、「系统软件」来说,通常只做配置修改; 对于自行安装的软件环境来说,个人通常这样分类:

    2024年02月11日
    浏览(57)
  • k8s pod 容器间测试接口

    1、配置k8s 详细的配置参考官网 2、获取pod节点PODID信息 3、进入到pod容器内部 4、安装CURL 5、调用测试接口 6、查看调用工程的Pod的日志

    2024年02月12日
    浏览(216)
  • K8s Pod状态与容器探针

    Pod创建过程如上图所示,首先用户向apiserver发送创建pod的请求,apiserver收到用于创建pod请求后,对应会对该用户身份信息进行验证,该用户是否是合法的用户,是否具有创建pod的权限,如果能够通过apiserver的验证,则进行下一步,对用户提交的资源进行准入控制,所谓准入控

    2024年02月07日
    浏览(92)
  • k8s快速查看pod对应的容器

    环境: centos 7.6 k8s 1.20 我们知道,在k8s中最小基本单位是pod,而一个pod里面可以封装一个或多个容器,而在宿主机上容器的名字并不是pod的名字,所以,下面的方式可以快速的查看一个pod里面对应宿主机哪些容器:

    2024年02月07日
    浏览(49)
  • K8s(四)Pod资源——pod生命周期、重启策略、容器钩子与容器探测

    目录 Pod生命周期 Pod重启策略 初始化容器 容器钩子 容器探测 启动探测 存活探测 就绪探测 参考资料 Pod 的生命周期 | Kubernetes Init 容器 | Kubernetes Pod的生命周期可以分为以下几个阶段: Pending(等待):在这个阶段,Pod被创建,并且正在等待被调度到一个节点上运行。此时,

    2024年01月20日
    浏览(47)
  • Kubernetes(k8s)容器编排Pod介绍和使用

    Pod是kubernetes中你可以创建和部署的最小也是最简的单位,一个Pod代表着集群中运行的一个进程。 Pod有两个必须知道的特点 通过yaml文件或者json描述Pod和其内容器的运行环境和期望状态,例如一个最简单的运行nginx应用的pod,定义如下 3.1.1 参数描述 下面简要分析一下上面的

    2024年02月08日
    浏览(84)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包