OpenFunction[1] 是一個現代化的雲原生 FaaS(函式即服務)框架,它引入了很多非常優秀的開源技術棧,包括 Knative、Tekton、Shipwright、Dapr、KEDA 等,這些技術棧為打造新一代開源函式計算平臺提供了無限可能:
- Shipwright 可以在函式構建的過程中讓使用者自由選擇和切換映象構建的工具,並對其進行抽象,提供了統一的 API;
- Knative 提供了優秀的同步函式執行時,具有強大的自動伸縮能力;
- KEDA 可以基於更多型別的指標來自動伸縮,更加靈活;
- Dapr 可以將不同應用的通用能力進行抽象,減輕開發分散式應用的工作量。
OpenFunction 最新發布了0.6版本,而且2022 年 4 月 27 日,OpenFunction[1] 順利通過了雲原生計算基金會 CNCF 技術監督委員會(TOC)的投票,正式進入 CNCF 沙箱(Sandbox)託管。OpenFunction 也將真正變成一個由 100% 社群驅動的開源專案。最近我也加入了OpenFunction專案開始規劃dotnet的支援開發,dotnet 框架支援的倉庫[2],目前完成0.1版本的開發。
經過我這2周時間的摸索,本文將會帶領大家快速部署和上手 OpenFunction,並通過一個 demo{hello-world-dotnet} 來體驗同步函式是如何運作的,以便對函式計算有一個感性的認知。
OpenFunction CLI 介紹
OpenFunction 從 0.5 版本開始使用全新的命令列工具 ofn[3] 來安裝各個依賴元件,它的功能更加全面,支援一鍵部署、一鍵解除安裝以及 Demo 演示的功能。使用者可以通過設定相應的引數自定義地選擇安裝各個元件,同時可以選擇特定的版本,使安裝更為靈活,安裝程式也提供了實時展示,使得介面更為美觀。它支援的元件和其依賴的 Kubernetes 版本如下:
ofn 的安裝引數 ofn install
解決了 OpenFunction 和 Kubernetes 的相容問題,會自動根據 Kubernetes 版本選擇相容元件進行安裝,同時提供多種引數以供使用者選擇。
使用 OpenFunction CLI 部署 OpenFunction
有了命令列工具 ofn 之後,OpenFunction 部署起來非常簡單。首先需要安裝 ofn,以 amd64 版本的 Linux 為例,僅需兩步即可:
1、下載 ofn,最新的ofn 是0.5.3
$ wget -c https://github.com/OpenFunction/cli/releases/download/v0.5.3/ofn_linux_amd64.tar.gz -O - | tar –xz
2、為 ofn 賦予許可權並移動到 /usr/local/bin/
資料夾下。
$ chmod +x ofn && mv ofn /usr/local/bin/
安裝好 ofn 之後,僅需一步即可完成 OpenFunction 的安裝。雖然使用 --all
選項可以安裝所有元件,也可以選擇安裝指定需要安裝的元件,我們的叢集裡面已經安裝了Dapr的情況下,我們就不想額外安裝一遍Dapr ,不過如果叢集裡面已經安裝了Dapr的情況下他也不會給重新安裝的,具體可以看下圖。
安裝成功了,之後我們就可以開始執行同步函式了,OpenFunction 還支援非同步函式,這部分今天就不演示了,留作後續在dotnet框架裡面實現了非同步函式的時候再來。
同步函式 demo 示例
OpenFunction 官方倉庫提供了多種語言的同步函式示例[4]:
這裡我們選擇 dotnet 的函式示例,先來看一下最核心的部署清單:
apiVersion: core.openfunction.io/v1beta1
kind: Function
metadata:
name: dotnet-sample
namespace: default
spec:
version: "v1.0.0"
image: "geffzhang/sample-dotnet-func:v1"
imageCredentials:
name: push-secret
port: 8080 # default to 8080
build:
builder: "openfunction/gcp-builder:v1"
env:
GOOGLE_FUNCTION_TARGET: "helloworld"
GOOGLE_FUNCTION_SIGNATURE_TYPE: "http"
srcRepo:
url: "https://github.com/openfunction/samples.git"
sourceSubPath: "functions/knative/hello-world-dotnet"
revision: "release-0.6"
serving:
runtime: "knative" # default to knative
template:
containers:
- name: function
imagePullPolicy: IfNotPresent
Function
是由 CRD 定義的一個 CR,用來將函式轉換為最終執行的應用。這個例子裡面包含了兩個元件:
- build : 通過 Shipwright 選擇不同的映象構建工具,最終將應用構建為容器映象;
- Serving : 通過 Serving CRD 將應用部署到不同的執行時中,可以選擇同步執行時或非同步執行時。這裡選擇的是同步執行時 knative。
執行這個示例之前,需要在執行函式的名稱空間下建立Secret ,生成一個Secret 來訪問您的容器登錄檔,例如Docker Hub[5] 或Quay.io[6] 上的一個。這一點非常重要,不然就在Build 階段就失敗了。
REGISTRY_SERVER
您可以通過編輯以下命令中的REGISTRY_USER
和欄位來建立此金鑰REGISTRY_PASSWORD
,然後執行它。
REGISTRY_SERVER=https://index.docker.io/v1/ REGISTRY_USER= < your_registry_user > REGISTRY_PASSWORD= < your_registry_password >
kubectl create secret –n default docker-registry push-secret \
--docker-server= $REGISTRY_SERVER \
--docker-username= $REGISTRY_USER \
--docker-password= $REGISTRY_PASSWORD
然後將上面的部署清單儲存為function-dotnet-sample.yaml ,修改spec.image 欄位為您自己的容器登錄檔地址,使用以下命令建立此函式:
kubectl apply –f function-dotnet-sample.yaml
在Build 階段,builder會啟動一個 Pod 來構建映象,這個 Pod 中包含了 4 個容器:
- step-source-default : 拉取原始碼;
- step-prepare : 設定環境變數;
- step-create : 構建映象;
- step-results : 輸出映象的 digest。
您可以使用以下命令觀察函式的過程。
kubectl get functions -n default
NAME BUILDSTATE SERVINGSTATE BUILDER SERVING URL AGE
dotnet-sample Succeeded Running builder-hf74t serving-wh6hs http://openfunction.io/default/dotnet-sample 54m
URL
是OpenFunction Domain提供的可以訪問的地址。要通過此 URL 地址訪問該功能,您需要確保 DNS 可以解析此地址。使用以下命令在叢集中建立一個 pod,並從該 pod 訪問該功能
kubectl run curl --image=radial/busyboxplus:curl -i –tty
[ root@curl:/ ]$ curl http://openfunction.io.svc.cluster.local/default/dotnet-sample/
還可以通過 Knative Services 提供的訪問地址觸發該功能
kubectl get ksvc
geffzhang@edgevm1:~/openfunctionsamples/functions/knative/hello-world-dotnet$ sudo kubectl get ksvc
NAME URL LATESTCREATED LATESTREADY READY REASON
serving-wh6hs-ksvc-m7fc9 http://serving-wh6hs-ksvc-m7fc9.default.20.239.115.228.sslip.io serving-wh6hs-ksvc-m7fc9-v100 serving-wh6hs-ksvc-m7fc9-v100 True
這個地址是可以直接訪問的
訪問這個函式時會自動觸發執行一個 Pod:
這個 Pod 使用的映象就是之前 build 階段構建的映象。事實上這個 Pod 是由 Deployment 控制的,在沒有流量時,這個 Deployment 的副本數是 0。當有新的流量進入時,會先進入 Knative 的 Activator,Activator 接收到流量後會通知 Autoscaler(自動伸縮控制器),然後 Autoscaler 將 Deployment 的副本數擴充套件到 1,最後 Activator 會將流量轉發到實際的 Pod 中,從而實現服務呼叫。這個過程也叫冷啟動。
如果你不再訪問這個入口,過一段時間之後,Deployment 的副本數就會被收縮為 0:
通過上面的示例,相信大家應該能夠體會到一些函式計算的優勢,我們只需要專注於業務開發,編寫函式程式碼,並上傳到程式碼倉庫,其他的東西不需要關心,就連Dockerfile都不需要編寫,不需要了解基礎設施,甚至不需要知道容器和 Kubernetes 的存在。函式計算平臺會自動為您分配好計算資源,並彈性地執行任務,只有當您需要訪問的時候,才會通過擴容來執行任務,其他時間並不會消耗計算資源,可以充分利用dotnet在雲原生時代的優勢,使用dotnet寫函式是很高效的,大家可以體驗一下我上面的示例http://serving-wh6hs-ksvc-m7fc9.default.20.239.115.228.sslip.io 。OpenFunction基於Dapr 所提供的各種分散式能力,讓我們輕鬆的實現無服務微服務架構,獲得像Azure 容器應用[7] 一樣的能力。
相關連結
[1] openFunction: https://github.com/OpenFunction/OpenFunction
[2] functions-framework-dotnet: https://github.com/OpenFunction/functions-framework-dotnet
[3] ofn: https://github.com/OpenFunction/cli
[4] OpenFunction 官方倉庫提供了多種語言的同步函式示例: https://github.com/OpenFunction/samples/tree/main/functions/knative
[5] Docker Hub: https://hub.docker.com/
[6] Quay.io: https://quay.io/
[7] Azure 容器應用: https://www.cnblogs.com/shanyou/p/15509042.html