本篇文章已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
Fission:Kubernetes 的無伺服器函數即服務
Fission 是一個建構於 Kubernetes 之上的函式即服務 (FaaS) / 無伺服器函式框架。
Fission 讓您可以從函式輕鬆地在 Kubernetes 上創建 HTTP 服務。它在原始碼層級運作,並將容器映像抽象化(在大多數情況下)。它還簡化了 Kubernetes 的學習曲線,讓您無需了解太多 Kubernetes 即可建立有用的服務。
要使用 Fission,您只需創建函式並使用 CLI 添加它們。您可以將函式與 HTTP 路由、Kubernetes 事件或其他觸發器關聯。目前 Fission 支援 NodeJS 和 Python。
函式在其觸發器觸發時被調用,並且僅在運行時消耗 CPU 和記憶體。閒置的函式不消耗任何資源,除了儲存空間。
為什麼要在 Kubernetes 上建立 FaaS 框架?
我們認為需要一個可以在各種基礎設施上運行的 FaaS 框架,無論是在公有雲還是本地基礎設施中。接下來,我們必須決定從頭開始構建,還是基於現有的協調系統之上。很快就清楚了,我們不應該從頭開始構建——我們最終只會重新發明叢集管理、排程、網路管理等等。
Kubernetes 提供了一個強大而靈活的協調系統,具有由強大且不斷成長的社群支持的完整 API。基於它構建意味著 Fission 可以將容器協調功能留給 Kubernetes,並專注於 FaaS 功能。
我們不想要單獨的 FaaS 叢集的另一個原因是,FaaS 與其他基礎設施結合使用時效果最佳。例如,它可能非常適合小型 REST API,但它需要與其他服務協同工作以儲存狀態。FaaS 也非常適合作為事件處理程序機制,以處理來自儲存、資料庫和 Kubernetes 本身的通知。Kubernetes 是一個很棒的平台,可讓所有這些服務在其之上互操作。
部署和使用 Fission
可以使用 kubectl create
命令安裝 Fission:請參閱專案 README 以獲取說明。
以下是如何編寫「hello world」HTTP 服務的方法
$ cat \> hello.py
def main(context):
print "Hello, world!"
$ fission function create --name hello --env python --code hello.py --route /hello
$ curl http://\<fission router\>/hello
Hello, world!
Fission 負責將函式載入到容器中、將請求路由到它等等。我們將在下一節中詳細介紹。
Fission 如何在 Kubernetes 上實作
從核心上講,FaaS 框架必須 (1) 將函式轉變為服務,以及 (2) 管理這些服務的生命週期。
有許多方法可以實現這些目標,每種方法都有不同的權衡。框架應該在原始碼層級運作,還是在 Docker 映像層級運作(或介於兩者之間的東西,例如「buildpacks」)?函式第一次運行時,可接受的開銷量是多少?這裡做出的選擇會影響平台靈活性、易用性、資源使用和成本,以及效能。
打包、原始碼和映像
我們的目標之一是讓新使用者非常容易使用 Fission。我們選擇在
原始碼層級運作,以便使用者可以避免處理容器映像建構、將映像推送到登錄檔、管理登錄檔憑證、映像版本控制等等。
然而,容器映像是打包應用程式最靈活的方式。純粹的原始碼層級介面不允許使用者打包二進制依賴項,例如。
因此,Fission 採用混合方法——包含函式動態載入器的容器映像。這種方法允許大多數使用者純粹在原始碼層級使用 Fission,但也使他們能夠在需要時自訂容器映像。
這些映像在 Fission 中稱為「環境映像」,包含語言的運行時(例如 NodeJS 或 Python)、一組常用的依賴項和函式的動態載入器。如果這些依賴項對於使用者正在編寫的函式來說足夠,則不需要重建映像。否則,可以修改依賴項列表,並重建映像。
這些環境映像是 Fission 中唯一特定於語言的部分。它們為框架的其餘部分提供統一的介面。這種設計使得 Fission 可以輕鬆擴展到更多語言。
冷啟動效能
無伺服器函式的目標之一是函式僅在運行時使用 CPU/記憶體資源。這優化了函式的資源成本,但代價是在從閒置狀態啟動時會產生一些效能開銷(「冷啟動」開銷)。
冷啟動開銷在許多使用案例中都很重要。特別是,對於在互動式使用案例中使用的函式(例如 Web 或行動應用程式,使用者正在等待操作完成),幾秒鐘的冷啟動延遲將是不可接受的。
為了優化冷啟動開銷,Fission 為每個環境保留一個正在運行的容器池。當收到對函式的請求時,Fission 不必部署新容器——它只是選擇一個已經在運行的容器,將函式複製到容器中,動態載入它,並將請求路由到該實例。對於 NodeJS 和 Python 函式,此過程的開銷約為 100 毫秒。
Fission 如何在 Kubernetes 上運作
Fission 被設計為一組微服務。控制器追蹤函式、HTTP
路由、事件觸發器和環境映像。池管理器管理閒置環境容器池、將函式載入到這些容器中,以及在函式實例閒置時終止它們。路由器接收 HTTP 請求並將其路由到函式實例,並在必要時從池管理器請求實例。
控制器提供 fission API。所有其他組件都監控控制器以獲取更新。路由器作為 Kubernetes 服務公開,類型為 LoadBalancer 或 NodePort,具體取決於 Kubernetes 叢集的託管位置。
當路由器收到請求時,它會查找快取,看看此請求是否已有應路由至的服務。如果沒有,它會查找將請求對應到的函數,並向 poolmgr 請求一個執行個體。poolmgr 有一個閒置 Pod 池;它會選擇一個 Pod,將函數載入其中(透過向 Pod 中的 Sidecar 容器發送請求),並將 Pod 的位址返回給路由器。路由器會將請求代理到此 Pod。此 Pod 會被快取以供後續請求使用,如果閒置幾分鐘,則會被終止。
(目前,Fission 將一個函數對應到一個容器;擴展到多個執行個體的自動擴展功能計劃在後續版本中推出。重複使用函數 Pod 來託管多個函數也在計畫中,適用於不要求隔離的情況。)
Fission 的使用案例
機器人、Webhook、REST API
Fission 是一個很好的框架,可以用於建立小型 REST API、實作 Webhook,以及為 Slack 或其他服務編寫聊天機器人。
作為一個簡單 REST API 的範例,我們建立了一個小型留言簿應用程式,它使用函數來讀取和寫入留言簿,並與 Redis 執行個體協作來追蹤狀態。您可以在 Fission GitHub 儲存庫中找到該應用程式:Fission GitHub repo。
該應用程式包含兩個端點 -- GET 端點列出 Redis 中的留言簿條目,並將其呈現為 HTML。POST 端點將新條目新增到 Redis 中的留言簿清單。這就是全部內容 -- 無需管理 Dockerfile,更新應用程式就像呼叫 fission function update 一樣簡單。
處理 Kubernetes 事件
Fission 也支援根據 Kubernetes 監看觸發函數。例如,您可以設定一個函數來監看特定命名空間中符合特定標籤的所有 Pod。該函數會在其上下文中取得序列化物件和監看事件類型(新增/移除/更新)。
這些事件處理函數可用於簡單的監控 -- 例如,您可以在每次向叢集新增新服務時發送 Slack 訊息。還有更複雜的使用案例,例如透過監看 Kubernetes 的第三方資源來編寫自訂控制器。
狀態和 Roadmap
Fission 目前處於早期 Alpha 階段(2017 年 1 月)。它尚未準備好用於生產環境。我們正在尋找早期採用者和回饋。
Fission 的未來發展是什麼?我們正致力於使 Kubernetes 上的 FaaS 更方便、易於使用且更容易整合。在未來幾個月,我們將致力於新增對單元測試、與 Git 整合、函數監控和日誌聚合的支援。我們也正在努力與其他事件來源整合。
建立更多語言環境也在進行中。目前支援 NodeJS 和 Python。Klavs Madsen 已貢獻了對 C# .NET 的初步支援。
您可以在我們的 GitHub issues 和 projects 上找到我們目前的 Roadmap。
參與其中
Fission 是由 Platform9 Systems 開發的開放原始碼專案。在 GitHub 上查看我們,如果您想與我們聊天,請加入我們的 Slack 頻道。我們也在 Twitter 上:@fissionio。
- 下載 Kubernetes
- 參與 Kubernetes 專案,請訪問 GitHub
- 在 Stack Overflow 上發布問題(或回答問題)
- 在 Slack 上與社群聯繫
- 在 Twitter 上關注我們 @Kubernetesio 以獲取最新更新