摘要:本文中對比了 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。