函數計算平臺 OpenFunction 在自動駕駛領域的應用

嘉賓 | 霍秉傑 整理 | 王新

出品 | CSDN 雲原生

2022 年 5 月 10 日,在 CSDN 雲原生系列在線峯會第 4 期“ApacheSkyWalking 峯會”上,青雲科技資深架構師霍秉傑分享了 SkyWalkingv9 如何幫助 OpenFunction 實現函數可觀測。

Serverless: 下一波浪潮

file

隨着技術的發展,人們越來越少關注底層技術棧的一些細節,越來越多關注自己應用的商業邏輯。CNCF 發佈的 Serverless 白皮書印證了這一點。

如上圖所示,從下往上,最底層是 CaaS(Container as a Service),它向下抽象和屏蔽了基礎設施的差異,向上提供了一個應用運行的平臺,用戶對基礎設施和應用有相對全面和靈活的掌控。

中間層是 PaaS(Platform as a Service),主要分爲兩類,一類是傳統的 PaaS 平臺,例如 Cloud Foundry、Heroku; 另一類則是容器平臺,例如 OpenShift、KubeSphere,它們可以提供 Kubernetes 沒有的一些能力,比如用戶的鑑權、認證與管理,可觀測性包括監控、告警、日誌、事件與審計,服務網格,還有 CI/CD 等。這使得用戶可以更加關注於開發和部署應用,其他可以依賴平臺提供的能力。

最上層是 FaaS(Function as a Service),包括雲廠商的函數計算服務和開源的函數計算平臺。在 FaaS 這層,用戶更多關注自己應用的業務邏輯部分,其他的方面都交給平臺去處理。

爲什麼需要一個雲廠商中立的 FaaS 平臺?

近幾年我們越來越多地聽到多雲、分佈式雲、混合雲這樣的提法,其中原因應該是 Kubernetes 帶來了雲廠商中立的可能性,於是很多公司開始基於 Kubernetes 去做多雲、分佈式雲、混合雲的方案或產品。但是在 FaaS 領域卻很難實現廠商中立,因爲每個雲廠商都有自己的 FaaS 平臺,通常這些雲廠商的 FaaS 平臺都會和自己雲上的後端服務綁定。CNCF Serverless 白皮書其實也提到了這一點:各個廠商由於編程模型,事件及消息接口,還有後端服務的不同導致用了一個廠商的 FaaS 平臺後,就很難遷移到別的廠商的 FaaS 平臺。

如何構建一個雲廠商中立的 FaaS 平臺?

那麼有沒有可能去構建一個雲廠商中立的 FaaS 平臺?如何去構建這樣一個平臺?首先不開源肯定是不太可能做到廠商中立的,不開源就成了另一個廠商。

CNCF 的 Serverless 白皮書在 2018 年發佈,裏面提到 Serverless 缺乏標準化,成熟度方面也有所欠缺。四年過去了,其實這兩個方面都有所改觀。首先標準化方面,據 CNCF 2021 年的調查報告顯示正在使用以及正在評估使用 Kubernetes 的受訪者已經達到創紀錄的 96%,Kubernetes 逐漸走向底層成爲更上層平臺和服務的基礎設施;此外四年以來雲原生 Serverless 領域也有了很多進展,其中最著名的 Knative 就是在 2018 年開源的,四年以來 Knative 已經發布了 v1.0 版並且現在已經捐給了 CNCF。本文不會過多介紹 Knative,而是會着重介紹另外兩個雲原生 Serverless 領域的技術,Dapr 和 KEDA。

KEDA 全稱是 Kubernetes Event-driven Autoscaling。顧名思義 KEDA 主要用於 Kubernetes 上分佈式應用的自動伸縮,其獨特之處在於可根據衆多事件源特有的指標進行伸縮,包括開源的中間件及各大雲廠商的後端服務等事件源。我們可以用 KEDA 來解耦事件源與分佈式應用的自動伸縮,KEDA 使得應用可以根據使用中間件或服務的特有指標進行伸縮,無論該中間件或服務是雲上託管的還是開源的。

file

Dapr 全稱是分佈式應用運行時,它是把分佈式應用的各種能力抽象成多個 Building Block,比如有的應用有狀態管理的需求,需要存取一些狀態,Dapr 有一個 State Management 的 Building Block 可以提供這方面的能力;有一些事件驅動的分佈式應用,有發佈訂閱的需求,Dapr 有一個 pubsub 的 Building Block 可以提供這方面的能力;再比如很多應用都有輸入和輸出,於是 Dapr 提供了 Input/Output Binding 的 Building Block。總之,使用 Dapr 可以把分佈式的應用和其依賴的後端服務進行解耦。

