13 張圖帶你搞懂 Serverless

Serverless 是一種雲原生開發模型,可使開發人員專注構建和運行應用,而無需管理服務器。簡單來說 Serverless 就是讓你不與或少與運行應用程序所需的服務器和基礎設施進行交互,當今天我們提到 "serverless" 這個詞的時候通常它可以指 CaaS 和 FaaS 這兩種服務。

CaaS - 容器即服務

當我們創建容器後,把它扔到 CaaS 上,它就會自動運行、服務和擴展,比如 Azure Container Instances、Google Cloud Run 或 AWS Fargate 這些服務。

FaaS - 函數即服務

當我們寫好代碼,扔給 FaaS,它就會自動運行、服務和擴展。比如 Azure Functions、Google Functions 或者 AWS Lambda 這些服務。

FaaS 可以用不同的方式來運行你的代碼,一種方式可能是 FaaS 爲每一次代碼變化構建一個容器,就類似於使用 CaaS 這種服務。

FaaS 構建成容器發送給 CaaS

另一種方式是 FaaS 在啓動過程中動態地將函數的源碼拉到一個預定義的環境(容器)中,不同的語言會有不同的環境,當使用像 Go 這樣的編譯語言時,那麼編譯必須在啓動時進行。

事件或伸縮

FaaS 大多數時候與函數實例的觸發器事件系統一起使用,事件可以來源於 API 網關、Github、Kafka、RabbitMQ、CronJobs 等。

FaaS 封裝了與事件源的通信

對於每個事件,將創建一個新的函數來處理它,如果有多個事件同時發生,將創建多個實例來處理這些事件。這樣我們就有了自動伸縮的功能。

FaaS 與各種事件源進行通信,所以函數本身不需要去實現,它們只需要與 FaaS 使用的一種事件格式進行通信,比如 CloudEvents 或者通過 HTTP 傳輸。

Kubernetes 應用

下面讓我們來看看開發一個運行在 Kubernetes 上的傳統非 serverless 應用需要的步驟。

我們需要構建一個容器,創建各種 Kubernetes 資源清單文件,然後決定我們需要多少個工作節點來運行我們的應用程序。

我們需要多少個工作節點的可以通過配置一個 Cluster/Node autoscaler來動態地處理,但是我們仍然必須配置它,並且需要設置一個最小 + 最大的節點數量。

Kubernetes Serverless 應用

現在我們來探討一下爲 Kubernetes 開發應用時的 serverless 方法。

CaaS - 容器即服務

可以看到我們大大減少了需要創建的 Kubernetes 資源清單的數量,CaaS 將爲我們創建所有必要的子資源,比如 autoscaler、Ingress 或 Istio 路由。

我們要做的就是提供一個(Docker)容器,並創建一個單一的 k8s 資源,即通過 CRD 引入的 CaaS - 容器資源。CaaS 決定什麼時候啓動我們應用的實例,以及啓動多少個,可能是基於事件或我們自定義的方式。

我們必須確保我們構建的容器能夠接收和處理來自 CaaS 的事件,例如可以通過 HTTP 或 CloudEvents,這可能需要容器內部的某些庫支持。

Knative 就是一個典型的 CaaS 服務,Knative 提供了靈活的構建模塊,其他解決方案也可以使用和依賴它。

FaaS - 函數即服務

在 FaaS 服務中的 function.yml 文件中將包含一個來自 FaaS 系統的 K8s 資源,通過 CRD 引入,在該資源中,我們可以配置函數名稱、源代碼位置、語言運行時和觸發事件等內容。

有了 FaaS,我們也就擁有了 CaaS 解決方案的一切能力了,現在我們進一步減少了工作量,因爲我們有工具在 Kubernetes 集羣中運行,可以直接執行 / 構建我們的應用源代碼。

爲我們構建的容器已經包含了必要的庫,比如 HTTP 或 CloudEvents,來接收來自 FaaS 的事件,所以我們不必擔心這個問題。

