CRI和容器运行时
发表于:2025-12-09 | 分类: 学习

有了CRI的Kubernetes 的架构图:

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

CRI的接口可以分为两组:

  • 第一组,是 RuntimeService。它提供的接口,主要是跟容器相关的操作。比如,创建和启动容器、删除容器、执行 exec 命令等等。
  • 而第二组,则是 ImageService。它提供的接口,主要是容器镜像相关的操作,比如拉取镜像、删除镜像等等。

RuntimeService接口本身,只关注容器,不关注 Pod。

首先,Pod 是 Kubernetes 的编排概念,而不是容器运行时的概念。所以,我们就不能假设所有下层容器项目,都能够暴露出可以直接映射为 Pod 的 API。

其次,如果 CRI 里引入了关于 Pod 的概念,那么接下来只要 Pod API 对象的字段发生变化,那么 CRI 就很有可能需要变更。而在 Kubernetes 开发的前期,Pod 对象的变化还是比较频繁的,但对于 CRI 这样的标准接口来说,这个变更频率就有点麻烦了。

在 CRI 的设计里,并没有一个直接创建 Pod 或者启动 Pod 的接口。

CRI 里有一组叫作 RunPodSandbox 的接口。 PodSandbox是抽取了 Pod 里的一部分与容器运行时相关的字段,比如 HostName、DnsConfig、CgroupParent 等。PodSandbox 这个接口描述的,是 Kubernetes 将 Pod 这个概念映射到容器运行时层面所需要的字段,或者说是一个 Pod 对象子集。

下图展示了Kubernetes 期望的 Pod 模型:

当执行 kubectl run 创建了一个名叫 foo 的、包括了 A、B 两个容器的 Pod 之后。这个 Pod 的信息最后来到 kubelet,kubelet 就会按照图中所示的顺序来调用 CRI 接口。

CRI有一个叫Streaming的API,用于实现 exec、logs 等接口,这些 gRPC 接口调用期间,kubelet 需要跟容器项目维护一个长连接来传输数据。

CRI shim 里对 Streaming API 的实现,依赖于一套独立的 Streaming Server 机制,如图所示:

当我们对一个容器执行 kubectl exec 命令的时候,这个请求首先交给 API Server,然后 API Server 就会调用 kubelet 的 Exec API。接着kubelet 就会调用 CRI 的 Exec 接口,而负责响应这个接口的,自然就是具体的 CRI shim。

上一篇:
Kubernetes监控
下一篇:
SIG-Node与CRI