file

具體來說一般 FaaS 平臺都需要支持多語言,通常需要和多種後端服務去打交道。我們假設一個 FaaS 平臺需要支持 5 種語言並且需要和 10 個 message queue 去對接。不用 Dapr 的情況下,每種語言都得用每個 message queue 該語言的 SDK 去對接這個 message queue,總共就會有 50 種實現;在使用 Dapr 的情況下,每種語言僅需要用 Dapr 的 SDK 去和 Dapr 對接,再由 Dapr 去和各個 message queue 對接,這時候只需要 5 種實現。可以看到在引入了 Dapr 之後,極大地降低了 FaaS 平臺的複雜度。

file

相當於我們在 Serverless 的 FaaS 和 BaaS 之間額外添加了一層 Dapr。

file

Dapr 相當於 FaaS 訪問 BaaS 的一個統一的接口。

file

幾個星期之前我們把如何在 OpenFunction 中使用 Dapr 和 Dapr 全球社區做了一個分享,Dapr 的兩位聯合創始人 Mark 和 Yaron 對 OpenFunction 這種用法很欣賞,也很高興看到 Dapr 被應用到越來越多的 Serverless Function runtimes 中。

file

OpenFunction 簡介

file

OpenFunction 主要由 3 個部分組成: Build,Serving 和 Events. 在 Build 和 Serving 之上還有一層抽象 Function, 由 Function 來控制函數的 Build 和 Serving. Function 是用戶和 OpenFunction 交互的統一接口,用戶無需和 Build 以及 Serving 打交道。

Build 主要負責把函數的代碼構建成函數的鏡像。採用的是 Cloud Native Buildpacks 技術,這也是最近幾年湧現出來的一個雲原生構建技術,它的特點就是不需要依賴 Dockerfile 就能夠把函數的鏡像給 build 出來。目前已被 Google Cloud,IBM Cloud,VMWare, Heroku 等公司採用。現在 OpenFunction 也支持用另外三種依賴於 Dockerfile 的構建技術去 build 應用包括 buildah, BuildKit 和 Kaniko. 以後也會陸續支持用這些依賴於 Dockerfile 的構建技術去構建函數鏡像。

Serving 應該是 OpenFunction 中最關鍵的部分,主要負責運行函數。目前 Serving 包含了同步和異步兩個函數運行時。同步函數目前支持用 Knative 作爲運行時,我們也計劃支持用 KEDA http-addon 作爲另一個同步函數運行時,目前我們已經有 Maintainer 積極參與到了這個項目中。OpenFunction 比較有特色的應該是它的異步函數運行時。很少看到在開源或者是雲廠商的 FaaS 平臺裏有專門的異步函數運行時,如果有異步函數也多是通過把事件源的事件轉換成一個 HTTP 的請求後再去處理。OpenFunction 的異步函數是直接對接事件源的,由 KEDA 和 Dapr 構成,這是 OpenFunction 所特有的。

OpenFunction Events 的作用類似 Knative Eventing. 但是 Knative Eventing 在設計與使用上都過於複雜,於是 OpenFunction 受 Argo Events 的啓發設計了自己的事件管理框架 OpenFunction Events,其由 EventSource, Sink, EventBus 和 Trigger 等部分組成。

OpenFunction Build

file

當一個函數創建後,Function 會創建一個 Builder,Builder 會創建 Shipwright 的 Build 和 BuildRun,結合 Shipwright 的 BuildStrategy, Shipwright 會生成 Tekton 的 TaskRun,TaskRun 中包含多個 Step,函數代碼就是在這些 Step 的控制下構建成函數鏡像。

OpenFunction Serving

file

如前所述,OpenFunction 現在支持 Knative 同步函數運行時和 OpenFunction 異步函數運行時。二者都可以和 Dapr 集成,區別在於 Knative 同步函數運行時因爲輸入來自 HTTP 請求,只用到了 Dapr 的 output binding 和 pubsub 的 publish 部分;而 OpenFunction 異步函數運行時的輸入和輸出都是通過 Dapr 對接中間件或雲服務,所以用到了 Dapr 的 input 和 output binding 或 pubsub 的 publish 和 subscribe.

我們未來計劃支持 KEDA http-addon 作爲另一個同步函數運行時,同時也將探討通過 pool 的技術優化函數冷啓動的時間。

