当前位置: 首页 > 科技观察

CRIshim:Kubelet如何与ContainerRuntime交互II

时间:2023-03-11 21:00:57 科技观察

前言通过本文《CRI shim:kubelet怎么与容器运行时交互(一)》,我们知道:CRI服务于Kubernetes,呈现向上的状态。它适用于Kubernetes,不适用于OCI。所以当你做这个集成的时候,你会发现,尤其是对于VMgVisor\KataContainer,它并不对应CRI的很多假设或者API的写法。所以你的融合工作会比较困难,这是一种不匹配的状态。还有一个问题就是我们维护起来非常困难,因为有了CRI之后,比如RedHat有自己的CRI实现叫cri-o,本质上和containerd是一样的。最后都是依赖runC来启动容器。为什么?还需要像cri-o这样的东西吗?我们不知道,如果我想使用Katacontainer和containerd来运行更多,我需要为它们编写两部分集成,将Kata集成到其中。这样很麻烦,也就是说我有100个这样的CRI,我要写100个shim来集成,而且它们的功能都是重复的。多容器运行时用于不同的目的,例如使用虚拟化的容器引擎来运行不受信任的应用程序和多租户应用程序,而使用Docker来运行系统组件或无法虚拟化的容器(例如需要HostNetwork的容器。所以这个创建ContainerdShimV2这样的shim解决了这个问题,ContainerdShimV22018年,containerd社区主导的shimv2API的出现,基于CRI,为用户集成自己的容器运行时带来了更加成熟便捷的实用方法。今天我向您推荐的东西叫做ContainerdShimV2。前面我们提到了CRI,CRI决定了Runtime和Kubernetes之间的关系,那我们现在能不能有一个更详细的API来确定我的CRIShim和下面的Runtime真正的接口?这就是ShimV2出现的原因,它是一层CRIshim和Containerdruntime之间的标准接口,所以我之前直接从CRI到Containerd再到runC,现在不行了。我们从CRI到Containerd再到ShimV2,然后从ShimV2到RunC或KataContainer。这样做有什么好处?让我们来看看。最大的区别是:通过这种方式,你可以为每个Pod指定一个Shim。因为最开始的时候,Containerd直接启动了一个ContainerdShim来响应,但是我们新的API是这样写的,就是ContainerdShim启动或者停止。那么如何实现启停操作就是你要做的事情了。现在,作为KataContainers项目的维护者,我可以做到这一点。当我在创建Sandbox时调用这个start时,我启动了一个ContainerdShim。但是当我下一步调用API的时候,也就是在之前的CRI中,访问ContainerAPI的时候,不需要再开启一个连接,我是多路复用的。我重用了创建的Sandbox,它为您的实现提供了很大的自由度。所以这个时候,你会发现整个实现方式都变了。这时候使用Containerd之后,不再关心从ContainerdShim开始的每一个容器,而是自己去实现。我的实现方式是我在Sandbox的时候只创建containerd-shim-v2,然后后面整个container层的操作都会跑到这个containerd-shim-v2去复用Sandbox,所以下面有一个与上次大不相同。所以你现在去总结这张图,你会发现我们的实现方式变成了这样:首先你还是用原来的CRIContainerd,但是现在你安装了runC,现在你安装了一个kata容器,放到机器上多于。接下来Kata会为你写一个实现,叫做kata-Containerd-Shimv2。现在,我们只关注如何将Containerd连接到kata容器,也就是所谓的Shimv2API的实现,这是我们要做的事情。至于我们要做的,其实就是一系列运行容器相关的API。比如我可以去创建并开始。所有这些操作都映射到我的Shimv2去实现,而不是现在想着怎么映射实现CRI。之前这个自由度太大了,才造成了我们现在的情况。有一堆CRI垫片可用。这实际上是一件坏事。有很多政治原因和很多非技术原因。这些都不是我们作为技术人员应该关心的事情。现在你只需要考虑我如何与Shimv2连接。为Kubernetes提供kata-runtime通过直接创建一个Container,就可以使用kata-runtime。但是在集群中,我们如何告诉Kubernetes哪些负载需要使用kata-runtime呢?根据不同的版本,Kata提供了不同的方式。1、以CentOS操作系统为例,安装kata和命令工具:$source/etc/os-release$yum-yinstallyum-utils$ARCH=$(arch)$BRANCH="${BRANCH:-master}"$yum-config-manager--add-repo"http://download.opensuse.org/repositories/home:/katacontainers:/releases:/${ARCH}:/${BRANCH}/CentOS_${VERSION_ID}/home:katacontainers:releases:${ARCH}:${BRANCH}.repo"$yum-yinstallkata-runtimekata-proxykata-shim2.首先检查Kata的硬件要求是否满足以下任一条件:IntelVT-x技术。ARMHyp模式(虚拟化扩展)。IBM电力系统。IBMZ大型机。安装kata-runtime后,执行检测命令:$kata-runtimekata-check$SystemiscapableofrunningKataContainers$SystemcancurrentlycreateKataContainers3。安装Kubernetes集群使用Kubeadm安装集群非常方便,可以参考之前的文档Kubeadm安装Kubernetes集群。4.生成containerd配置文件的方法containerdconfigdefault>/etc/containerd/config.tomlRuntimeClass该方法对相关组件版本有要求:config中的KataContainersv1.5.0orabove(including1.5.0-rc)Containerdv1.2.0oraboveKubernetesv1.12.0orabove.在toml配置文件中,添加如下内容:[plugins.cri.containerd]no_pivot=false[plugins.cri.containerd.runtimes][plugins.cri.containerd.runtimes.runc]runtime_type="io.containerd.runc。v1"[plugins.cri.containerd.runtimes.runc.options]NoPivotRoot=falseNoNewKeyring=falseShimCgroup=""IoUid=0IoGid=0BinaryName="runc"Root=""CriuPath=""SystemdCgroup=false[plugins.cri.containerd。运行时。kata]runtime_type="io.containerd.kata.v2"[plugins.cri.containerd.runtimes.katacli]runtime_type="io.containerd.runc.v1"[plugins.cri.containerd.runtimes.katacli.options]NoPivotRoot=falseNoNewKeyring=falseShimCgroup=""IoUid=0IoGid=0BinaryName="/usr/bin/kata-runtime"Root=""CriuPath=""SystemdCgroup=false这里,[plugins.cri.containerd.runtimes.kata]中的kata将作为RuntimeClasshandler关键字使用untrusted_workload_runtime方法。对于不满足上述版本要求的环境,可以使用前面的方法。在配置文件中添加如下内容:[plugins.cri.containerd.untrusted_workload_runtime]runtime_type="io.containerd.runtime.v1.linux"runtime_engine="/usr/bin/kata-runtime"最后需要重启containerd.$containerdsystemctldaemon-reload$systemctlrestartcontainerd5。使用kata-runtime方法一:RuntimeClass方式创建RuntimeClasskind:RuntimeClassapiVersion:node.k8s.io/v1beta1metadata:name:kata-containerhandler:kata也可以创建runtimeClass为runc$kubectlgetruntimeclassNAMECREATEDATkata-containers2020-08-3创建加载kata-pod。yamlapiVersion:v1kind:Podmetadata:name:kata-nginxspec:runtimeClassName:kata-containerscontainers:-name:nginximage:nginxports:-containerPort:80执行创建:$kubectlapply-fkata-pod.yaml查看加载:$kata-runtimelist方法2:untrusted_workload_runtime方法untrusted_workload_runtime使用注解告诉Kubernetes集群哪些负载需要使用kata-runtime。annotations:io.kubernetes.cri.untrusted-workload:"true"这是一个例子kata-pod-untrusted.yamlapiVersion:v1kind:Podmetadata:name:kata-nginx-untrustedannotations:io.kubernetes.cri.untrusted-workload:"true"spec:containers:-name:nginximage:nginxports:-containerPort:80执行创建:$kubectlapply-fkata-pod-untrusted.yaml查看加载:$kata-runtimelist总结一下目前Kubernetes的核心设计思想,其中是通过接口和Plug-in,将原有的复杂和侵入性的特性从核心库中一一剥离和解耦。在这个过程中,CRI是Kubernetes项目中最早的插件调用接口。这里主要介绍另一种基于CRI集成容器运行时的方式,即:CRI+containerdshimv2。这样就不需要为自己的容器运行时编写CRI实现(CRIshim),而是可以直接复用containerd对CRI的支持,然后使用containerdshimv2连接到具体的容器操作时(比如runc).这种集成方式已经成为社区对接下层容器运行时的主流思路。许多基于独立内核或虚拟化的容器项目,如KataContainers、gVisor、Firecracker,也开始使用shimv2,然后使用containerd项目无缝集成到Kubernetes中。参考https://blog.csdn.net/yuchunyu97/article/details/109241723https://github.com/kata-containers/documentation/blob/master/install/centos-installation-guide.mdhttps://ustack.io/2019-11-21-容器%E7%9B%B8%E5%85%B3%E6%A6%82%E5%BF%B5%E6%A2%B3%E7%90%86.htmlhttps://github。com/kata-containers/documentation/blob/master/how-to/how-to-use-k8s-with-cri-containerd-and-kata.mdhttps://github.com/kubernetes/kubernetes/issues/73189https://blog.zufardhiyaulhaq.com/kubernetes-with-cri-containerd-and-kata-containers/https://www.chenshaowen.com/blog/how-to-integrate-kata-in-kubernetes-cluster.html