[聚合文章] 函数与容器

软件架构 2017-12-10 22 阅读

【编者的话】Chad Arimura是Iron.io公司的前创始人和CEO,现在是Oracle的软件开发副总裁,也是一个程序员。他在这篇文章中从多个维度将目前炙手可热的函数与容器做了对比以及进一步的阐述。

容器和函数现在“非常热”,但是两者之间的区别究竟是什么? 我最近一直在谈这个话题,很明显,这里没有简单的答案。 在这篇文章中,我会尝试回答这个问题,并且至少我们可以推进这个话题,以便更好地理解容器和函数是如何相互关联的。 让我们从一些宽泛的定义开始:

定义

容器:按照Docker的网站所说的:“容器镜像是一个轻量级的、独立的、可执行的软件包,包括运行所需的所有东西:代码、运行时、系统工具、系统库和环境设置。”

函数:函数是代码块,在理想的情况下是小而单一用途的。 在Serverless的上下文环境中,它们由函数即服务(FaaS)平台协调和调度,这些平台包括诸如 AWS LambdaAzure FunctionsGoogle Cloud Functions 之类的商业服务或者一些开源项目比如 Fn项目 (我们的项目)、 OpenWhiskOpenFaas

Serverless:软件设计的一种分类,针对开发人员的抽象层位于应用程序层,高于操作系统、基础设施和云IaaS API。 换句话说,开发人员不需要考虑底层基础设施。

最早参与这个游戏的FaaS参与者(Lambda、Azure、Google和OpenWhisk)为用户提供了一个API或GUI来上传代码。 这里没有暴露的容器,因此用户会受到预编译环境和不太理想的依赖管理和构建系统的约束。 由Kelsey Hightower发起的一个有趣的 Twitter thread 凸显了这个模型的当前状态。

包括 Fn (我们的项目)在内的新一代框架是“容器原生”的,这意味着Docker容器是一等公民,任何镜像本身都可以作为函数使用。

这是混乱的症结所在——如果函数是一个容器,而容器也是一个函数,它们实际上是不同的吗? 此外,如果您只需在Cloud Foundry或Kubernetes等平台上运行容器,FaaS系统的价值是什么? IBM的 Max博士 把这个问题提到了我在DockerCon Europe上的一个小组。 那时我决定尝试回答这个问题。

函数 < 容器

一个容器可以包含任何东西,从Web服务到百万代码行的单体应用,或者到一个完整的数据库管理系统,以及到数据库管理系统写入的数据层。 这些容器可以永久存在,横向(或不横向)扩展,20分钟启动,运行20天等等。

我们将其与通常具有一组已知特性的函数进行对比:

1. 短时间运行: 函数运行很短的时间,然后进程就结束了。 这个“短”当然是主观的,但假设我们正在讲话5分钟甚至更少。

2. 转瞬即逝: 运行该函数的外部容器可能只能用于该函数的单次调用。

3. 无状态: 函数本身不持有任何状态。 所有状态必须推送到结构化或非结构化存储中。

4. 调用: 通过HTTP、TCP或其他协议定义的事件调用函数。

5. 单一意图: 函数通过最小化的API公开接口具有清晰和明确的意图,这意味着他们需要合理的短输入,并提供合理的短输出。

6. 自包含: 一个函数可以运行并且为其自身的意图提供服务。尽管一个函数可能只是更广泛的函数组的一部分(例如,许多函数创建一个API,一系列函数创建一个“流”),它本身可以独立运行,只要它获得所需的输入即可。 [感谢 Tobias Kunze 的命名建议]

现在,如果我们将这些特性与函数结合起来,并将其打包到一个容器中,那么我们现在就可以对这个容器进行不同的思考和推理,从而给出一个强大的概念——一个新的计算原子单元。

计算原子单元

在核心层面,封装在容器中的函数为我们提供了一个新的“计算原子单元”。 我们可以从我们理解的构建模块的角度思考和讨论我们的软件,比如镜像处理函数,情感分析函数等等。 我们可以共享和扩展这些函数,也可以构建复合的应用程序。 建立原子单元使我们能够搭建等价于分子和复杂生物体的软件。

我们不仅获得了这个计算的原子单元,而且还继承了容器本身的所有好处,例如标准化的打包格式、运行时、存储和传输等等。此外,平台和工具可以是为这个新的计算原子单元所专门特地构建的。这就在函数和Serverless计算的基础上搭建了一个生气勃勃的生态系统,这也是容器隐喻在第一时间所代表的。

现在让我们将这个原子单元用于一些对软件开发非常重要的概念。

函数作为扩展单元

大多数软件都是为了扩展到许多用户而构建的。 过去一直是纵向扩展(性能更强的机器),现在是横向扩展(更多的机器),并且我们可以比机器更细粒度的精度来做到这一点,我们可以一个单独进程的精度来做纵向/横向扩展。 这里没有函数调用,不需要容器,不需要机器,只需重新调整它们来执行其他操作。 许多函数调用,使用免费资源来启动容器。 这是一个简化的视图,但函数的特性加上容器的通用打包/运行时机制,使我们能够更有效地扩展我们的应用程序。

函数作为计费单元

“Serverless”的计费模式是一个令人兴奋的提升。 现在,我们可以更细粒度地地付出一个特定函数所消耗的时间——有时候是毫秒级的,而不是运行服务或者虚拟机所需的几天、几月或者几年。 这样可以降低那些只是轻度使用的应用程序的成本,在市场上更便宜地迭代测试应用程序功能。

函数作为设计单元

设计是我可以想出的最好的词来描述我认为的“SOA的未来”。 使用自己的契约来封装在容器中的函数应该是天然可共享的,这样复合的应用程序可以被构建和重用。 这也需要函数编排工具,这也是我们正在用 Fn Flow 解决的问题。

接下来是什么?

好吧,我已经做了我一直想做的事情,就容器,函数,无服务器和原子单元这些议题发表了这篇文章。 我希望这有助于把我们从有分歧的争论转移到拥抱这些组合上来。 我也觉得讨论这个话题有些筋疲力尽了,但是我不得不再次生活在一个谈论Serverless计算的一群人当中。

我将继续讨论高层次的Serverless,但是也会越来越多地开始关注如何引入架构和 早期的优势 ,以及更多类型的应用程序,甚至更复杂的应用程序。 我们有点卡在触发器上面,可以理解为是事件驱动的性质,所以我们还需要技术演进。

接下来会有更多内容。。。关于该主题的预览,请查看Fn Project博客上的 Flow 101Serverless Sagas 博客文章。

原文链接: Functions vs Containers (翻译:胡震)

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。