OCI && CRI

使用容器经常会听到容器运行时的概念、OCI以及CRI等,这些有什么区别和联系呢?

  • CR,即Container Runtime,容器运行时
  • CRI,即Container Runtime Interface,容器运行时接口,实现该系列接口以实现容器功能
  • OCI,即Open Container Initiative:开口容器倡议,是建立围绕容器格式和运行时的开放式行业标准的明确目的的开放式的治理结构。

OCI 目前包含两个规范:运行时规范(runtime-spec)和镜像规范(image-spec)。运行时规范概述了如何运行在磁盘上解压缩的“文件系统包”。

现在清楚了,OCI定义了一种规范,即怎么做如何做。而CR是这个规范的实践并定义了一系列接口CRI,只要实现了该接口就能使用这个CR。

比如CR有很多种,如runc、lxc等,但他们都提供了统一的CRI,其他实现了这个CRI的组件如kubelet在runc和lxc间切换是无感的。

低级(low-level)容器运行时

我理解的low-level是一系列操作容器的行为在很底层,比如通过Linux内核接口创建各个Namespace以及生成Cgroup等操作。把这些行为打包就是一个低级的运行时的内容。或者说低级容器运行时干了啥。

高级(high-level)容器运行时

高级容器运行时又干了啥事情呢?镜像管理、镜像传输、镜像解压缩等技术都可以归为高级的容器运行时。

比如docker提供的镜像构建、拉取等。docker可以分为以下几层:

+----------+
|          |
|  docker  |
|          |
+-----+----+
      | socket/API
      |
+-----v----+
|          |
|  dockerd |
|          |
+-----+----+
      |  socket/API
      |
+-----v----+
|          |
|contanerd |
|          |
+-----+----+
      |
      | OCI
+-----v----+
|          |
|  runc    |
+----------+

K8s 与 CRI

k8s 1.5 中自己实现了 docker CRI shim,通过这个组件与docker交互。管理容器的过程还是通过docker那套,在containerd 1.1版本中containerd直接实现了CRI,kubelet可以直接通过这个CRI实现与containerd的交互,从而绕过了docker。

CRI 定义了几种远程过程调用 (RPC) 和消息类型。RPC 用于:

  • 拉取镜像 ImageService.PullImage
  • 创建pod RuntimeService.RunPodSandbox
  • 创建容器RuntimeService.CreateContainer
  • 启动容器RuntimeService.StartContainer
  • 停止容器RuntimeService.StopContainer

等操作。

实现一个容器运行时

参考链接

Container Runtimes Part 1: An Introduction to Container Runtimes

opencontainers.org

runtime-spec

Building a container from scratch in Go - Liz Rice (Microscaling Systems)