OpenFunction Events

file

OpenFunction Events 是受 Argo Events 啓發,其和 Argo Events 的不同之處在於 OpenFunction 的 EventBus 由於使用了 Dapr 的 pubsub 與底層的 message queue 是解耦的,這意味着它並不會綁定到某個雲平臺或者開源軟件上。當 EventSource 收到外部事件後,有兩條路徑:它可以直接觸發一個同步函數,也可以將事件寫入到 EventBus 進行持久化。事件寫入 EventBus 後也有兩種處理方式:它可以直接觸發一個異步函數;也可以定義一個 Trigger 來對事件進行篩選,篩選出感興趣事件後,可觸發一個同步函數,或者將篩選出的事件寫回到 EventBus 作爲輸出。

OpenFunction Functions Framework

file

Functions Framework 是 OpenFunction 的另一個重要組成部分,由 context、plugins、Runtime、Framework 這構成。Framework 讀取 OpenFunction 的 Context,將 Function 的上下文讀取出來,並且查看這個函數有沒有插件,如果有的話則將插件註冊進來,然後創建 Runtime 並且啓動。當同步或者異步函數觸發後,由 Runtime 控制函數運行的生命週期。首先會執行插件的 pre-phase hooks,再調用用戶函數,之後調用插件的 post-phase hooks, 最後處理這個函數輸出。

加入插件的機制的很大一部分原因是想在這個函數執行的前後,執行一些用戶不需要關心的自定義邏輯。比如 OpenFunction 和 SkyWalking 的集成,就需要在這個函數執行前後做一些處理,這個我們稍後展開。

FaaS 可觀測性: SkyWalking v9 助力 OpenFunction 實現函數可觀測

函數的性能對用戶來說比較重要,於是經過和 SkyWalking 社區的充分討論和合作,OpenFunction 在 v0.6.0 實現了與 SkyWalking 的集成,用戶經過簡單的配置就能通過 SkyWalking v9 監測函數的性能。

file

以上面的同步函數觸發異步函數爲例,爲了監測同步和異步函數的性能,用戶只需要在函數的 annotation 做如下配置即可(也可以將配置放入 configmap 以對所有函數生效):

file

做好上述 tracing 的配置,部署函數後,用戶將可以在 SkyWalking V9 的 FaaS 頁面看到如下函數調用鏈及性能數據:

file

完整示例詳見:https://github.com/OpenFunction/samples/tree/main/functions/tracing

SkyWalking 與 OpenFunction 集成 Demo 詳見:http://demo.skywalking.apache.org/functions

Case Study: OpenFunction 在自動駕駛領域的應用

OpenFunction 有個社區用戶馭勢科技是自動駕駛行業的,他們把 OpenFunction 應用於自動駕駛,下面我們看看 OpenFunction 在馭勢科技的應用。

馭勢科技自動駕駛場景

file

如上圖所示,自動駕駛的場景比較複雜,設計的模塊比較多包括車輛檢測、調度命令分發、環境感知、行人規避、路由規劃、底盤控制、多車協同等等。

爲什麼自動駕駛廠商需要一個雲廠商中立的 FaaS 平臺?

原因有以下幾點:

  • 不同的客戶要求部署到不同的雲廠商
  • 一些客戶的車端數據比較敏感,要求放到和公有云隔離的環境
  • 數據處理邏輯多樣,來自同一數據源的數據在不同場景下的處理邏輯不盡相同
  • 數據處理邏輯經常變化
  • 自動駕駛涉及的模塊較多,不同的模塊由不同的團隊負責,需要多語言支持
  • 大量車端數據需要實時處理
  • 自動駕駛車輛也有潮汐的特性,數據處理需求有高峯和低谷

file

此外,不同的雲廠商有不同的後端服務,如果沒有一個雲廠商中立的 FaaS 平臺,對於同一處理邏輯則需要爲對接的每一個雲廠商都實現相似的實現。

file

使用 OpenFunction 同步與異步函數處理車輛數據

馭勢科技使用 OpenFunction 處理車端數據的歸檔:

  • 同步函數接收請求並分解任務併發送至消息隊列
  • 消息隊列中的子任務觸發異步函數運行
  • 用不同語言編寫的異步函數處理不同的子任務,並將處理結果發送至不同的後端服務
  • 利用消息隊列解耦生產者和消費者函數

file

FaaS 應用場景概覽

