摘要:本文中對比了 Kubernetes 中的三大 serverless 框架:OpenFaaS、Kubeless 和 Fission,文章比較長,請先收藏再閱讀。作者:Hisham Hasan
譯者:殷龍飛
校對:宋淨超、楊傳勝、王凱
Rancher 1.6和Rancher 2.0底層容器編排引擎的術語和概念略微有所不同。想要了解這些差異就需要先了解Cattle和Kubernetes之間的根本區別。對於使用過Cattle或者Kubernetes的新手來說,這篇文章比較適合您。同時你也可以從這裡獲取到容器編排引擎 Cattle 到 Kubernetes 的對應關係詞匯表cheatsheet。
在Pokemon Go的早期,我們都驚訝於Niantic如何在全球範圍內擴充套件其使用者群,現在看來他們應該是以無縫地向其容器叢集新增額外的節點以容納更多的玩家和環境,所有這一切都可以通過使用Kubernetes作為容器編排工具來實現。Kubernetes在擴充套件和管理容器基礎架構中,能夠從開發者角度抽象出部分過程和低階依賴關係。這使它成為一個非常有效的平臺,用於開發和維護跨多個容器的應用程式服務。本文將探討如何利用K8S的設計引數和服務編排功能,並將它們與無伺服器框架和函式即服務(FaaS)結合起來。特別是,我們將深入研究其特性和功能,分析在K8s架構上構建的三個無伺服器框架的執行效能和效率:(i)Fission; (ii)OpenFaaS; (iii)Kubeless。
A. 為什麼Kubernetes是無伺服器的優秀編排系統?
無伺服器體系結構指的是從開發人員中抽象出伺服器管理任務的應用程式體系結構,並通過動態分配和管理計算資源來提高開發速度和效率。函式即服務(FaaS)是一個執行時被構建的無服務架構,可以在其上構建無伺服器體系結構。FaaS框架作為短暫的容器執行,它們已經安裝了公共語言執行時,並允許在這些執行時內執行程式碼。
FaaS框架應該能夠在各種基礎架構上執行,以實現真正有用,包括公共雲,混合雲和內部部署環境。在真實生產環境中基於FaaS執行時構建的無伺服器框架應該能夠依靠經過驗證和測試的編排和管理功能來大規模部署容器和分散式工作負載。
對於編排和管理,無伺服器FaaS框架依賴Kubernetes,因為它能夠:
跨主機群集編排容器。
最大化程度的利用企業應用程式所需的硬體資源。
管理和自動化應用程式部署並提供宣告式更新。
通過掛載儲存執行有狀態應用程式。
秒級擴容容器化應用程式並提供支援它們的資源。
宣告式地管理服務。
提供一個大盤,來檢查應用的健康情況,並通過自動重啟,自動複製和自動縮放來進行應用程式的自我修復。
無伺服器系統可以包括通過客戶端請求觸發的功能或作為業務服務的一部分執行的功能。這兩個過程都可以使用容器叢集管理器(如Kubernetes)進行編排。資料來源:dzone.com
我們將在本文中介紹三個無伺服器框架各自的優點和缺點。這些FaaS框架之間的共同點是,它們能夠(1)將函式轉化為服務; (2)利用Kubernetes平臺管理這些服務的生命週期。這些框架背後的設計,會由於其用於實現的具體方式的不同而有差異,我們將在下一節中探討。我們將在以下部分中重點介紹這些框架之間的一些差異:
框架是在原始碼級別或Docker映象級別還是在中間執行,例如buildpacks?
由於使用公共語言執行庫啟動容器,冷啟動效能的延遲或執行函式期間的延遲分別是多少?
它們如何為服務分配記憶體或資源?
它們如何訪問和部署Kubernetes的編排和容器管理功能?
B. OpenFaaS和部署Spring Boot模板
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模板。
在本地安裝OpenFaaS
在本地計算機上下載和安裝模板
我們需要安裝和配置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"}複製程式碼
在Google Cloud Platform上安裝OpenFaaS
在使用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。
資料來源:dzone.com
使用基本身份驗證部署OpenFaaS。
克隆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>
C. Fission和部署簡單的HTTP請求
Fission是一個無伺服器框架,它進一步抽象出容器映象,並允許僅通過函式在K8s上建立HTTP服務。Fission中的容器映象包含語言執行時,一組常用的依賴項和一個用於函式的動態載入器。可以定製這些影像,例如打包二進位制依賴項。Fission能夠通過維護一個正在執行的容器池來優化冷啟動開銷。當新請求來自客戶端應用程式或業務服務時,它會將該函式複製到容器中,動態載入它,並將請求路由到該例項。因此,對於NodeJS和Python函式,它能夠最小化100毫秒的冷啟動開銷。
通過在原始碼級別進行操作,Fission使使用者不必處理容器的映象構建,將映象推送到登錄檔,管理登錄檔憑據,映象版本控制和其他管理任務。
https://kubernetes.io/blog/2017/01/fission-serverless-functions-as-service-for-kubernetes
如上圖所示,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!複製程式碼
D. Kubeless和部署Spring Boot模板
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
可以通過瀏覽器導航到http://localhost:8080/來訪問儀表板
2. 安裝Kubeless CLIOSX
$ 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
E.無伺服器平臺的評估
我們評估的每個無伺服器平臺都有其獨特的價值主張。使用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從事軟體實施和技術支援工作。
ServiceMesher社群資訊
微信群:聯絡我入群
Slack:servicemesher.slack.com 需要邀請才能加入
Twitter: twitter.com/servicemesh…
GitHub:github.com/
更多Service Mesh諮詢請掃碼關注微信公眾號ServiceMesher。