新钛云服已为您服务930

本文从两部分介绍docker和containered的区别,第一部分介绍OCI、CRI、CNI,并且了解“容器运行时”一词。第二部分介绍了经典的容器运行时。第三部分docker和containered对比,通过上面三部分的介绍来发现docker和containered的相同和不同。

第一部分:基础

开放容器倡议

开放容器倡议(OCI)由Docker,CoreOS和其他机构于2015年成立,其使命是围绕容器格式和运行时创建开放的行业标准。

如果容器运行时符合OCI,则表示它实现了OCI定义的规范:即image-spec和runtime-spec。前者定义了一种可互操作的格式来构建,传输和准备要运行的容器镜像。

后者描述了正在运行的容器的生命周期,以及执行该容器的工具必须如何操作并与其交互。

容器运行时接口

在Kubernetes 1.5版本中引入了容器运行时接口(CRI)。在此发行版之前,负责运行容器的kubelet(每个Kubernetes节点的管理实例)和运行时是交织在一起的。这导致大量的实现工作,因为Kubernetes支持的容器运行时的清单正在(并且仍在)增长。

借助CRI,Kubernetes开发人员创建了一个定义明确的接口来针对其开发容器运行时。如果某个容器运行时实现了CRI,则可以将其与Kubernetes一起使用。

容器网络接口

在此基础部分中,我们最后的三个字母的缩写是:容器网络接口(CNI)。它属于CNCF(云原生计算基金会),定义了如何实现容器之间以及容器与其主机之间的连接。

CNI与容器本身的属性或体系结构无关,这使其专注于小范围且易于实现。致力于该项目的CNI的组织和企业的清单对此声明提供了支持:Kubernetes,OpenShift,Cloud Foundry,Amazon ECS,Calico和Weave等。

“容器运行时”的歧义

到目前为止,已经使用了很多术语“容器运行时”。它会贯穿整个过程。一方面,有一些底层容器运行时实际上可以运行一个容器。这些可能会实现OCI运行时规范。

另一方面,有一些高级容器运行时捆绑了许多其他功能。考虑构建和解压缩镜像,保存和共享镜像,并提供用于交互的CLI。

这些高级和低级容器运行时的定义不是标准化的,但是在对不同项目进行分类时会有所帮助。就像看到的那样,高级运行时通常包含低级运行时,否则它们是独立的项目。

总体来说:容器项目应使其符合OCI,CRI和CNI的要求。这些是容器化的主要标准,并塑造了云和容器本地应用程序的发展。

第二部分:经典容器运行时

经典容器运行时如何应用于现实世界以及那里有哪些运行时。从所有容器都使用通常称为容器化的技术开始,我将以经典的容器运行时开始,使用通用主机,并使用namespaces和cgroups之类的Linux工具分隔容器。

Docker

从Docker开始,因为它是大多数人都知道的容器运行时。实际上,我认为Docker从Kleenex效应中获利,该效应使品牌名称通用化在这种情况下,有些人倾向于认为Docker等于container。

事实并非如此,这只是较早的著名容器解决方案之一。Docker于2013年首次面世时,它是一款单片软件,具有高级容器运行时的所有特质。

随着个人以及像Docker Inc.这样的公司推动标准化工作,Docker生态系统发生了变化。在独立项目中,某些功能已分离和外包,容器化成为用于镜像管理的新的高级守护程序,runc成为新的低层容器运行时。无论何时使用Docker,实际上都在使用一个由docker守护程序组成的堆栈,该守护程序对容器化进行调用,而容器化又调用了runc。

有人认为没有必要完全使用Docker。因为这只会增加一个额外的步骤,因此会给容器管理带来不稳定。对于Kubernetes,差异如图1所示。

图1:在Kubernetes上下文中的Docker与容器。dockershim和cri-containerd实现通过来回转换调用使各自的API符合CRI。

containerd

containerd是独立的高级容器运行时,能够推送和拉取镜像,管理存储并定义网络功能。通过将相应的命令传递给像runc这样的低级容器运行时,它也能够管理正在运行的容器的生命周期。

可以使用ctr(用于与容器通信的准系统CLI)在本地设置中直接与容器通信。在Kubernetes中,已经了解了容器如何使用cri-containerd实现来替换基于Docker的设置。此外,容器化满足镜像和运行时的OCI规范(同样以低级运行时的形式)。