源碼可能存儲在 Git 倉庫中,也可能是通過 web 界面上傳的,或者是在其他地方提供的。FaaS 將訪問代碼,監聽變化,構建容器,然後將其傳遞給 CaaS,用於服務終端事件。

TriggerMesh 的 web 界面,用於上傳代碼並作爲一個函數進行部署

冷熱啓動

冷啓動將意味着沒有 Pod 已經在運行處理事件,所以需要一些時間來創建它。通常情況下,這些 Pod 在最後一次使用後會保持一段時間,可以重複使用。在 "已經運行" 期間的調用被稱爲熱啓動,熱啓動的速度較快,但也會消耗資源。

Fission

Fission 是一個典型的運行在 Kubernetes 環境下面的 Faas 服務,實際上並沒有爲每個函數的代碼變化構建一個不可變的容器,而是使用了可變的環境容器("Generic pods")的概念,動態地將代碼拉進來,然後將這些容器轉換成 "Specific Function pods",這也是 AWS Lambda 使用用 AWS Firecracker 的工作方式。

可觀測性

從容器化的微服務轉向函數,可能會導致不得不管理比以前更多、更小的服務。這是因爲創建小型函數是很容易的,這些函數只是監聽和處理一個單一事件。

爲了管理更多的服務或功能,所以非常有必要保持可觀察性(指標、日誌、跟蹤),這就是爲什麼大多數 Kubernetes 的 FaaS 和 CaaS 已經與 Prometheus、Jaeger 和 Istio 或 Linkerd 等服務網格進行了集成。

Kubernetes Serverless 節點

上面我們談到了 K8s Serverless 應用,我們看到了使用 CaaS 或 FaaS 時的工作流程,這些服務減少了我們很多重複性的工作。

但是開發人員或運維人員仍然在與服務器交互:作爲集羣中的工作節點的虛擬機,他們仍然需要指定有多少節點以及它們的資源(CPU / 內存)。

下面我們來看下使用 Virtual Kubelet 讓實際的底層 Kubernetes 節點成爲 Serverless 節點。

FaaS 在 Kubernetes 之上,以 Virtual Kubelet 爲節點

Virtual Kubelet 給 Kubernetes 模擬了一個 worker 節點,然後可以調度 Pods 到上面來工作,就像其他普通節點一樣。雖然 Pods 的容器不是運行在虛擬機上,而是在雲提供商的無服務器容器產品中,如 AWS Fargate、Google Cloud Run 或 Azure Container Instances。

K8s Serverless 應用和 K8s Serverless 節點可能是一個強大的組合,但是,如果我們把所有的東西都 serverless 化了,那爲什麼還要使用 K8s 呢?

爲什麼還要用 Kubernetes

Kubernetes 提供了強大而靈活的構建功能,而不是爲了方便交互和終端用戶而生的的。這使得 K8s 變得很複雜,直接使用時需要大量的重複性工作。

Kubernetes 成爲一個獨立於雲提供商的標準,在上面使用 serverless 框架,在使用 serverless 時保持這種獨立性是有意義的,如果有必要的話,我們可以隨時對我們的應用進行更加詳細的定義,因爲它的下面仍然只是運行 K8s 而已。

通過在 K8s 上使用 serverless,我們可以減少很多重複性工作,這樣我們就可以花更多的時間來構建實際的應用了。

總結

最後我們來回顧下傳統的 K8s 應用和 serverless 應用的區別。

傳統 K8s 應用

Serverless 應用

我認爲現代 serverless 事件驅動的架構已經證明了自己的能力,並且在未來幾年會越來越普遍。Kubernetes 上的 Serverless 只是持續自動化掉手工作業的結果。

原文鏈接:https://itnext.io/kubernetes-serverless-simply-visually-explained-ccf7be05a689

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Hx7l1gc18W69tllp0B0rwA