據 CNCF Serverless 白皮書所示,FaaS 可以應用到如下衆多場景中去:

  • HTTP REST APIs for web applications
  • Mobile backends
  • Executing logic in response to storage changes like S3, database (insert, update, trigger, delete)
  • Performing analytics on IoT sensor input messages (such as MQTT messages)
  • Stream processing at scale (ETL, analyzing or modifying data in motion)
  • Business logic like order processing, stock trade processing
  • Chatbot
  • Serving machine learning and AI models
  • Batch jobs or scheduled tasks: Jobs that require intense parallel computation, IO, or network for only a few minutes
  • Continuous integration pipelines

概括地說,Serverless 架構主要解決 IaaS, PaaS, CaaS 無法高效解決或解決不了的問題:

  • 高效地解決新問題:Solved a brand new problem efficiently where an on-demand model wasn’t available
  • 高效地解決老問題:Solved a traditional cloud problem much more efficiently (performance, cost)
  • 解決“大”的問題:Showed a dimension of “largeness”, whether in size of data processed or requests handled
  • 解決彈性的問題:Showed resilience by scaling automatically (up and down) with a low error rates
  • 解決快的問題:Brought a solution to market much faster than previously possible (days to hours)

OpenFunction 社區

OpenFunction 已經逐漸被越來越多的公司採用:

  • 國內某電信公司採用 OpenFunction 構建雲函數計算平臺
  • 馭勢科技 (UISEE) 採用 OpenFunction 處理車端數據
  • 全象低代碼平臺採用 OpenFunction 實現插件機制

也有越來越多的社區貢獻者參與到了 OpenFunction 項目中來:

  • 主要 Maintainer 來自 KubeSphere 團隊
  • SkyWalking PMC 成員張偉 @arugal 實現了 SkyWalking 和 OpenFunction Go 版 Functions Framework 的集成
  • 馭勢科技 (UISEE) 正在參與 Nodejs 和 Python 版 Functions Framework 的開發
  • 全象團隊參與了命令行工具 ofn 的開發
  • @Geffzhang 正在參與 dotNet 版 Functions Framework 的開發

OpenFunction 已經在 2022 年 4 月 26 日經 CNCF 技術監督委員會(TOC)投票被正式接納爲 CNCF 沙箱項目,歡迎更多的社區貢獻者參與到 OpenFunction 項目中來。

file

加入 OpenFunction 社區:

OpenFunction 路線圖

OpenFunction 將在之後的開發中,將重點放在如下功能上:

  • 支持更多語言的異步函數框架包括 Nodejs, Python, Java 和 .NET
  • 支持將 Java 函數編譯成 Native 程序運行在 Quarkus 環境中
  • 使用 KEDA 的 http-add-on 作爲 Knative Serving 之外同步函數運行時的又一個選擇
  • 支持 OpenTelemetry 生態作爲 SkyWalking 之外的另一個函數 Tracing 的方案
  • 增加 OpenFunction 控制檯
  • 實現 Serverless 工作流
  • 對在邊緣運行的函數有更好的支持
  • 預研基於 Pool 的冷啓動優化方案
  • 使用 WebAssembly 作爲更加輕量的運行時,結合 Rust 函數來加速冷啓動速度

函數示例

下面是兩個函數的例子,一個異步函數,一個同步函數觸發異步函數。

異步函數示例

下面是用異步函數進行日誌告警的例子,K8s 的日誌被收集併發送到 Kafka 後可以觸發異步函數,異步函數找到日誌中的某些錯誤後可以發送告警到 Notification Manager,最後 Notification Manager 會發通知到 Slack。

函數的代碼及定義詳見:https://github.com/OpenFunction/samples/tree/main/functions/async/logs-handler-function。

file

同步函數觸發異步函數

下面是一個同步函數觸發異步函數的例子,同步函數接收 HTTP 請求,處理後將處理結果通過 Dapr 發送到 Kafka,Kafka 中的 Event 進而會觸發異步函數。

同步函數的代碼及定義詳見:https://github.com/OpenFunction/samples/tree/main/functions/knative/with-output-binding。

異步函數的代碼及定義詳見:https://github.com/OpenFunction/samples/tree/main/functions/async/bindings/kafka-input。

file

​controller-manager 被重啓後,同樣會根據配置的變化,把部分資源類型自動轉化成聯邦資源的邏輯,也就是說,在 Host 集羣創建的這部分資源會自動同步到所有成員集羣,實際的多集羣同步靠 kubefed-controller-manager 來執行。以下資源會被自動創建聯邦資源下發:

本文由博客一文多發平臺 OpenWrite 發佈!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章