3

前言
在涉及到容器时你经常听到一个术语:容器运行时。每个人对这个术语都有不同的理解,即使在容器社区也是这种情况。这篇文章是这个系列文章的第一篇,它们分别是:

  • 容器运行时介绍:为什么它们令人如此困惑?
  • 深入Low-Level 运行时
  • 深入High-Level 运行时
  • Kubernetes运行时和CRI

    这篇文章将会介绍容器运行时是什么和为什么会让人如此困惑,然后深入介容器运行时不同的类型,它们是如何工作的以及它们之间的不同点。

    image.png
    通常来说,一个计算机程序员可能将一个程序的运行周期理解为"运行时",或者是支持其运行的语言的特定实现,其中的一个例子是`Java HotSpot运行时,后者更接近"容器运行时"的概念。容器运行时负责一个容器运行的所有部分,而容器实际上并未在运行程序本身。正如我们将从本系列文章中看到的那样,运行时实现了各个级别的功能特性,但实际上运行一个容器就是调用容器运行时所需的全部。

为什么容器让人如此困惑?

Docker于2013年发布,它端到端地解决了开发者运行容器的诸多问题:

  • 容器镜像格式
  • 构建镜像的方法(Dcokerfile/docker build
  • 管理容器镜像的方法(Docker images, docker rm, etc
  • 管理容器实例的方法(docker ps, docker rm, etc
  • 分享容器镜像的方法(docker push/pull
  • 运行容器的方法(docker run

在那时,Docker是一个一体化的系统,然而事实上这些功能特性彼此之间并没有相互依赖,它们中的每一个都可以在一个更小更专注的工具实现,每个工具都可以在一个通用的标准(容器标准)下一起使用。因为这个缘故,Docker,Google,CoreOS以及其他的供应商一起创立了开放容器规范(OCI),同时他们拆分了容器运行这部分的代码将其作为一个工具或lib库称之为run c,然后捐赠给OCI作为OCI运行标准的参考范例。
最初,这使Docker对OCI的捐赠感到困惑,他们捐赠的是一个标准而不是运行容器的方法,其中并没有包含镜像格式或者镜像仓库拉取推送规则,当你运行一个Docker容器的时候,它们实际上经过了以下的步骤:

  • 下载镜像
  • 将镜像文件解开为bundle文件,将一个文件系统拆分成多层
  • bundle文件运行容器

Docker标准化的仅仅是第三步。在此之前,每个人都认为容器运行时支持Docker支持的所有功能。最终,Docker方面澄清:原始OCI规范指出,只有“运行容器”的部分组成了runtime。这种“概念失联”一直持续到今天,并使“容器运行时”成为一个令人困惑的话题。希望我能证明双方都不是完全错误的,并且在本博文中将广泛使用该术语。

Low-Level和High-Level容器运行时

当人们想到容器运行时时,可能会想到许多示例。runc,lxc,lmctfy,Docker(containerd),rkt,cri-o。这些中的每一个都是针对不同的情况而构建的,并实现了不同的功能。有些容器(例如containerdcri-o容器)实际上使用runc来运行容器,在runc之上实现了镜像管理和API接口。与runcLow-Level特性相比,您可以将这些功能(包括图像传输,图像管理,图像解压缩和API)视为High-Level特性。考虑到这点,可以看到容器运行时空间相当复杂,每个运行时涵盖了从Low-LevelHigh-Level的不同部分,这里有一张非常直观的图:
image.png

因此,从实际出发,通常只专注于正在运行的容器的runtime通常称为“Low-Level容器运行时”,支持更多高级功能(如镜像管理和gRPC / Web API)的运行时通常称为“High-Level容器运行时”,“High-Level容器运行时”或通常仅称为“容器运行时”,我将它们称为“高级容器运行时”。值得注意的是,Low-Level容器运行时和High-Level容器运行时是解决不同问题的、从根本上不同的事物。容器是通过Linux nanespaceCgroups实现的,Namespace能让你为每个容器提供虚拟化系统资源,像是文件系统和网络,Cgroups提供了限制每个容器所能使用的资源的如内存和CPU使用量的方法。在最低级别的运行时中,容器运行时负责为容器建立namespacescgroups,然后在其中运行命令,Low-Level容器运行时支持在容器中使用这些操作系统特性。

通常情况下,开发人员想要运行一个容器不仅仅需要Low-Level容器运行时提供的这些特性,同时也需要与镜像格式、镜像管理和共享镜像相关的API接口和特性,而这些特性一般由High-Level容器运行时提供。就日常使用来说,Low-Level容器运行时提供的这些特性可能满足不了日常所需,因为这个缘故,唯一会使用Low-Level容器运行时的人是那些实现High-Level容器运行时以及容器工具的开发人员。那些实现Low-Level容器运行时的开发者会说High-Level容器运行时比如containerdcri-o不像真正的容器运行时,因为从他们的角度来看,他们将容器运行的实现外包给了runc。但是从用户的角度来看,它们只是提供容器功能的单个组件,可以被另一个的实现替换,因此从这个角度将其称为runtime仍然是有意义的。即使containerdcri-o都使用runc,但是它们是截然不同的项目,支持的特性也是非常不同的。


EngineerLeo
598 声望38 粉丝

专注于云原生、AI等相关技术


引用和评论

0 条评论