1Serverless简介1.1比微服务分拆服务还要细
serverless是近来几年继微服务以后盛行的又一种十分流行的新型估算模式,它相对微服务来说是愈发细细度的服务构架模式,把用户所要执行的每位API操作进一步分拆。
换句话说,微服务包含了对某个资源的所有CURD操作,而Serverless则把针对资源的创建、读取、删除、更新等操作进一步分拆,每一个操作具象为一个函数,Serverless是通过直接把这种函数曝露的方式进行发布,因而Serverless一般又称为函数估算服务(FunctionasService,FaaS)。
1.2Serverless可能是目前资源具象级别最高的
从资源具象上看,从最早的化学服务器开始,我们都在不断地具象或则虚拟化服务器,而Serverless则更是具象到了极至,它彻底屏蔽了底层硬件、操作系统甚至底层平台等技术细节
注:图片来源。
总而言之,毫不夸张地说Serverless比我们熟知的服务器、KVM、OpenStack、Kubernetes、微服务等提供了更中级的资源具象能力。Serverless平台犹如一个无限容量的超级计算机,只要把代码递交起来才能运行,不须要关心究竟是运行在化学机、虚拟机还是容器。
其实Serverless并不意味着底层真的不须要服务器运行,而是平台屏蔽了前端基础资源和基础构架的维护,从实现上它仍然可能运行在虚拟机、容器或则Kubernetes平台之上,只是用户不须要关心罢了,真正运行在那个虚拟机上或则那个Kubernetes集群似乎都无所谓了。
1.3从用户的视角看
而从用户的视角,用户只须要把代码写好打包递交起来即可运行,不须要自己打算运行的服务器、安装运行环境,所以可以近似觉得Serverless提供了一个代码可运行的平台。
使用Serverless用户甚至都不须要关心运行所须要多少CPU、内存等估算资源,由于Serverless平台就提供了近似无限的估算能力,这也是和PaaS的主要区别,即大部份PaaS平台,用户仍然须要自动维护运行的容量,须要自动扩容或则缩放平台规模。
而对于FaaS应用,这些问题完全是透明的。AWS云构架战略总工裁AdrianCockcroft当初针对二者的划分给出了一个简单的方式:“如果你的PaaS才能有效地在20微秒内启动实例并运行半秒,这么就可以称之为Serverless”。--摘录自《从IaaS到FaaS——Serverless构架的前世此生》
1.4云估算层面剖析
而从云估算角度,Serverless才能最大化借助估算资源,降低资源闲置和碎片。从云营运角度上看,Serverless能精确到代码调用次数和运行时间的细度实现计量计费,实现调用一次计费一次,不调用不计费,这相对启动一个虚拟机运行代码来说,除非你的应用才能始终保证满载运行,否则只要资源空闲则意味着资源浪费。
2那究竟哪些是Serverless?
上面讲了这么多,虽然都是概念和理论linux内存管理api函数,那究竟Serverless长哪些样,如何用呢?
2.1写一个Serverless函数
接出来我们就以AWS的Serverless函数估算Lambda服务为例,介绍一个ServerlessHelloWorld函数如何运行的。
首先我们创建一个函数:
创建一个函数只须要两个最基本的参数,一个是函数名称,另一个是运行环境,这儿我们选择Python3.8。我们发觉根本不须要告诉它须要运行在虚拟机还是容器,也不须要告诉它运行究竟须要多少CPU、多少显存,由于这一切都是透明的,用多少分多少。
但须要注意,这儿说的理论上是不须要提早分配CPU和显存,但事实上仍须要对其使用的资源进行限制,否则你的应用假如存在显存泄漏或则fork炸弹,则会造成资源浪费。因而AWSLambda就会配置默认的显存限制128MB以及超时时间3秒,用户可以自动调节这种参数。
接出来我们就可以上传或则在线写代码了,这儿我们的HelloWorld函数很简单,仅复印HelloWorld!以及返回"hello"字符串。
def lambda_handler(event, context):
print("HelloWorld!")
return "hello"
我们点击Test按键就可以运行我们的代码了:
输出如预期那样复印了HelloWorld!而且函数返回了字符串"hello"。
所以Serverless就是如此简单,不是吗?
2.2Serverless平台就是一个在线代码运行平台?
大多数人听到这儿都可能会说,上面说了这么多,原先Serverless就是一个在线编程工具,这个网上这样的平台一大把,例如codechef、doocnn、repl.it,随时随地有创意马哥linux,随时随地写程序,支持C、C++、Python、Java、Php、Perl,Ruby、Bash、C#、Go、Lisp、Lua、Scala...,递交代码才能运行,这个AWSLambda也没哪些非常的嘛。
确实假如须要自动去执行,这个与在线代码运行平台没哪些区别,之前手身上没有现成的运行环境时懒得安装配置,我就是在AWSLambda上测试代码的。
2.3Serverless风波驱动
但是Serverless最强悍的功能并不是能在线运行各类编程语言代码,而是其支持的各类触发器。悉心的读者可能会发觉Lambda的函数入口lambda_handler(event,context)有一个十分重要的参数event,这个event就是Lambda函数的灵魂、云平台的神经系统。
有了这个神经系统就相当于打通了整个云平台系统血脉,云平台上的任何一个服务都可以通过event传递到Lambda函数,Lambda函数接收到这个event后调用就相当于神经反射。
那哪些是event呢?event翻译成英文就是风波,几乎所有的行为变化都可觉得是一个风波,例如调用API创建一个虚拟机是一个风波,通过Web或则联通APP的一次HTTP调用也是一个风波,告警也是风波,定时器到点了也是风波,其实,你做的任何一件事都可以觉得发生了一系列风波。
所以Serverless本质就是风波驱动的,有了风波,便有了灵魂,便和这些在线编程工具不再是同类。
其实风波这么多,但并不是所有的风波都是我们关心的,函数估算只处理早已注册的风波,AWS上叫添加触发器,这个和Linux的讯号机制是完全一样的。
为了验证event触发功能我们把代码改成如下:
def lambda_handler(event, context):
print(event)
return event
如上代码我们并没有处理event,而是直接返回了event实例。
我们注册如下风波:
即注册了所有往S3int32bit-test桶里创建对象的风波,可选参数Prefix、Suffix还可以进一步过滤风波,例如只处理上传以.jpg为文件扩充名的图片文件。
风波注册后自动向int32bit-test桶上传一个文件repl.png,在Cloudwatch中可以查看Lambda函数的执行记录:
我们发觉风波event中包含了如下信息:
即清晰记录了哪些人在哪些地方以及在哪些时侯做了哪些以及形成了哪些。
2.4Serverless能做哪些
其实后面作为S3触发风波最简单的事例,我们并没有做哪些。但只要我们实现Lambda函数,就可以实现无限可能的功能,例如:
其实不仅S3风波,Lambda还可以注册其他服务风波,例如:
2.6Serverless总结
Serverless构架中主要由应用(代码)、运行环境(runtime)以及风波这三个重要诱因构成,其中风波是Serverless的灵魂,打通了云平台服务的血脉,可以说Serverless的函数估算是云平台服务的粘合剂,把看上去不相关的服务挺好的串上去,实现服务扩充。
3基于Serverless实现云资源合规基线检测与配置
这个在之前的文章早已简单介绍过通过Lambda函数估算实现云资源的合规基线检测和配置。
其基本流程如下:
用户通过console或则命令行创建云资源,例如虚拟机;
cloudtrail会对所有的API调用进行审计(auditing);
cloudwatch会监控cloudtrail风波;
cloudwatch过滤风波类型,并调用Lambda函数;
Lambda函数执行,对资源进行合规性检测。
其实假如我们针对每一个基线都须要自己写Lambda函数代码,则工作量还是挺大的,我们可利用一些规则引擎工具如CapitalOne开源的cloudcustodian(简称c7n)手动生成Lambda函数代码。
以一个AWS上常见的问题为例,我们晓得AWS的EC2、EBS等资源是不记录创建用户的,假如一个帐户有多个用户,在EC2列表中根本查不到这个虚拟机究竟是谁创建的,只能通过Cloudtrail在海量日志中渐渐去找了。
若果不使用Serverless,可以在AWS上启动一个EC2虚拟机,这个EC2虚拟机Attach读取Cloudtrail的权限,然前轮询这种风波,查询Runinstances风波,找到event是谁触发的,因而打上User标签。
而使用Serverless函数估算则可通过Cloudwatch窃听Cloudtrail的RunInstances风波并触发Lambda函数调用,这个Lambda函数负责把event取下来,按照event的记录的用户名把标签CreatorName打到EC2实例上即可,这样的用处在于:
cloudcustodian规则如下:
policies:
- name: ec2-auto-tag-user
resource: ec2
mode:
type: cloudtrail
role: arn:aws-cn:iam::***:role/***
events:
- RunInstances
actions:
- type: auto-tag-user
tag: CreatorName
principal_id_tag: CreatorId
如上规则代码会手动生成Lambda函数代码:
触发器为CloudWatchEvents,可以查看其配置如下:
可见,借助Serverless函数估算和event实现Lambda、Cloudtrail、Cloudwatch的联动,共同完成了给虚拟机手动打上User标签的任务。
目前我们早已基于custodian实现了几十条基线规则,包括手动关联堡垒机安全组、检查安全组规则是否开放高危端口、根据VPC给资源打上PROD或则TEST环境标签等。
另外须要注意的是AWS的风波一般会有数分钟的延后,因而Lambda函数触发也一般会有几分钟的信噪比。
4基于Serverless构架的Web应用4.1传统Web应用布署构架
我们晓得传统的Web应用布署过程一般包括如下步骤:
这些方法的问题如下:
目前基于Kubernetes平台服务发布则相对来说要敏捷得多,应用布署流程如下:
只要Kubernetes布署好,应用基本实现了和底层资源的隔离,例如我们通过Ingress实现七层负载均衡,但这个负载均衡究竟是基于Ngnix实现的还是F5实现,虽然用户并不须要关心。
这些方法相对最传统的布署构架,具有如下优点:
然而这些方法linux命令大全,依然还是和平台耦合在一起的,即使通过HorizontalPodAutoscaler以及ClusterAutoscaler实现了Pod以及集群规模的手动水平扩充能力,仍然未能在具体恳求数目层面上进行自由缩放,继续引用AWS云构架战略总工裁AdrianCockcroft的话:“如果你的PaaS才能有效地在20微秒内启动实例并运行半秒,这么就可以称之为Serverless”。
4.2Serverless构架
我们晓得一个Web应用包括静态页面和动态代码构成,静态内容是不变的,例如HTML、JS、CSS、图片、视频等,而业务逻辑通过动态代码在后台读取数据库并渲染为静态页面呈现给用户,是业务系统的核心。
在目前流行的MVC构架以及微服务模式下,一般后端和前端是分离的,前端处理业务逻辑并曝露RestfulAPI,而后端则通过Ajax异步调用前端的API恳求数据并渲染成表格、列表等进行数据展示。
这些应用构架很容易进行Serverless改建:
以AWS为例:
其处理流程如下:
用户通过浏览器访问Cloudfront或则S3上的静态页面;
静态页面中包含JS代码,JS代码通过Ajax向apigateway恳求数据;
apigateway会通过恳求路径以及恳求方式找到注册的Lambda处理函数;
Lambda函数解析用户的恳求参数,从数据库中读取数据,并返回JSON格式;
数据通过api-gateway返回给用户浏览器,浏览器领到数据通过JS渲染数据。
4.3一个简单的事例
这个事例参考了BuildingaServerlessWebApponAWSServices,这个是个极其简单的web课程培训管理页面,用户可以通过该应用查看课程培训列表以及降低、删除、更新那些课程。
应用包含两个实体:
这种数据储存在AWSDynamoDB上,对应两个表:
Lambda函数实现对Course的CURD操作以及Author读取:
在api-gateway服务创建对应的Resource,注册恳求方式以及对应的Lambda函数:
注册的方式如下:
其中POST/courses的执行过程如下:
S3上储存静态页面:
静态页面的JS封装了对api-gateway的调用,因为该应用通过nodejs编译后代码不可读,因而展示编译前的代码样例如下:
其中SERVER_URL就是api-gateway曝露的endpoint地址。
布署完成后就可以通过浏览器访问应用了:
4.4基于Serverless构架的Web应用的优势
相对传统的Web应用布署方法,基于Serverless构架的Web应用布署过程中我们发觉不须要配置CPU和显存资源,也不须要指定运行的平台环境,甚至也不须要配置负载均衡,只要递交打包代码才能运行,根据恳求方式选择调用的Lambda函数,没有恳求则不须要调用任何函数,提供满足实时需求的最大限度估算能力即可,使我们更有效地借助估算资源,不存在资源浪费的问题。
对于用户来说,不须要维护运行环境,不须要维护集群,不须要维护负载均衡,大大增加了运维和营运成本。
5基于Serverless实现Webhook
后面介绍了基于Serverless构架实现的Web应用,其实我们也很容易通过api-gateway以及函数估算实现Webhook功能。
例如配置githubwebhook,一旦有代码更新便通过Serverless触发CI/CD。
我们忽视CI/CD的复杂流程,以一个最简单的基于webhook实现手动布署的事例作为Demo,假定有一个静态网站托管在AWSS3上,源代码托管在github,通过Webhook实现一旦代码更新便通知Serverless手动拉取最新代码同步到S3上,进而维持我们网站是最新版本。
首先我们在github上创建一个test-web库房:
index.html代码为:
<h1 style='color:green'>
HelloWorld!
即显示一行红色的HelloWorld!。
之后我们实现一个Lambda函数clone代码到本地并上传到S3桶中:
import glob
import os
import boto3
GIT_REPO="https://github.com/int32bit/test-web.git"
def lambda_handler(event, context):
os.system("rm -rf /tmp/test-web")
os.system("git clone %s /tmp/test-web"% GIT_REPO)
s3 = boto3.client('s3')
for f in glob.glob('/tmp/test-web/*.html'):
try:
response = s3.upload_file(f, "int32bit-test-web",
os.path.basename(f),
ExtraArgs={'ContentType': 'text/html'})
exceptException as e:
return{"Status": "Fail to upload '%s'"% f,
"Reason": str(e)}
return{"Status": "OK"}
这儿须要注意的Lambda运行环境中并不包含git工具,好在早已有人实现基于LambdaLayer封装了git工具lambci/git-lambda-layer,我们可以直接引用这个Layer,不过因为国外Region未能引用美国AWSRegion的资源,因而须要自动创建并上传Layer。
接着我们通过api-gateway实现Webhook,因为Webhook是通过POST方式恳求,因而我们只须要实现POST方式,该方式调用test_webhook函数:
最后再github上配置webhook,其中PayloadURL填写api-gateway的endpoint。
此时我们只要更新int32ibt/test-web库房的代码才会手动触发Lambda函数,更新代码到S3桶中。
sed -i 's/green/red/g' index.html
git add index.html
git commit -m "Change font color to red"
git push
如上我们把字体颜色从green改成red并push代码到github库房中,我们可以在githubwebhook记录中查看执行情况:
可见webhook调用成功,我们再度访问网站:
可见网站HelloWorld字体更新为白色了。
须要注意的是,githubwebhook超时时间为10秒,这个难以配置。而github访问国外的AWS有时会很慢造成webhook触发超时。
5总结
本文首先简单介绍了Serverless函数估算的特性,之后介绍了Serverless构架中的应用(代码)、运行环境(runtime)以及风波这三个重要诱因以及Serverless怎么打通云平台服务的系统血脉,最后介绍了基于Serverless实现的三个典型应用场景。
不仅上面介绍的三个典型场景,还有好多其他适宜Serverless构架的场景,例如:
更多的案例以及开发手册可以参考Serverless应用开发手册。
其实不仅后面介绍的AWSLambda函数估算,还有好多的Serverless函数估算平台:
不过当前大多数公有云上的Serverless函数估算还不支持GPU,不过随着AI的流行,恐怕很快能够降低这个功能linux内存管理api函数,目前开源项目nuclio:High-PerformanceServerlesseventanddataprocessingplatform就实现了支持GPU的Serverless估算。
nuclio支持在Kubernetes平台上快速布署,参考GettingStartedwithNuclioonKubernetes。