通过Kubernetes Runtime Class,可以将容器化作为集群中的中央高级容器运行时使用,但可以根据要求(性能和速度与安全性和分离性)使用多个低级容器运行时。如图2所示,这种基于插件的场景无法使用之前看到的dockershim来实现。

图2:容器化允许使用多个低级容器运行时,这些运行时可以根据特定应用程序的需求在Kubernetes中互换使用。

Runc

之前提到过,OCI还为其规范提供了一些参考实现。runc是其中之一,其目标是严格遵守OCI运行时规范。最初,runc从Docker项目诞生(其前身为libcontainer),并捐赠给OCI,此后一直由OCI负责。

由于runc的范围仅专注于管理运行中的容器,因此runc可以被视为低级容器运行时。它使用上述namespaces和cgroups提供隔离。

如果要在本地使用runc,则必须获取OCI容器镜像-这可以通过Dockers export命令来实现。导出镜像并为容器创建基本规范后,可以直接使用runc而不是Docker来运行镜像。

需要更强的分离

许多现实世界中的设置都依赖于多租户,这意味着许多潜在的不受信任的应用程序在Kubernetes集群中的容器中并排运行。要求即使一个应用程序被盗用,应用程序仍必须安全且可以正常运行。

可能已经听说过容器逃逸漏洞,例如CVE 2019-5736,这些漏洞使攻击者具有对主机的根访问权限。这也可能给不同租户运行的其他应用程序带来灾难性的后果,这就是为什么我们现在要研究使用类似于VM的分隔的替代方案的原因。

CRI-O

CRI-O(或crio)主要实现CRI。它是专门为Kubernetes开发的轻量级容器运行时。它可以与任何OCI运行时兼容的软件一起使用,例如runc。因此,原则上,它充当Kubernetes与选择的各种运行时之间的万能中介。

这意味着可以结合不同的解决方案而真正发挥创意:例如,runc遵循OCI标准,因此可以使用CRI-O代替建议的容器式工作流程。但是请注意:并非理论上所有可能的事情都应该这么做。如前所述,额外的步骤会增加不稳定性,这是从越来越多的Kubernetes设置中淘汰Docker的主要原因之一。

第三部分:Docker和Containered的比较

通过上面相关的概述,我想提一个论点:不一定总是Docker。而且,Docker不是Docker,而是一堆独立的部件,可以与许多其他的项目结合使用。通过docker和containered的对比,可以发现:

· 无论您使用的是Docker还是containered,runc都会启动并管理它们的实际容器。

· CRI-O将Kubernetes的容器运行时接口映射到OCI运行时规范。这能够在集群中创建各种各样的运行时组合。

常见命令对比

containerd不支持docker API和docker CLI,可以通过cri-tool实现类似的功能。

镜像相关功能对比

容器相关功能对比

POD相关功能对比

总体来说,Docker、Containerd和CRI-O都有各自的空间,并且都可以使Kubernetes在启动和维护Pod时受益。可以看到这三个在最低级别上依赖runC来处理容器的运行。

了解新钛云服

当IPFS遇见云服务|新钛云服与冰河分布式实验室达成战略协议

新钛云服正式获批工信部ISP/IDC(含互联网资源协作)牌照

深耕专业,矗立鳌头,新钛云服获千万Pre-A轮融资

新钛云服,打造最专业的Cloud MSP+,做企业业务和云之间的桥梁

新钛云服一周年,完成两轮融资,服务五十多家客户

上海某仓储物流电子商务公司混合云解决方案

往期技术干货

低代码开发,全民开发,淘汰职业程序员!

国内主流公有云VPC使用对比及总结

万字长文:云架构设计原则|附PDF下载

刚刚,OpenStack 第 19 个版本来了,附28项特性详细解读!

Ceph OSD故障排除|万字经验总结

七个用于Docker和Kubernetes防护的安全工具

运维人的终身成长,从清单管理开始|万字长文!

OpenStack与ZStack深度对比:架构、部署、计算存储与网络、运维监控等

什么是云原生?

IT混合云战略:是什么、为什么,如何构建?

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