摘要:本文中对比了 Kubernetes 中的三大 serverless 框架:OpenFaaS、Kubeless 和 Fission,文章比较长,请先收藏再阅读。原文连接:rancher.com/blog/2018/2… java
做者:Hisham Hasan node
译者:殷龙飞python
校对:宋净超、杨传胜、王凯git
Rancher 1.6和Rancher 2.0底层容器编排引擎的术语和概念略微有所不一样。想要了解这些差别就须要先了解Cattle和Kubernetes之间的根本区别。对于使用过Cattle或者Kubernetes的新手来讲,这篇文章比较适合您。同时你也能够从这里获取到容器编排引擎 Cattle 到 Kubernetes 的对应关系词汇表cheatsheet。github
无服务器 kubernetesweb
在Pokemon Go的早期,咱们都惊讶于Niantic如何在全球范围内扩展其用户群,如今看来他们应该是以无缝地向其容器集群添加额外的节点以容纳更多的玩家和环境,全部这一切均可以经过使用Kubernetes做为容器编排工具来实现。Kubernetes在扩展和管理容器基础架构中,可以从开发者角度抽象出部分过程和低级依赖关系。这使它成为一个很是有效的平台,用于开发和维护跨多个容器的应用程序服务。本文将探讨如何利用K8S的设计参数和服务编排功能,并将它们与无服务器框架和函数即服务(FaaS)结合起来。特别是,咱们将深刻研究其特性和功能,分析在K8s架构上构建的三个无服务器框架的运行性能和效率:(i)Fission; (ii)OpenFaaS; (iii)Kubeless。spring
无服务器体系结构指的是从开发人员中抽象出服务器管理任务的应用程序体系结构,并经过动态分配和管理计算资源来提升开发速度和效率。函数即服务(FaaS)是一个运行时被构建的无服务架构,能够在其上构建无服务器体系结构。FaaS框架做为短暂的容器运行,它们已经安装了公共语言运行时,并容许在这些运行时内执行代码。docker
FaaS框架应该可以在各类基础架构上运行,以实现真正有用,包括公共云,混合云和内部部署环境。在真实生产环境中基于FaaS运行时构建的无服务器框架应该可以依靠通过验证和测试的编排和管理功能来大规模部署容器和分布式工做负载。json
对于编排和管理,无服务器FaaS框架依赖Kubernetes,由于它可以:后端
跨主机群集编排容器。
最大化程度的利用企业应用程序所需的硬件资源。
管理和自动化应用程序部署并提供声明式更新。
经过挂载存储运行有状态应用程序。
秒级扩容容器化应用程序并提供支持它们的资源。
声明式地管理服务。
提供一个大盘,来检查应用的健康状况,并经过自动重启,自动复制和自动缩放来进行应用程序的自我修复。
咱们将在本文中介绍三个无服务器框架各自的优势和缺点。这些FaaS框架之间的共同点是,它们可以(1)将函数转化为服务; (2)利用Kubernetes平台管理这些服务的生命周期。这些框架背后的设计,会因为其用于实现的具体方式的不一样而有差别,咱们将在下一节中探讨。咱们将在如下部分中重点介绍这些框架之间的一些差别:
框架是在源码级别或Docker镜像级别仍是在中间运行,例如buildpacks?
因为使用公共语言运行库启动容器,冷启动性能的延迟或执行函数期间的延迟分别是多少?
它们如何为服务分配内存或资源?
它们如何访问和部署Kubernetes的编排和容器管理功能?
OpenFaaS是一个无服务器平台,容许使用Docker或Kubernetes管理函数,由于它是基于OCI格式的容器。OpenFaaS能够支持企业级扩展的功能,如Docker Universal Control Plane企业级集群管理解决方案与Docker Enterprise或Tectonic for Kubernetes。OpenFaaS继承了现有的容器安全功能,例如r/o文件系统,权限降低和内容信任。它可以使用Docker或K8s调度程序/容器编排的管理功能,而且可使用其相关的丰富的商业和社区供应商生态系统。一样,因为其多语言特性,任何可执行文件均可以打包到OpenFaas中的函数中。
SpringBoot和Vertx是开发微服务的很是流行的框架,它们的易用性已经经过OpenFaaS模板扩展到OpenFaaS。这些模板容许在OpenFaaS平台上无缝地开发和部署无服务器函数。模板在这里的github存储库中可用。让咱们来看看如何在OpenFaaS平台上部署SpringBoot模板。
咱们须要安装和配置FaaS CLI以与本地或远程K8S或Docker配合使用。在本练习中,咱们将使用本地Docker客户端,并在后续工做中将其扩展到基于云的GKE集群。
对于最新版本的CLI类型:
$ curl -sL https://cli.openfaas.com | sudo sh
[或经过MacOS上的brew install faas-cli。]
使用如下命令验证本地安装的模板:
faas-cli new --list
在咱们建立无服务器函数以前,咱们必须在本地计算机上安装这些模板。
faas-cli template pull https://github.com/tmobile/faas-java-templates.git复制代码
能够为全部命令调用-help标志。
$ faas-cli --help
从命令行管理您的OpenFaaS功能
用法: faas-cli
[flags] faas-cli
[command]
可用命令:
build
构建OpenFaaS功能容器
deploy
部署OpenFaaS功能
help
有关任何命令的帮助
push
将OpenFaaS功能推送到远程仓库(Docker Hub)
remove
删除已部署的OpenFaaS功能
version
显示客户端版本信息
参数: -h
,--help
帮助FAAS-CLI -f
,--yaml string
描述函数的yaml文件的路径
有关命令的更多信息,请使用 faas-cli
[command] --help
。
使用来自Vertx/SpringBoot模板的github存储库中咱们感兴趣的函数,咱们能够建立一个函数(用咱们的函数替换大括号内的文本,咱们使用springboot但你能够用vertx模板代替它):
faas-cli new {function of function} --lang springboot
使用mvnw,命令是
faas-cli new mvnw --lang vertx | springboot Folder: mvnw created.Function created in folder: mvnw Stack file written: mvnw.yml复制代码
mvnw.yml的内容如今能够与CLI一块儿使用。
注意:若是您的群集是远程的或未在8080端口上运行 - 请在继续以前在YAML文件中对其进行编辑。为咱们的函数生成了handler.java文件。您能够编辑pom.xml文件,并在“build”步骤中安装全部依赖项。
如今咱们已经建立了函数逻辑,咱们可使用faas cli build命令构建函数。咱们将使用本地Docker客户端将该函数构建到docker镜像中。
$ faas-cli build -f mvnw.ymlBuilding: mvnw.Clearing temporary build folder: ./build/mvnw/Preparing ./mvnw/ ./build/mvnw/functionBuilding: mvnw with node template. Please wait..docker build -t mvnw .Sending build context to Docker daemon 8.704kBStep 1/19 : FROM node:6.11.2-alpine ---> 16566b7ed19eStep 19/19 : CMD fwatchdog ---> Running in 53d04c1631aa ---> f5e1266b0d32Removing intermediate container 53d04c1631aaSuccessfully built f5e1266b0d32Successfully tagged mvnw:latestImage: mvnw built.复制代码
为了部署咱们的函数,咱们将编辑mvnw.yml文件并将“image”行设置为Docker Hub上适用的用户名,例如:hishamhasan/mvnw。而后咱们将再次构建该函数。
$ faas-cli push -f mvnw.ymlPushing: mvnw to remote repository.The push refers to a repository [docker.io/hishamhasan/mvnw]复制代码
完成此操做后,镜像将被推送到Docker Hub或远程Docker registry,咱们能够部署并运行该函数。
$ faas-cli deploy -f mvnw.ymlDeploying: mvnw.No existing service to removeDeployed.200 OKURL: [http://localhost:8080/function/mvnw](http://localhost:8080/function/mvnw)复制代码
$ faas-cli invoke -f mvnw.yml callmeReading from STDIN - hit (Control + D) to stop.This is my message{"status":"done"}复制代码
咱们还能够将命令传递给函数,例如:
$ date | faas-cli invoke -f mvnw.yml mvnw{"status":"done"}复制代码
在使用OpenFaaS时,咱们不限于任何本地或云基础架构。如今咱们已经在本地Docker集群中部署了模板,咱们能够经过在GCP中的GKE上设置它来利用OpenFaaS的多功能性。
建立一个名为的GCP项目
在此处 下载并安装Google Cloud SDK。安装SDK后,运行gcloud init,而后将默认项目设置为openfaas。
使用gcloud安装kubectl: gcloud components install kubectl
导航到API Manager>凭据>建立凭据>服务账户密钥。
选择JSON做为密钥类型。将文件重命名为json并将其放在项目中
添加刚刚在ComputeEngine> Metadata> SSH Keys下建立的SSH密钥,并使用您的公共SSH密钥做为值建立名为sshKeys的元数据条目。
建立一个三节点Kubernetes集群,每一个节点位于不一样的区域中。在此处 阅读 有关群集联合的信息,以了解如何选择每一个群集中的群集数和节点数,这些群集可能会根据负载或增加频繁更改。
k8s_version=$(gcloud container get-server-config --format=json | jq -r '.validNodeVersions[0]')gcloud container clusters create demo \ --cluster-version=${k8s_version} \ --zone=us-west1-a \ --additional-zones=us-west1-b,us-west1-c \ --num-nodes=1 \ --machine-type=n1-standard-2 \ --scopes=default,storage-rw复制代码
将默认节点池的大小增长到所需的节点数(在此示例中,咱们将按比例增长3到9个节点):
gcloud container clusters resize --size=3
您能够经过调用此 页面中 所述的合适的SDK命令来执行集群管理功能,例如删除集群。
gcloud container clusters delete demo -z=us-west1-a
设置kubectl的凭据:
gcloud container clusters get-credentials demo -z=us-west1-a
建立集群管理员用户:
kubectl create clusterrolebinding "cluster-admin-$(whoami)" \--clusterrole=cluster-admin \--user="$(gcloud config get-value core/account)"复制代码
授予kubernetes-dashboard管理员权限(确保在非生产环境中完成):
kubectl create clusterrolebinding "cluster-admin-$(whoami)" \--clusterrole=cluster-admin \--user="$(gcloud config get-value core/account)"复制代码
您能够经过使用kubectl反向代理在浏览器(或在 http//localhost:9099/ui )上调用 kubectl proxy --port=8080
和导航到 http//localhost:8080/ui 来访问port-8080上的kubernetes-dashboard :http://localhost:9099/ui
kubectl proxy --port=9099 &
Kubernetes集群由主节点和节点资源组成 - 主节点协调集群,节点运行应用程序,并经过Kubernetes API进行通讯。咱们使用OpenFaaS CLI构建了容器化应用程序并编写了.yml文件来构建和部署该函数。经过在Kubernetes集群中的节点之间部署该函数,咱们容许GKE分发和调度咱们的节点资源。咱们的节点已经配置了处理容器操做的工具,能够经过kubectl CLI。
克隆openfaas-gke存储库:
git clone https://github.com/tmobile/faas-java-templates.gitcd openfaas-gke复制代码
建立openfaas和openfaas-fn名称空间以在多租户设置中部署OpenFaaS服务:
kubectl apply -f ./namespaces.yaml
要在openfaas命名空间中部署OpenFaaS服务:
kubectl apply -f ./openfaas
这将为OpenFaaS网关,FaaS-netesd(K8S控制器),Prometheus,警报管理器,Nats和队列工做者提供K8s pods,部署和服务。
咱们须要在经过设置身份验证在Internet上公开OpenFaaS以前保护咱们的网关。咱们可使用一组凭据建立一个通用的basic-auth秘密:
kubectl -n openfaas create secret generic basic-auth \--from-literal=user=admin \--from-literal=password=admin复制代码
而后咱们能够为咱们的OpenFaaS网关部署Caddy,它既能够做为反向代理,又能够做为强大的负载均衡器,并支持WebSocket链接:
kubectl apply -f ./caddy
而后,咱们将使用K8s服务对象公开的外部IP访问OpenFaaS网关UI,并使用咱们的凭据访问http://<EXTERNAL-IP>。咱们能够经过运行kubectl get svc来获取外部IP。
get_gateway_ip() { kubectl -n openfaas describe service caddy-lb | grep Ingress | awk'{ print $NF }'}until [["$(get_gateway_ip)"]]do sleep1;echo -n ".";doneecho "."gateway_ip=$(get_gateway_ip)echo "OpenFaaS Gateway IP: ${gateway_ip}"复制代码
注意:若是外部IP地址显示为<pending>,请等待一分钟再次输入相同的命令。
若是您还没有执行上一个练习,请经过调用安装OpenFaaS CLI。
curl-sL cli.openfaas.com | sh
而后使用CLI,凭据和K8s服务公开的外部IP登陆:
faas-cli login -u admin -p admin --gateway http://<EXTERNAL-IP>
注意:(a)您能够经过建立Ingress资源,使用Google Cloud L7 HTTPS负载均衡器公开OpenFaaS网关。您能够在 此处 找到有关建立负载均衡器的详细指南。(b)您可使用密码建立文本文件,并将该文件与-password-stdin标志一块儿使用,以免在bash历史记录中输入密码。
$ faas-cli deploy -f mvnw.yml
deploy命令在当前目录中查找mvnw.yml文件,并部署openfaas-fn命名空间中的全部函数。
注意:(a)您可使用com.openfaas.scale.min标签设置最小运行pod数,并为autoscaler com.openfaas.scale.max设置最小副本数。OpenFaaS的默认设置是每一个功能运行一个pod,而且在负载下最多可扩展到20个pod
faas-cli invoke mvnw--gateway=http://<GATEWAY-IP>
faas-cli logout -gateway http://<EXTERNAL-IP>
Fission是一个无服务器框架,它进一步抽象出容器镜像,并容许仅经过函数在K8s上建立HTTP服务。Fission中的容器镜像包含语言运行时,一组经常使用的依赖项和一个用于函数的动态加载器。能够定制这些图像,例如打包二进制依赖项。Fission可以经过维护一个正在运行的容器池来优化冷启动开销。当新请求来自客户端应用程序或业务服务时,它会将该函数复制到容器中,动态加载它,并将请求路由到该实例。所以,对于NodeJS和Python函数,它可以最小化100毫秒的冷启动开销。
经过在源码级别进行操做,Fission使用户没必要处理容器的镜像构建,将镜像推送到注册表,管理注册表凭据,镜像版本控制和其余管理任务。
如上图所示,Fission被设计为一组微服务,主要组件以下所述:
跟踪功能,HTTP路由,事件触发器和环境镜像的控制器;
管理空闲环境容器池的池管理器,将函数加载到这些容器中,并按期杀死函数实例以管理容器开销;
一种路由器,它接收HTTP请求并将它们路由到poolmgr或已在运行的实例中的新鲜函数实例。
咱们可使用在上一个练习中GCP上建立的K8s群集在Fission上部署HTTP请求。让咱们走过这个过程吧。
1. 安装Helm CLI, Helm是一个Kubernetes包管理器。让咱们初始化Helm:
$ helm init复制代码
2. 在GKE命名空间中安装Fission
$ helm install --namespace fission https://github.com/fission/fission/releases/download/0.7.0/fission-all-0.7.0.tgz复制代码
3. 安装Fission CLI
OSX
$ curl -Lo fission https://github.com/fission/fission/releases/download/0.7.0/fission-cli-osx&& chmod +x fission && sudo mv fission /usr/local/bin/复制代码
Windows 在 此处 下载Windows可执行文件。
1. 建立HTTP服务咱们将建立一个简单的HTTP服务来打印Hello World。
$ cat > hello.pydef main(context): print "Hello, world!"复制代码
2. 在Fission上部署HTTP服务
$ fission function create --name hello --env python --code hello.py --route /hello$ curl http://<fission router>/helloHello, world!复制代码
Kubeless是一个Kubernetes原生无服务器框架,能够将功能部署在K8s集群上,同时容许用户利用Kubernetes资源提供自动扩展,API路由,监控和故障排除。Kubeless使用Kubernetes自定义资源定义来建立自定义kubernetes资源的功能。自定义资源是 Kubernetes API 中的端点,用于存储API对象的集合某种类型的K8s pod对象,它表明了特定K8s安装的自定义。自定义资源很是有用,由于它们能够经过动态注册进行配置而后在正在运行的集群中删除,集群管理员能够独立于集群自己更新自定义资源。Kubeless利用这些功能并运行集群内控制器,能够跟踪这些自定义资源并按需启动运行时。
咱们可使用在上一个练习中GCP上建立的K8s群集在Fission上部署HTTP请求。让咱们走过这个过程吧。
1. 访问Kubernetes仪表板
在K8s集群正在运行的状况下,咱们可使用kubectl在8080端口上使用仪表板:
kubectl proxy --port=8080
OSX
$ curl -L https://github.com/kubeless/kubeless/releases/download/0.0.20/kubeless_darwin-amd64.zip > kubeless.zip$ unzip kubeless.zip$ sudo cp bundles/kubeless_darwin-amd64/kubeless /usr/local/bin/复制代码
Windows
在 此处 下载Windows可执行文件。
1. 在K8s群集中部署Kubeless
咱们将使用此连接中 的清单在K8s群集中部署Kubless。根据清单建立一个kubeless命名空间,一个函数ThirdPartyResource,一个kubeless控制器,并在进程中设置一个kafka,zookeeper StatefulSet。Kubless的一个主要优势是它具备高度的Kubernetes原生特性,它能够设置非rbac和rbac特定环境。下面的屏幕截图显示了如何使用kubectl命令在非rbac环境中部署kubeless。
2. 建立函数
咱们能够建立一个服务函数,并从请求中接受方法,URL,标题和请求体。
const http = require('http'); http.createServer((request, response) => { const { headers, method, url } = request; let body = []; request.on('error', (err) => { console.error(err); }).on('data', (chunk) => { body.push(chunk); }).on('end', () => { body = Buffer.concat(body).toString(); // 此时,咱们有标题,方法,网址和请求体,如今能够作任何咱们须要的事情来回应这个要求。 }); }).listen(8080); // 激活此服务器,监听8080端口。复制代码
在Kubeless环境中运行函数
咱们能够经过提供如下信息向Kubeless注册该函数:
用于经过Web访问该函数的名称
用于访问该函数的协议
要执行以运行代码的语言运行时
包含函数代码的文件的名称
文件内部函数的名称
经过添加上面的变量1-5,咱们调用如下命令在Kubeless中注册和部署函数:
kubeless function deploy serverequest--trigger-http --runtime nodejs6 --handler serverequest.createServer --from-file /tmp/serverequest.js
咱们评估的每一个无服务器平台都有其独特的价值主张。使用OpenFaas,任何进程或容器均可以打包为Linux或Windows的无服务器功能。对于企业而言,OpenFaaS使用的体系结构提供了无缝插入计划群集和现有微服务的CI/CD工做流的能力,由于OpenFaaS是围绕Docker构建的,全部功能都打包到Docker镜像中。OpenFaaS还为企业提供了一种经过外部API,网关管理和执行函数的无缝方式,并管理函数的生命周期,包括经过提供商进行部署,扩展和secret管理。
Fission具备事件驱动架构,使其成为短时间无状态应用程序的理想选择,包括REST API或webhook实现以及DevOps自动化。使用Fission的一个很好的用例多是开发聊天机器人的后端,由于Fission能够实现良好的冷启动性能,并在须要时经过保持运行时的容器池来提供快速响应时间。
最后,Kubeless架构利用原生Kubernetes概念来部署和管理功能,例如自定义资源定义,用于定义功能和自定义控制器来管理函数,将其部署为Kubernetes部署并经过Kubernetes服务公开它。与Kubernetes原生功能的紧密结合将吸引现有的Kubernetes用户,下降所需的学习曲线并没有缝插入现有的Kubernetes架构。
Hisham是一位咨询企业解决方案架构师,在利用容器技术解决基础架构问题和更快地部署应用程序以及更高级别的安全性,性能和可靠性方面拥有丰富的经验 最近,Hisham一直在为各类中间件应用程序利用容器和云原生架构,以在整个企业中部署复杂的关键任务服务。在进入咨询领域以前,Hisham曾在Aon Hewitt,Lexmark和ADP从事软件实施和技术支持工做。
微信群:联系我入群
Slack:servicemesher.slack.com 须要邀请才能加入
Twitter: twitter.com/servicemesh…
GitHub:github.com/
更多Service Mesh咨询请扫码关注微信公众号ServiceMesher。