CRI shim:Kubelet 怎么与容器运行时交互之二

开发 架构
今天给大家 propose 的这个东西叫做 Containerd ShimV2。前面我们说过 CRI,CRI 决定的是 Runtime 和 Kubernetes 之间的关系,那么我们现在能不能再有一层更细致的 API 来决定我的 CRI Shim 跟下面的 Runtime 之间真正的接口是什么样的?

[[441669]]

前言

通过《CRI shim:kubelet怎么与容器运行时交互(一)》这一篇文章,我们知道了:

  • CRI 是服务于 Kubernetes 的,而且它呈现向上汇报的状态。它是帮助 Kubernetes 的,它不帮助OCI的。所以说当你去做这个集成时候,你会发现尤其对于 VM gVisor\KataContainer 来说,它与 CRI 的很多假设或者是 API 的写法上是不对应的。所以你的集成工作会比较费劲,这是一个不 match 的状态。
  • 另一个问题就是我们维护起来非常困难,因为由于有了 CRI 之后,比如 RedHat 拥有自己的 CRI 实现叫 cri-o,他们和 containerd 在本质上没有任何区别,跑到最后都是靠 runC 起容器,为什么还需要cri-o这种东西?我们不知道,如果我想使用Kata container与containerd多运行时的话,我需要给他们两个分别写两部分的一体化把 Kata 集成进去。这就很麻烦,就意味着我有 100 种这样的 CRI ,我就要写 100 个shim去集成,而且他们的功能全部都是重复的。
  • 多容器运行时用于不同目的,比如使用虚拟化容器引擎式运行不可信应用和多租户应用,而使用 Docker 运行系统组件或者无法虚拟化的容器(比如需要 HostNetwork 的容器。

所以这就产生了Containerd ShimV2的这样的shim来解决这个问题。

Containerd ShimV2

2018 年,由 containerd 社区主导的 shimv2 API 的出现,在 CRI 的基础上,为用户集成自己的容器运行时带来了更加成熟和方便的实践方法。

今天给大家 propose 的这个东西叫做 Containerd ShimV2。前面我们说过 CRI,CRI 决定的是 Runtime 和 Kubernetes 之间的关系,那么我们现在能不能再有一层更细致的 API 来决定我的 CRI Shim 跟下面的 Runtime 之间真正的接口是什么样的?

这就是 ShimV2 出现的原因,它是一层 CRI shim 到 Containerd runtime 之间的标准接口,所以前面我直接从 CRI 到 Containerd 到 runC,现在不是。我们是从 CRI 到 Containerd 到 ShimV2,然后 ShimV2 再到 RunC 或者 KataContainer。这么做有什么好处?

我们来看一下,最大的区别在于:在这种方式下,你可以为每一个 Pod 指定一个 Shim。因为在最开始的时候,Containerd 是直接启动了一个 Containerd Shim 来去做响应,但我们新的 API 是这样写的,是 Containerd Shim start 或者 stop。所以这个 start 和 stop 操作怎么去实现是你要做的事情。

现在,我作为一位 Kata Containers项目的维护者我就可以这么实现。我在 created Sandbox 的时候 call 这个 start 的时候,我启动一个 Containerd Shim。

但是当我下一步是调用 API 的时候,就是在前面那个 CRI 里面,访问 Container API 时候,我就不用再启动一个连接,我是复用。我重用创建好的这个 Sandbox,这就为你的实现提供了很大的自由度。所以这时候你会发现整个实现的方式变了,这时候 Containerd 用过来之后,它不再去关心每个容器起 Containerd Shim,而是由你自己去实现。我的实现方式是我只在 Sandbox 时候,去创建 containerd-shim-v2,而接下来整个后面的 container 层的操作,会全部走到这个 containerd-shim-v2 里面,去重用这个 Sandbox,所以这个跟前面的时间就出现很大的不同。

所以你现在去总结一下这个图的话,你发现我们实现方式是变成这个样子:

首先,你还是用原来的 CRI Containerd,只不过现在装的是 runC,你现在再装一个 kata container 放在那机器上面。接下来我们 Kata 那边会给你写一个实现叫 kata-Containerd-Shimv2。

现在,我们只聚焦在怎么去把 Containerd 对接在 kata container 上面,就是所谓的实现 Shimv2 API,这是我们要做的工作。而具体到我们这要做的事情上,其实它就是这样一系列与run一个容器相关的 API。比如说我可以去 create、start,这些操作全部映射在我 Shimv2 上面去实现,而不是说我现在考虑怎么去映射,去实现 CRI,这个自由度由于之前太大,造成了我们现在的一个局面,就有一堆 CRI Shim 可以用。这其实是一个不好的事情。有很多政治原因,有很多非技术原因,这都不是我们作为技术人员应该关心的事情,你现在只需要想我怎么去跟 Shimv2 对接就好了。

给 Kubernetes 提供 kata-runtime

通过直接创建 Container 可以使用 kata-runtime 。但在集群中,我们该如何告诉 Kubernetes 哪些负载需要使用 kata-runtime 呢?根据不同的版本,Kata 提供了不同的方式。1.以 CentOS 操作系统为例,安装kata及命令工具:

$ source /etc/os-release 
$ yum -y install yum-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 -y install kata-runtime kata-proxy kata-shim 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

2.首先检查Kata 对硬件的要求是否满足以下任意条件:

  • Intel VT-x technology.
  • ARM Hyp mode (virtualization extension).
  • IBM Power Systems.
  • IBM Z mainframes.

安装完 kata-runtime 之后,执行检测命令:

$ kata-runtime kata-check 
$ System is capable of running Kata Containers 
$ System can currently create Kata Containers 
  • 1.
  • 2.
  • 3.

3.安装 Kubernetes 集群 使用 Kubeadm 安装集群非常方便,可以参考之前的文档 使用 Kubeadm 安装 Kubernetes 集群 。4.生成 containerd 配置文件

containerd config default > /etc/containerd/config.toml 
  • 1.
  • RuntimeClass 的方式

这种方式对相关组件版本有要求:

Kata Containers v1.5.0 or above (including 1.5.0-rc) 
Containerd v1.2.0 or above 
Kubernetes v1.12.0 or above 
  • 1.
  • 2.
  • 3.

在 config.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 = false 
       NoNewKeyring = false 
       ShimCgroup = "" 
       IoUid = 0 
       IoGid = 0 
       BinaryName = "runc" 
       Root = "" 
       CriuPath = "" 
       SystemdCgroup = false 
  [plugins.cri.containerd.runtimes.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 = false 
       NoNewKeyring = false 
       ShimCgroup = "" 
       IoUid = 0 
       IoGid = 0 
       BinaryName = "/usr/bin/kata-runtime" 
       Root = "" 
       CriuPath = "" 
       SystemdCgroup = false 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.

这里 [plugins.cri.containerd.runtimes.kata] 中的 kata 将被作为 RuntimeClass handler 关键字。

  • 使用 untrusted_workload_runtime 的方式

对于不符合上述版本要求的环境,可以使用之前的方式。在配置文件中新增如下内容:

[plugins.cri.containerd.untrusted_workload_runtime] 
  runtime_type = "io.containerd.runtime.v1.linux" 
  runtime_engine = "/usr/bin/kata-runtime" 
  • 1.
  • 2.
  • 3.

最后,都需要重启 containerd。

$ containerd systemctl daemon-reload 
$ systemctl restart containerd 
  • 1.
  • 2.

5.使用 kata-runtime 方式一:RuntimeClass 方式

  • 创建 RuntimeClass
kind: RuntimeClass 
apiVersion: node.k8s.io/v1beta1 
metadata: 
  name: kata-containers 
handler: kata 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

也可以为 runc 创建 RuntimeClass

$ kubectl get runtimeclass 
 
NAME              CREATED AT 
kata-containers   2020-08-30 
  • 1.
  • 2.
  • 3.
  • 4.

创建负载 kata-pod.yaml

apiVersion: v1 
kind: Pod 
metadata: 
  name: kata-nginx 
spec: 
  runtimeClassName: kata-containers 
  containers: 
  - name: nginx 
    image: nginx 
    ports: 
    - containerPort: 80 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

执行创建:

$ kubectl apply -f kata-pod.yaml 
  • 1.

查看负载:

$ kata-runtime list 
  • 1.

方式二:untrusted_workload_runtime 的方式 untrusted_workload_runtime 使用 annotations 告诉 Kubernetes 集群哪些负载需要使用 kata-runtime。

annotations: 
  io.kubernetes.cri.untrusted-workload: "true" 
  • 1.
  • 2.

下面是一个示例 kata-pod-untrusted.yaml

apiVersion: v1 
kind: Pod 
metadata: 
  name: kata-nginx-untrusted 
  annotations: 
    io.kubernetes.cri.untrusted-workload: "true" 
spec: 
  containers: 
  - name: nginx 
    image: nginx 
    ports: 
    - containerPort: 80 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

执行创建:

$ kubectl apply -f kata-pod-untrusted.yaml 
  • 1.

查看负载:

$ kata-runtime list 
  • 1.

总结

Kubernetes 现在的核心设计思想,就是通过接口化和插件化,将原本复杂的、对主干代码有侵入性的特性,逐一从核心库中剥离和解耦。而在这个过程中,CRI 就是 Kubernetes 项目中最早完成了插件化的一个调用接口。这里主要为你介绍了在CRI基础上的另一种集成容器运行时的思路,即:CRI + containerd shimv2 的方式。

  • 通过这种方式,你就不需要再为自己的容器运行时专门编写一个 CRI 实现(CRI shim),而是可以直接重用 containerd对 CRI 的支持能力,然后通过 containerd shimv2的方式来对接具体的容器运行时(比如 runc)。
  • 这种集成方式已经成为了社区对接下层容器运行时的主流思路,像很多类似于 KataContainers,gVisor,Firecracker 等基于独立内核或者虚拟化的容器项目,也都开始通过 shimv2 ,进而借助 containerd项目无缝接入到 Kubernetes 当中。

reference

 

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-container%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

 

责任编辑:武晓燕 来源: 运维开发故事
相关推荐

2021-11-05 08:07:57

kubeletKubernetesContainerd

2023-08-29 08:20:35

Kubernete跨云容器

2021-10-22 00:09:16

Kubernetes容器接口

2023-04-03 13:01:14

UbuntuCRI-O

2024-03-20 10:46:00

云原生容器

2019-07-12 09:30:12

DashboardDockerDNS

2021-09-11 15:38:23

容器运行镜像开放

2023-01-03 09:10:21

2020-08-11 08:59:20

容器虚拟化技术

2015-07-20 15:44:46

Swift框架MJExtension反射

2025-03-03 08:05:14

2024-07-15 18:20:18

2024-03-21 09:15:58

JS运行的JavaScrip

2024-01-08 08:24:02

PythonSys 模块工具

2023-09-07 07:17:01

KubernetesCRI标准

2021-07-10 07:39:38

Node.js C++V8

2021-09-02 05:37:22

Containerd Kubernetes 容器

2021-03-15 08:33:01

CC++动态库

2013-11-26 16:49:55

Android开发运行时KitKat

2023-07-28 10:42:43

点赞
收藏

51CTO技术栈公众号