以中立性的立场看 Severless 的目标和流派
摘要
本文以中立性的立场阐述Severless(无服务器计算)。Severless基本的目标是简化使用者对于服务器的关注。在实际的应用中,Severless则分成了两个流派:一是函数为单位的FaaS引擎;二是以Knative为代表的kubernetes应用引擎。
1 Severless的基本目标
由Serverless衍生出来的概念、技术已经比较多,本段回归它基本的目标。顾名思义,Serverless的含义为无服务器计算,因此它的目标也就是让使用者减少对服务器的关注,简化DevOps流程。
Serverless的基本目标来自于实际的需求,可以看下面的“理想与现实”:
【理想】要做分布式程序
〖现实〗欠缺服务端RD&OP技能
【妥协〗可以通过无状态、函数式调用方式进行简化
换一个角度来说,以程序开发者为出发点,他应当更多关注本身程序的实现,而不是分布式程序环境、运维方面。
“多写代码、少管环境”也正是所有R&D体系的目标,只是这个目标对于分布式程序的开发来说,显得更加复杂。
本文对于Serverless的定性是:Serverless是一个Cloud Native的支线,只针对部分需求、而非所有需求,这部分需求可以用更为高效的方式来实现。
下面的图描述了Serverless的理念。
分布式系统涉及了DevOps的全流程,Cloud Native的全景图非常广阔,涉及了分布式的能力、移植适配能力、标准扩展能力等方面,支持了无状态、有状态、单次任务、定时任务等多种生命周期的应用。
Serverless一般是对无状态场景的优化,简化的结果就是技术可以更高效。如果进一步简化,无状态的应用可以分割成一个个独立的函数,函数再由触发器来调用,使用者则是只需要“写函数”。
当然,这种简化的目标是比较理想的,实现的过程、产生的技术点则非常多。
2 Severless的CNCF定义与两大流派
2.1 CNCF的Serverless全景图
Serverless的理念和类似的技术,原本出现是非常早的,但是这个名称的提出却与CNCF密切相关。
本段内容是CNCF内容的罗列,并不算非常系统化,仅作为参考资料。
在CNCF的全景图中,Serverless是右侧居中的一个部分(红框的部分)。
CNCF的Serverless的全景图大约是下面的情况。
CNCF视角中的Serverless的几个部分:
Framework:框架部分
• Spring Cloud Function :Java的编程模型,从Serverless角度是服务器运行能力;
• Claudia.js:Node.js部署到AWS Lambda的工具
Tools:相关工具
Security:安全部分
Hosted Platform:主机方式运行的平台
• AWS Lambda :从事件到响应代码的计算服务
Installable Platform:可在云安装的平台
• Kubless :Functions、Triggers、Runtime三位一体,通过k8s operator构建;
• Google Knative :解决serverless 应用的构建、部署和运行的问题,要运行k8s的 workload;
2.2 CNCF的Serverless流程
本节抛开 Serverless的具体实现流派,只是从使用者的角度来看它的操作流。
CNCF定义的Serverless几个步骤流程如下所示。
以上的流程图与用不用kubernetes并没有关系,这里面涉及了几个概念:
以Code(代码)和Spec(描述)为程序的起点;
标准化的Build生产bin(二进制)或者image(映像)——此处称之为Antifact;
Antifact可以与Spec共同进行Deploy,形成分布式的程序;
分布式的程序称之为Function Instance,它通过Event(事件)来触发;
通过Monitor(监控)和Auto-Scale(自动扩缩)来进行因为运维;
在以上的流程已经实现自动流、流程化的情况下,用户(使用者)只需要关注写代码。
CNCF定义的Serverless的几种触发器Trigger ,它们表示了无服务器计算场景。
以上的Trigger 表示了无服务器计算场景:作用Http调用的实现者、同步、异步消息队列的实现者、Job的实现者。
2.3 Serverless两个流派
Serverless目标是清晰的,实现的套路也有了框架,其中的一个变数就是如何从代表变成Bin和Image。
Bin和Image本身也是有区别的,Bin代表的是一个Function类的程序,而Image则是Docker的映像、代表K8s调度的workload。
基于上述的区别,Serverless的技术可以分成两个流派:
【函数计算】以Function为单元,形成FaaS函数计算平台;
【Knative】以kubernetes的workload为基线,提升自动扩缩等运维能力;
在狭义的Serverless概念中,仅指【函数计算】,而不包括【Knative】。
3 Severless流派一:函数计算
3.1 函数计算真谛
函数计算得到真谛是“简化”,这个概念要早于CNCF、Severless。对于开发者来说,工作简化为“写函数”,这是一个比“写代码”更加简单的过程,函数有着更明确的输入、输出,并且对接到某个出发点(Trigger)上面。
函数计算实现的一个流程图如下所示。
以上的Http Trigger就是一个最基本的触发点,比如一个URL可以对应到一个函数实现上面,它的输出就是函数计算的各个实现。
3.2 BaaS和FaaS的架构
FaaS(Function as a service)是一个仿照云计算的IaaS、PaaS、SaaS的类似概念,FaaS的底层是BaaS(Backend as a service),它代表后端服务。
下面是一个结合FaaS和BaaS的架构图。
在FaaS&BaaS模式中,二者的分工如下所示:
BaaS表示数据库、后端接口等实体,提供一些能力层面的东西,一般比较稳定;
FaaS是偏前的函数,实现具体的功能,开发工作比较多;
FaaS、BaaS与PaaS平台的一个关系描述如下所示。
上图中蓝色的部分是PaaS平台负责的内容,而黄色部分Serverless则是使用者需要关注的部分。
AWS lamada、Google Cloud Functions、Azure Funcions、IBM OpenWhisk都是Serveless的FaaS引擎,出于中立性的立场,本文不对这些云服务提供商的产品进行讨论。
4 Severless流派二:Knative
4.1 Knative的官方概念
Knative的官方定义是:Kubernetes-based platform to deploy and manage modern serverless。workloads。它本身是基于Kubernetes的,并且提供了serverless的workload。
Knative的目标是让开发者更有效率。Serverless本身并不是局限于Kubernetes的概念,但是Knative却是建立在Knative之上的。
Knative的官方结构图如下所示——本图的重点是Knative与Kubernetes的关系。
在Knative包括了下面的两个组件:
Serving:配置应用的路由、升级策略、自动扩缩容等功能
Eventing:自动完成事件的绑定、触发
Knative的向详细文档是:
4.2 Knative与自动扩缩
结合Serverless的目标、Kubernetes的具体情况,Knative其实提供了两个方面的能力:
介于Kubernetes与应用直接的中间层;
调度能力,也称之为AutoScaler;
从Kubernetes的角度,Knative改变了一个"应用"的编写过程:
由于中间层的存在,使用者不需要类似这种细节,在yaml中定义Deployment及其副本数、资源量等信息;
由于使用者定义的点平少,Kubernetes的调度端更可以更大的权限来进行弹性,也就是AutoScaler。
下面的图表示了Kubernetes当中AutoScaler的作用。
Kubernetes中的扩缩弹性分成下面两个概念:
HPA(Horizontal Pod Autoscaler):控制Pod的个数;
VPA(Vertical Pods Autoscaler):控制Pod的CPU、内存等资源指标;
例如:一个HPA的逻辑可以是:当Pod的CPU大于80%的时候,自动实现扩容。
Knative中定义了PodAutoscaler,它本身也就是一个中间层。
4.3 Knative与Istio的关系
在实际的应用中,Knative与Istio有结合使用的例子。
下面是Knative与Istio结合的示意图。
Knative与Istio其实并非强耦合,但有一个关联点。Knative的Autoscaler想要更好的进行扩缩,需要更多的输入,Istio的数据面,自然是一个理想的输入。
下面的图也是来自Istio的官方文档Mixer Adapter for Knative:https://istio.io/latest/blog/2019/knative-activator-adapter/
下面是一个Knative相关的架构图。
下面是一个Knative与Istio结合的结构图。
注意图中的一个关键点,由于Envoy本身作用系统的数据面,它可以得到更多的调用信息,这些信息提供给Knative的Autoscaler,作为扩缩的依据。
5 Serverless的中立性总结
本文秉承中立性的立场,不引入这些概念,要从不同的角度理解Serverless无服务器计算。
5.1 从实战的角度
从各个系统实战的角度,Serverless的确只是解决了部分场景,首先约束条件要求无状态。
在一个实际的系统中,无状态的确只是部分的场景,但这个量级可不一定小,理论上除了数据库、队列等依赖存储环节,其他应用都是无状态的。并且,服务化建设越多、服务层次越深,无状态应用的比重也就越大。
无论是面向应用的、还是面向函数的,Serverless的实现比较害怕系统的拓扑结构发生变化,因为在这种变化中,要调整的不仅仅是代码。
5.2 从FE工程师的角度
目前,FE工程师(以编写HTML、JavaScript)为主的工程师是推行Serverless最积极的群体,此处的Serverless一般就是FaaS函数平台。
因为在Serverless存在情况下,他们会有很多主观和客观的收益:
如果能力层固定,用NodeJS和前端就可以完成“大前端”工作,不再需要与后端工程师联调;
可以用同一套代码,在Node.js和JavaScript环境中实现同构渲染,适应不同场景;
前端工程师往往比较不懂运维,用Serverless恰好回避了这种问题;
实际情况并非如此简单,比如函数初次启动速度的问题、非Image上线的原罪性问题。
5.3 从后端工程师的角度
从后端工程师的角度,对于Serverless也有诉求,但是没有FE工程师强烈。
后端工程师对于Serverless的向往,往往有以下的考虑:
在只想实现较简单的无状态服务,简单的分布式方法即可;
在只需要处理某些事件的情况下, 单次的调用即可;
函数式的编程,毕竟可以减少成本。
这种场景在Web 服务,大数据处理均有场景,引入Serverless属于“理论上有收益”。
关于效率的问题,总有着两面性:
传统的发布、运维虽然麻烦,但在掌握之后,毕竟成本越来越低、趋于零;
Serverless平台本身不是个标准的东西,它的引入本来也有成本。
5.4 从Serverless方案提供者的角度
在 Serverless的商业化领域,常常有各种各样的宣传手段,甚至将“虚拟化、容器化、无服务器化”称之为计算领域的三个里程碑。
回归Serverless的本身,除了技术方案之外,方案提供者还有几个方面需要考虑:
语言支持:Node.js最重要,Python、C#、Java、PHP、GO可选
驱动机制:HTTP Trigger为基本,还有Job、Queue、Storage等触发,作为调用点
开发工具:每种语言都需要有配套设施,完成build的过程;
计费引擎:调用次数是基本因素,弹性扩缩也会引起账单的变化;
云计算服务提供商是Serverless的利益相关方,它们显然有一些本位的宣传。Serverless对云计算服务提供商的价值,其实不仅仅是赚钱。
Serverless在自然增值、降低门槛、绑架客户三个方面,均有作用,因此它对于云计算服务提供商来说,是一个很大的“杀手锏”,即便不是上述Serverless类型的服务,也常常会以Serverless的名义发布。
评论