本文转自绿盟科技研究通讯公众号 《Serverless安全研究 — Serverless概述》
一. 背景定义
从“硬件”到“Serverless”的变革之路
在“云”的概念还没有产生之前,开发者购买物理机,并在其上部署应用程序,企业将购买的机器放置数据中心,其网络、安全配置均需要专业的技术人员管理,在这种高成本运营模式下,虚拟化技术应运而生。
首先映入眼帘的是虚拟机,依托物理机的网络、计算、存储能力,一台物理机上可运行多个虚拟机,因此很大程度上提升了资源利用率。在虚拟机成为当时的主流后,供应商想到了以编程的方式租用物理机,通过服务器池释放更大的灵活性,这些也渐渐成为了往后IaaS的基础。在2006年8月,由AWS推出的EC2(Elastic Compute Cloud)为IaaS开辟了先河,引领了公有云的迅速发展,随后Microsoft、Google、阿里等厂商也紧追步伐并占据了一定的公有云市场份额,与此同时,私有云也渐渐浮出水面,其中不乏像OpenStack这样优秀的跨时代开源平台。
IaaS让开发者可以按需购买服务器资源,并灵活的部署应用程序,为开发者带来了便利,但针对服务器上操作系统的安装、升级、打补丁、监控等仍需开发者管理和维护。作为开发者来讲,最终目的往往是成功的部署应用,对于服务器的维护通常不应视为必须,为了解决这个难题,PaaS技术出现了,其运行在IaaS之上并抽象掉了硬件和操作系统细节,为应用程序提供了部署平台,让开发者只需关注自己的应用程序。 Openshift、CloudFoundry开源PaaS框架在早期一度独领风骚,后来随着容器技术的崛起, CaaS(Container as a Service)的概念被人提出,凭借容器轻量级、移植性强、快速部署的特点,企业渐渐将应用程序由虚拟机迁移至容器环境中部署,并将容器托管至公有云平台或使用开源容器编排工具Kubernetes来管理容器。
经历了IaaS、PaaS、CaaS之后,开发者虽然已经远离物理机运行应用程序的模式,但仍然非常依赖物理机的CPU、内存、存储、网络或其它组件,即便在使用Kubernetes管理容器时,开发者也需要为容器运行时指定硬件要求,如果管理不当,将无法做适当扩展[7]。是否有一种模式,可让开发者不对服务器进行管理,在需要运行应用时服务器启动,不需要时将其关闭,从而可减轻开发者的负担并专注于自己的应用实现呢?2012年,Serverless的概念由云基础施服务提供商Iron.io的副总裁Ken Fromm在《Why the future of software and apps is serverless》[1]首次提出,Serverless是一种新的云计算模式,它并不是不需要服务器,而是不需要开发者去管理服务器,其责任划分模式为云厂商提供对服务器的全面托管,开发者只需专注于应用程序设计,并按应用程序的执行次数向云厂商付费。
目前公有云Serverless使用最为广泛的为AWS Lambda,从2014年推出至今依然保持着非常高的热度,除了AWS Lambda外,Google Cloud Functions、Miscrosoft Azure、IBM Cloud Functions也相继推出了FaaS平台。国内市场上,腾讯[8]、阿里[9]、华为[10]这些大厂也紧追Serverless的步伐并各自推出了云函数解决方案。
另一方面,Serverless技术也驱动了许多开源FaaS平台的产生,按照Github上的热度,排名不分先后,目前主要以OpenFaaS、Fission、OpenWhisk、Knative、Kubeless为代表, 值得注意的是,随着云原生概念的普及和Serverless自身的特点,这些开源FaaS平台中绝大多数都支持在Kubernetes上进行部署。针对这些开源工具笔者也会在后续的Serverless系列文章中为大家带来解读。
下面笔者将介绍Serverless的具体含义及其优缺点。
二. Serverless定义
2016年8月,martinfowler.com网站上发表的《Serverless》[2] 一文中对Serverless概念做了详细阐述,简单来说,Serverless可以理解为以下内容:
Serverless可在不考虑服务器的情况下构建并运行应用程序和服务,它使开发者避免了基础设施管理,例如集群配置、漏洞修补、系统维护等。Serverless并非字面理解的不需要服务器,只是服务器均交由第三方管理。
Serverless通常可分为两种实现方式,BaaS(Backend as a Service)后端即服务和FaaS(Functions as a Service)函数即服务 [6]。
为了更清晰的理解BaaS和FaaS是什么,笔者下面将分别进行说明。
2.1 BaaS
开发者进行移动应用开发时,后端经常遇到一些重复、复杂、费时的工作,例如针对不同移动端的推送通知、社交网站登录等,BaaS的出现解决了这些难题,BaaS主要用于将后端复杂重复的逻辑外包给第三方处理,开发者只需编写和维护前端,所以BaaS是一种Serverless模式,下图为cloudflare提供BaaS示意图[11]:
可以看出BaaS供应商提供了各种服务端功能,例如数据库管理、远程更新、推送通知、云存储等,而前端完全由开发者管理,前后端通信问题通过BaaS提供的API解决。另外从上图也可以看出,BaaS提供的服务对前端是不可见的。
BaaS公司主要为移动应用开发者提供服务,目前比较知名的公司有 Back4App, Firebase, Backendless, Kinvey等。
BaaS与SaaS的区别
通过《BaaS vs SaaS: What’s the difference? 》[3]一文中笔者了解到两者区别主要体现为以下两点:
实现服务功能不同
BaaS应用程序致力于帮助开发者创建重复的代码功能,卖点多为特定的后端场景服务,而SaaS应用程序可以在各种场景下使用,卖点多为云软件,从实现功能层面看,SaaS更容易成为主流。
使用群体不同
BaaS专注于平台开发,是为开发人员设计的,而SaaS是为上层用户设计的,其提供的是现成的软件解决方案,所以两者的面向群体不一样。
2.2 FaaS
FaaS是Serverless主要的实现方式,开发者通过编写一段代码,并定义何时以及如何调用该函数,随后该函数在云厂商提供的服务端运行,全程开发者只需编写并维护一段功能代码即可。 另外,FaaS本质上是一种事件驱动并由消息触发的服务,事件类型可能是一个http请求,也可能是一次上传或保存操作,事件源与函数的关系如下图所示:
FaaS典型代表为AWS的lambda,为了便于理解,下述为一个简单的lambda python处理函数:
import json
def lambda_handler(event, context):
#TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
不难看出,这段代码导入了JSON python库并定义了一个lambda_handler函数,需要注意的是, 为了让lambda可以识别处理函数,通常函数名称需要遵循name_handler的格式,此外,该函数需接收两个参数,分别为event和context,其中event参数包含此函数收到的事件源信息,参数类型通常是python 的dict类型,也可以是list、str、int、float等类型,context参数包含此函数相关的运行时上下文信息。
下面两张图分别为传统的服务端应用部署和FaaS应用部署,我们看看FaaS有什么不同:
由图3可以看出,当应用程序部署在物理机、虚拟机、容器中时,它实际是一个系统进程,并且由许多不同的函数构成,这些函数之间有着相互关联的操作,一般需要长时间在操作系统中运行;图4可看出,FaaS通过抽离虚拟机实例和应用程序进程改变了传统的部署模式,使开发者只关注单个操作或功能,函数在第三方托管平台上运行,当有事件触发时执行,开发者为使用的资源进行付费。
三. Serverless优势
Serverless责任划分的原则实际已经帮助开发者降低了许多已知风险,这些都是Serverless为我们带来的优势,本节笔者将从成本、风险、应用扩展、交付时长四个方面对Serverless的优势进行说明。
3.1 降低成本
由于Serverless无需对服务端进行管理的特性,类似认证授权、系统升级、安全、进程监控、告警等操作几乎全托管至第三方云厂商,因此对于开发者来说就意味着更少量的运维工作。FaaS平台的运营模式就是一个很好的例子,当创建应用时,开发者只需向FaaS平台提供函数代码,对于函数对应的镜像构建、函数运行时、函数启停及应用的自动化扩展操作均不需要开发者参与,因此相比传统模式,时间、开发、运维成本都将大大降低。
另外,传统的应用程序部署在服务端,往往是非常浪费主机资源的,因为它始终在线,但实际应用程序在数天或数周中可能只会被调用几次,有一些闲置数个月的应用甚至连开发者都忘记曾经部署过,Serverless设计模式摆脱了这种资源浪费,让应用程序可以按需调用,因此又节省了资源成本。
3.2 降低风险
从安全角度而言,Serverless的设计模式实际上在一定程度上降低了安全风险。传统模式下,我们考虑安全架构设计覆盖方方面面,其中需要耗费极大的人力与时间成本,且需要专业的安全团队去处理,在Serverless中,服务端的安全完全可以交由第三方云厂商管理,而开发者只需确保自己上传的代码是安全的即可。
目前,公有云厂商在各自的Serverless解决方案中均配套了相应的安全服务,比如AWS的API网关可以作为函数调用前的过滤器,过滤掉DDoS、异常参数的恶意请求等,KMS(Key Management Service)服务可以创建并管理加密密钥,控制密钥在Serverless函数中的使用;开源的FaaS平台多选择在Kubernetes上部署也是依托其丰富的安全配置。
3.3 自动化弹性扩展
资源的自动化弹性伸缩是Serverless的一大特性,且由开发者管理,在需求量达到高峰时,可通过弹性伸缩自动增加实例数量以保证性能不受影响,在需求量较低时,又可自动减少实例数量以降低成本,相比传统的部署模式,开发者省去了手动部署的烦恼,变化的是开发者需要为增加的实例及调用频次支付相应费用。
3.4 降低交付时常
传统的应用交付模式需要开发人员与运维人员合力完成,其中开发周期长、人员沟通效率低下通常为阻碍交付进展的主要因素,随着容器技术的出现,DevOps和敏捷开发在一定程度上改善了这一问题,但对于缺乏经验的工程师仍需要几个月的时间去交付一个项目,Serverless的出现屏蔽了容器技术这一必要条件,让开发者只关注于函数代码实现,并且在数天之内就可以独立完成交付,Serverless的这一优势不仅大大降低了交付时长,还让交付这一本身复杂的事情变的更容易了。
四. Serverless局限性
每种新技术的出现都是为了让人类解决事情变得更简单,但凡事都具有两面性,Serverless的出现也必然伴随着一定的局限性,笔者将从Serverless自身架构模式和运行时局限性两方面进行说明。
4.1 固有局限性
虽然Serverless作为一种云计算模式应用非常广泛,但在使用场景上还是有一定的局限性,CNCF发布的Serverless白皮书v1.0版本中[4]对Serverless的使用场景进行了介绍,如下图所示:
由上图我们可以看出Serverless比较适用于异步并发、短暂、无状态的应用的场景,并且Serverless一直秉持着节约成本的原则,因此也适用于应对突发或服务使用量不可预测的场景。
下面笔者对Serverless固有局限性分别进行说明。
4.1.1 不适用于有状态服务
为了满足“云”的特点 — 灵活自行扩缩容,Serverless为无状态应用提供了运行平台,对于像数据库这种有状态的服务是不易在Serverless上部署的,即使部署成功也丧失了灵活性,因此
Serverless天然不适于部署有状态的应用。 目前针对Serverless函数涉及的数据存储主要通过公有云厂商各自的存储服务实现,比如AWS Lambda可将数据存储至S3、DynamoDB、Kinesis、SNS等服务中。
4.1.2 延迟高
传统的应用程序组件间通信可通过数据格式、网络协议、地理位置进行优化,但Serverless固有的设计模式使得应用程序天然具备高度分布式,低耦合的特征,这种模式下应用程序间如果涉及通信,必然会带来延迟,并且延迟会随应用程序的增加而增加。
4.1.3 本地测试受限
Serverless将许多基础设施从平台内部抽离出来,这种设计模式虽然给开发者减轻了服务端的工作量,但也同时增加了本地测试难度,尤其对于服务端的模拟常常是一件棘手的事情,另外Serverless分布式的特点也使应用程序的测试变得困难。
4.2 运行时局限性
FaaS平台作为Serverless的主要实现模式在运行时也具有一定的局限性,像冷启动、供应商锁定、开发和安全工具限制等等,笔者下面将对这些局限性进行介绍。
4.2.1 冷启动
目前,许多像AWS Lambda、Google Cloud Functions、Microsoft Azure Functions等FaaS平台都面临冷启动的问题,冷启动主要分两种,第一种是开发者将应用部署完成后,从某个函数进行第一次调用到该函数被执行期间的这段延迟,具体的讲,这段延迟主要指第三方云厂商将函数打包成镜像并运行为容器所花费的初始化时间;第二种是函数经历第一次调用后很长时间再次被调用时实例化所花费的时间;。
冷启动到底有多慢呢?各大云厂商均提供了各自官方的冷启动持续时间,虽然每家都声称自己很快,但为了准确性,笔者参照了国外一篇热度非常高的针对冷启动研究的文章《Comparison of Cold Starts in Serverless Functions across AWS, Azure, and GCP》[5], 其中作者通过对AWS Lambda, Azure Functions, Google Cloud Functions三家FaaS平台提供的常见语言冷启动时间进行了比较,其中颜色较暗范围为启动运行时花费时间,颜色较亮范围为总共持续时间如下图所示
可以看出,AWS Lambda以绝对优势领先于其它厂商,冷启动持续时间均低于1秒,Google Cloud Functions启动通常需要1至4秒,Azure Functions启动运行时时长与Google Cloud Functions几乎一样,但Azure Functions整体的冷启动时长较慢,平均下来也基本在8至9秒左右。
冷启动的快慢也与部署文件大小有着紧密联系,在《Comparison of Cold Starts in Serverless Functions across AWS, Azure, and GCP》文章中,作者通过增加部署文件的大小测试了冷启动延迟时间对比,如下图所示:
可以看出冷启动时间随部署文件大小的增加承稳步上升趋势,AWS Lambda同样在这次比较中以绝对优势获胜。
针对冷启动问题,各大云厂商都在积极应对。目前公有云FaaS平台通常的处理思路为函数被首次调用后,应用实例将保持一段时间的活动状态再被回收,这样优点是对后续请求可进行持续响应并减少不必要的冷启动,缺点是可能会造成一定的资源浪费,所以云厂商也试图在这两者之间做权衡。
4.2.2 供应商锁定
由于各大厂商均有各自的Serverless解决方案,且各自的基础架构组件都不一样,这样就会导致开发者在A供应商使用的Serverless功能可能无法平滑迁移至B供应商,例如开发者使用AWS Lambda,通过DynamoDB来处理数据,也许AWS Lambda和Microsoft Azure Functions之间区别不大,但是很难将Microsoft Azure Functions的东西迁移至AWS Lambda上,所以想要完成适配,就得需要一套标准,但该标准的建立非常难,因为可能需要对整个基础架构进行迁移,如果没有一个完美的理由或利益驱动,各大云厂商是很难达成共识的。
4.2.3 安全工具限制
所谓术业有专攻, 传统的应用程序在部署完成后有专业的Web应用防火墙,入侵检测及防护设备对其进行防护,但在Serverless中这些安全设备功能却因供应商锁定问题全部由云厂商实现了,第三方安全设备很难集成至服务端,所以开发者不得不依赖服务端的安全机制,这也是传统安全设备在Serverless环境中的局限性所在。
五. 总结
Serverless作为一种新的云计算模式,具有诸多优点,在过去几年积累了一大批拥簇者,在开发者享受新技术为其带来便利的同时也对实用性提出了新的要求和挑战,尤其在FaaS平台中,我们要清楚在这当中既有宝藏 — 良好的伸缩性和低成本;也有废墟— 本地调试和冷启动。
当然,技术也是不断进展的,面对Serverless现有的局限性,各大云厂商也在努力改进。例如,Serverless的监控能力在几年前较弱,如今各大云厂商已经有了各自的监控服务,AWS Lambda的CloudWatch,Azure Function的Azure Monitor ,Google Cloud Functions的Google Stackdriver等均受到了开发者的一致好评;而开源FaaS平台像Fission v1.0版本已支持Opentracing和Jaeger,Openfaas也启动了对Prometheus的支持。所以,有些瓶颈一定只是暂时的,不因噎废食是对新技术的态度。
行文至此,Serverless的概述已接近尾声,笔者后续还会为各位读者带来《Serverless安全威胁》及《Serverless安全防护》系列文章,希望可以引起大家对Serverless安全的思考。
六. 参考文献
- https://readwrite.com/2012/10/15/why-the-future-of-software-and-apps-is-serverless/
- https://martinfowler.com/bliki/Serverless.html
- https://medium.com/@george_51059/baas-vs-saas-whats-the-difference-back4app-blog-195f9b3d3e2#:~:text=BaaS%20is%20focused%20specifically%20on,a%20wide%20range%20of%20situations
- https://github.com/cncf/wg-serverless/raw/master/whitepapers/serverless-overview/cncf_serverless_whitepaper_v1.0.pdf
- https://mikhail.io/serverless/coldstarts/big3/
- https://mp.weixin.qq.com/s/hTi1HmYjYO3BN_hUwvEH0A
- OReilly Serverless Security
- https://cloud.tencent.com/product/scf
- https://serverless.aliyun.com/
- https://www.huaweicloud.com/product/functionstage.html
- https://www.cloudflare.com/img/learning/serverless/glossary/backend-as-a-service-baas/what-is-backend-as-a-service.svg
「真诚赞赏,手留余香」
真诚赞赏,手留余香