1.6.3 Serverless
继从虚拟机发展到容器之后,我们可以进一步抽象基础设施,这就是Serverless技术。借助该计算模型,开发人员只须关注应用的业务逻辑实现即可。
Serverless这个名字可能会有一定误导性:当然,服务器是存在的。不同的是,既不是我们在管理它,也不是由我们将应用部署编排到对应的服务器上。现在,这变成了平台的责任。当使用像Kubernetes这样的编排器时,我们依然需要考虑基础设施供应、容量规划和扩展的问题。而Serverless平台会负责搭建应用所需的底层基础设施,包括虚拟机、容器和动态扩展。
Serverless架构通常会与函数关联,但是它们包含两种经常一起使用的主要模型。
■ 后端即服务(Backend as a Service,BaaS):在这种模型中,应用严重依赖于云供应商提供的第三方服务,比如数据库、认证服务和消息队列。它的关注点在于减少后端服务相关的开发和运维成本。开发人员可以只实现前端应用(比如单页应用或移动应用),而将大部分甚至全部的后端功能转移至BaaS供应商。例如,可以使用Okta来认证用户,使用Google Firebase来持久化数据,并使用Amazon API Gateway来发布和管理REST API。
■ 函数即服务(Function as a Service,FaaS):在这种模型中,应用是无状态的,由事件触发并且完全由平台来管理。它的关注点在于减少编排和扩展应用相关的部署和运维成本。开发人员只须实现应用的业务逻辑,平台负责处理其他内容。Serverless应用并非必须要以函数的方式来实现并归类。目前主要有两种FaaS方案。第一种是特定供应商的FaaS平台,比如AWS Lambda、Azure Functions或Google Cloud Functions。另一种方案是选择基于开源项目的Serverless平台,它们可以运行在公有云或内建基础设施上,从而解决供应商锁定和缺乏控制的问题。这种项目的样例是Knative和Apache Open- Whisk。Knative在Kubernetes之上提供了一个Serverless运行时环境,我们会在第16章对其进行介绍。它被用来作为一些企业级Serverless平台的基础,包括VMware Tanzu Application Platform、RedHat OpenShift Serverless和Google Cloud Run。
Serverless应用一般是事件驱动的,仅在有事件(比如HTTP请求或消息)需要处理的时候才会运行。事件可以是外部的,也可以是由另一个函数生成的。例如,当一个消息添加到队列中时,某个函数可能会被触发,该函数处理事件,然后退出执行。
当没有任何要处理的事件时,Serverless平台就会关闭所有与该函数相关的资源,因此,我们可以真正为实际使用付费。在其他云原生拓扑结构中,如CaaS或PaaS,总会有一台服务器在7×24小时运行。与传统系统相比,它们提供了动态可扩展性的优势,以减少任意时刻资源供应的数量。不过,总会有一些资源在始终运行,这也是有成本的。而在Serverless模型中,只有在必要时才会供应资源。如果没有要处理的事件,所有的资源都会被关闭。这就是我们所说的伸缩至零(scaling to zero),这是Serverless平台提供的主要特性之一。
除了成本优化,Serverless技术还将一些额外的职责从应用转移到了平台中。这可能是一个优势,因为它能让开发人员完全专注于业务逻辑。但同样重要的是,我们必须要考虑控制权,以及如何处理供应商锁定的问题。
每个FaaS以及通用的Serverless平台都有自己的特性和API。一旦我们开始为某个特定的平台编写函数,就无法轻易地将它们转移到另一个平台上了,而对于容器,我们是能够实现这一点的。与其他方式相比,FaaS是以在控制权和可移植性方面的妥协换取职责方面的收益。这也是Knative得以迅速流行起来的原因,它构建在Kubernetes之上,这意味着我们可以很容易地在平台和供应商之间转移Serverless工作负载。归根到底,这就是一种权衡。