Container Runtime (一) :介绍

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

  • 容器运行时介绍:为何它们使人如此困惑?
  • 深刻Low-Level 运行时
  • 深刻High-Level 运行时
  • Kubernetes运行时和CRIdocker

    这篇文章将会介绍容器运行时是什么和为何会让人如此困惑,而后深刻介容器运行时不一样的类型,它们是如何工做的以及它们之间的不一样点。网络

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

为何容器让人如此困惑?

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

  • 容器镜像格式
  • 构建镜像的方法(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容器的时候,它们实际上通过了如下的步骤:spa

  • 下载镜像
  • 将镜像文件解开为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.pngcode

所以,从实际出发,一般只专一于正在运行的容器的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,可是它们是大相径庭的项目,支持的特性也是很是不一样的。内存