无服务器计算和容器是用来减少云托管应用开销的两种架构。不过它们在许多重要的方面都有所不同。容器比虚拟机“轻”,而无服务器部署比容器更“轻”,并且更容易扩展。在本文中,我们将和您讨论无服务器计算和容器之间的区别,以及该如何进行选择。
无服务器
在传统的应用开发实践中,为了将程序部署到服务器上,以供用户使用,我们往往需要经历规划容量,采购硬件,安装软件,以及准备应用等环节。这些通常需要一周到几个月的时间。再加上应用的初期运营,这可谓既耗时又费力。
随着按需使用的云服务广泛流行,我们解决问题的能力逐渐增强。虽然资本性支出(CAPEX)和运营性支持(OPEX)仍会产生成本,但是我们在容量规划、部署时间、以及硬件管理上的花销将大幅减少。其中,最典型的云计算应用便是无服务器。
无服务器可以被定义为一种方法。该方法用短暂的计算能力代替了长时间运行的计算提供机制。此类临时计算力只是按需而存在的,并且会在使用完毕后立即消失。
当然,无服务器并不意味着真的没有服务器,而是我们不需要管理服务器。也就是说,由于我们在由AWS、Google或Azure等云计算供应商,所提供的硬件上运行自己的服务,因此,我们将服务器的维护委托给了第三方(通常是云计算供应商),由它们根据需求将资源分配到服务器上,以便我们专注于开发运行所需的服务。
实际上,无服务器计算是一种执行模型。在该模型中,硬件是由云计算供应商管理的。无服务器无需预定义的硬件,只要在执行时触发和获取硬件资源,并在执行完成后停止已获取的硬件,直到触发另一个动作为止。例如,某个内容管理应用可以让用户将图像上传到自己撰写的文章中。如果我们处于使用了AWS Lambda来构建的无服务器架构中,那么图像将首先被上传到S3存储桶处,并触发一个事件。该触发器会调用一个用多种编程语言编写的AWS Lambda函数,来调整图像的大小,并对其进行压缩,以适合多种设备的显示。可见,由触发事件调用的AWS Lambda代码或功能,会在云计算提供商所提供的硬件上执行。完毕后该硬件会处于停止状态,并等待其他的触发器。
功能即服务(Faas)
为了能够动态创建和管理服务器,开发人员需要以功能函数的形式编写应用代码。也就是说,根据无服务器计算的Faas概念,软件开发人员可以无需编写基础架构的代码,而只专注于编写和部署那些单独的、能够在毫秒内处理请求的各种功能、操作、以及业务逻辑。而让云计算提供商调配与管理服务器,以及代为执行的功能代码。
值得注意的是:在部署功能时,我们需要以一种事件的形式来进行调用。该事件可以是来自API网关(HTTP请求)的任何时间、另一个无服务器功能的事件、或是S3之类另一个云计算的事件。
无服务器提供商
目前,大多数主流云计算提供商都拥有自己的无服务器产品。其中,AWS Lambda于2014年率先推出了首款成熟的无服务器框架。它不但支持诸如Node.js、Java、Python和C#等多种编程语言,而且能与许多其他AWS服务相集成。
当然,您也可以选用Google Cloud Functions、Microsoft的Azure功能、IBM的OpenWhisk(开源的无服务器平台),以及Iron.io和Webtask等。
无服务器的优缺点
我们首先来看看无服务器能够为开发人员提供的优点:
- 按使用付费:由于我们仅为那些在服务器上执行代码的时间付费,因此那些空闲的服务器时间是不计费的。
- 弹性:利用无服务器架构,应用程序可以自动扩展,以适应流量的激增,并在用户较少的情况下自行缩减。
- 花费在管理上的时间和费用更少:正是由于云计算接手了基础架构,以及服务的缩放,因此用户不但能够花费更少的时间与资源,还能够专注于自身的业务。
- 减少开发并缩短上市的时间:开发人员和组织拥有更多的时间来专注于构建产品,并将其发布到市场上;云计算供应商则负责保护与修补操作系统。
- 微服务方法:通过微服务方法,开发人员可以构建出模块化、功能专一、且松耦合的软件。此类软件比整体应用要更加灵活、且更易于管理。
当然,无服务器计算也存在着如下缺点:
- 供应商锁定和透明度降低:这是向云端无服务器迁移的主要问题之一。由于后端完全由云计算供应商进行管理,一旦我们将现有的功能移至其他云服务平台,则会导致应用程序的重大更改。此类更改不仅仅是代码层面上的,那些与之关联的数据库、访问管理、存储等其他服务,也会涉及到向其他平台的移植和更改的问题。
- 支持的编程语言:由于特定功能需用相应的语言编写,因此它无法支持所有的语言。例如:AWS Lambda只直接支持Java、C#、Python和Node.js(JavaScript),Google Cloud Functions只与Node.js配合使用,Microsoft Azure Functions与JavaScript、C#、F#、Python和PHP配合使用,而IBM OpenWhisk只支持JavaScript、Python、Java和Swift。
- 不适合需要长时间运行的任务:由于此类功能在本质上是基于事件的,因此它们不太适合长时间运行的任务。例如:Lambda的超时限制为15分钟。而在其他无服务器平台上,时限为9分钟到60分钟不等。在实际应用场景中,长时间运行的流程用例有许多种,例如:视频处理、大数据分析、批量数据转换、批处理事件、长期同步的请求和统计计算等。显然,这些情况都不太适合无服务器计算。
- 难以调试:仅部分工具可以进行远程调试,而像Azure之类的服务仅提供镜像的本地开发环境。
- 隐藏成本:功能调用的自动缩放往往意味着成本的自动缩放。而这可能会使您难以衡量自己的业务成本。
- 需要更好的工具:为了跟踪已部署的大量功能,我们往往需要借助一些更好的工具,例如:针对开发的脚本、框架;针对诊断的逐步调试、本地运行时;以及针对云端调试和可视化的用户界面、分析和监控。
- 响应应用事件延迟的较高:由于硬件在相当长的一段时间内处于空闲状态,并且功能仅在触发时运行,因此服务器可能需要一段时间才能唤醒并提供功能服务。
- 学习曲线:我们需要将传统的整体应用转换为微服务,再将其编写为功能。这些都需要我们深入了解架构及其工作原理。
容器
容器是操作系统虚拟化的一种方法,可以让用户在资源隔离的进程中,运行某个应用程序及其依赖项。其中,容器包含了应用程序及其需要正常运行的所有依赖项,即:系统库、系统设置和其他文件。因此,无论在何处托管的应用,容器化应用都能够以相同的方式运行在容器中。
软件从一个计算环境轻松地转移和部署到另一个计算环境时,容器能够保障其可靠地运行。这种转移既可能是从开发人员的笔记本电脑到测试环境,也可能是从过渡环境到生产环境,还可能是从数据中心的物理机到私有或公共云中的虚拟机。
由于容器需要硬件才能运行,因此构建硬件并在其上部署容器便是我们的责任。具体说来,容器会通过在机器上划分出单独的用户空间,以便在每个环境中仅运行一个应用。而多个用户空间环境则可以共享主机的内核与硬件。也就是说,主机的内核将负责为容器提供必要的内存、CPU和其他硬件。
容器使您可以轻松地将应用代码、配置和依赖项,打包到那些易用的构建块中,以提高环境的一致性、运营效率、开发人员生产力、以及版本控制。容器可以对资源进行精细化的控制,从而提高整体架构的效率。
容器的优点
- 增强的可移植性:容器的主要优点是,我们可以将应用程序及其所有依赖项,组合到一个小的程序包中,以便在任何地方运行。这种灵活性和可移植性,方便了应用被轻松地部署到多个不同的操作系统和硬件平台上。
- 与供应商无关:容器并不依赖于某个云计算供应商。我们创建好基本应用和依赖项的映像后,便可在任何地方运行它们。
- 完全控制应用程序:由于团队负责打包应用程序及其依赖项,因此他们拥有完全的控制权。
- 大型和复杂的应用:我们可以将大型且复杂的应用打包,并在容器中运行。
- 可扩展性:在我们的控制下,容器可以根据其基础架构,进行最大程度的扩展。
- 安全灵活性:在设置策略、管理资源和安全性方面,我们对容器具有完全的灵活性和控制能力。
- 更少的开销:由于不包含任何操作系统的镜像,因此容器比传统的硬件或虚拟机环境需要更少的系统资源。
- 一致性的操作:无论它们被部署在何处,DevOps团队总能确保应用程序在容器中的相同位置运行。
- 更高的效率:容器使应用程序可以更快地进行部署、修补或扩展。
容器的缺点
- 性能开销:容器不会以裸机(bare-metal)的速度运行。虽然容器比虚拟机更能有效地利用资源,但是鉴于其覆盖的网络,容器与主机系统之间的接口,因此它仍然会产生性能开销。
- 不支持图形界面:Docker容器被设计为,可用于部署无需图形界面的服务器应用解决方案。虽然我们可以使用诸如X11视频转发之类创造性策略,在容器内运行GUI应用程序,但是这些方案并不太好用。
- 管理:我们通过管理容器和配置来完成工作,但是如果没有协调工具,我们将难以轻松地管理容器的扩展。
- 安全性:安全性是容器的最大问题。由于容器没有内核,因此它需要通过主机的内核,来进行硬件通信。如果容器内运行的应用存在缺陷,则会产生安全漏洞。
- 并非所有应用都能受益:通常,只有那些被作为一组离散微服务运行的应用,才能从容器模式中获益。
- 监控:随着应用的发展,越来越多的容器会被添加进来。而我们很难合理监控这些高度分散且持续变化的容器。
- 减慢开发进程:在每次更改代码库时,我们都需要打包容器,并确保所有容器在部署到生产环境之前都能够正确地通信。同时,我们也需要通过频繁的安全修复、以及其他修补程序,使容器的操作系统能够保持最新。
无服务器与容器
无服务器和容器纵然有着许多共同点,下面我们来看看它们之间的主要区别:
- 服务器空间:由于无服务器计算实际上是运行在服务器上,因此它需要云计算供应商决定是否需要供应和调整服务器空间,而不会为特定的功能或应用分配特定的机器。而容器则位于预先配置、并准备就绪的机器上。
- 部署:在无服务器计算中,部署并运行某项功能是由云计算供应商负责的。每当某个功能需要被触发并执行时,它会被部署到供应商的已知服务器上。而在容器中,开发人员需要负责部署容器,并使容器保持运行的状态。
- 弹性:供应商会根据负载,考虑在无服务器中扩展对应的功能。而对于容器的扩展,则需要通过增加容器数量,来进行人动干预。随着容器编排(orchestration)平台的引入,诸如kubernetes之类编排引擎会自动根据负载的增加扩展容器。
- 按使用付费:无服务器的优势是价格。在触发功能时,我们只需支付执行该功能所需的时间和资源。而容器需要持续处于正常运行状态,因此费用往往更高。
- 维护:在无服务器架构中,开发团队无需管理后端,而由供应商负责对运行代码的服务器进行管理和软件更新。在容器方面,开发团队有责任保持硬件的更新、修补和维护。
- 测试:由于很难在本地计算机上复制后端环境,因此我们很难在本地测试无服务器的功能。而无论容器被部署在何处,它都可以在本地计算机上被轻松地测试和运行。
- 扩展的成本:容器技术能够按需扩展应用。而无服务器有时可能会面临空间和内存限制。
- 缓慢地扩展:无服务器的扩展是由供应商完成的,而容器的扩展则由应用开发团队来负责和定义。因此与无服务器相比,容器的扩展速度较慢。
- 支持编程语言:无服务器无法支持所有的编程语言。而我们可以使用任何编程语言来构建容器。我们只需编写代码,与资源库一起打包,并在容器中运行即可。
- 长时间运行的任务:如前所述,无服务器计算不太适合长时间运行的任务。而容器则可以运行任何类型的应用程序或任务。
- 开发时间:使用无服务器,我们只需考虑编写代码,其余部分都将由供应商来负责。而容器则涉及到诸如构建映像、移植等其他工作。
- 监控:供应商通过工具,来监控无服务器各项功能的执行、以及响应时间等。而在容器中,开发团队需要通过安装监控工具,来捕获各种详细的信息。
选择哪种架构?
总的说来,无服务器和容器并不构成竞争关系,它们同属云计算动态架构,都可根据不同的需求,用于部署微服务。
何时该使用容器?
容器最适合用于运行较长的流程。在这些流程中,您需要对环境进行高度控制,并且拥有足够的资源来设置和维护应用程序。同时,云容器也是迁移单体式传统式(monolithic legacy)应用的最佳方法。我们可以将这些应用分解成为容器化的微服务,然后使用kubernetes或swarm等引擎进行编排(orchestrate)。
何时使用无服务器?
无服务器适合于那些按需执行,却无需维持任务运行的应用程序。当团队关注的是开发速度和成本最小化,而并非管理扩展性和架构问题时,无服务器是理想的选择。
简而言之,当您需要灵活性或迁移旧服务时,请选择容器和容器编排。当您注重开发速度、自动扩展、并要显着降低运行时成本时,请选择无服务器。
无服务器和容器能协同工作吗?
毫无疑问,无服务器和容器是可以协同工作的。两者互为补充。我们可以使用基于容器的微服务架构,来构建大型、复杂的应用程序,并处理诸如数据传输、文件备份、触发无服务器功能警报等后端任务。
值得一提的是,Fargate是一种适用于Amazon ECS(Elastic Container Service)和EKS(Elastic Kubernetes Service)的计算引擎,它使我们能够运行容器,而无需管理服务器。Fargate有效地将容器的便携性,以及无服务器的灵活性与易用性相结合。您可以在无需添加、配置或扩展虚拟服务器的情况下运行容器。
原标题:Serverless Computing vs Containers: How to Choose,作者:Jagadish Manchala