當前位置:
首頁 > 最新 > 使用Istio控制Serverless架構Fn Project中的函數間流量路由

使用Istio控制Serverless架構Fn Project中的函數間流量路由

作者:Peter Jausovec

譯者:殷龍飛

校對:宋凈超

在本文中,我將解釋如何在 Fn 函數之間使用 Istio 服務網格實現基於版本的流量路由。

我將首先解釋 Istio 路由的基礎知識以及將 Fn 部署和運行在 Kubernetes 上的方式。最後,我將解釋我是如何利用 Istio 服務網格及其路由規則在兩個不同的 Fn 函數之間路由流量的。

請注意,接下來的解釋非常基本和簡單——我的目的不是解釋 Istio 或 Fn 的深入細節,而是解釋得足夠清楚,讓您可以了解如何使自己的路由工作。


讓我花了一點時間來解釋 Istio 路由如何工作。Istio 使用 sidecar 容器( )注入到您部署的應用中。注入的代理會劫持所有進出該 pod 的網路流量。部署中所有這些代理的集合與 Istio 系統的其他部分進行通信,以確定如何以及在何處路由流量(以及其他一些很酷的事情,如流量鏡像、故障注入和斷路由)。

為了解釋這是如何工作的,我們將開始運行一個 Kubernetes 服務( )和兩個特定版本的應用程序部署( 和 )。

在上圖中,我們有 一個選擇器設置為 Kubernetes 的服務 ?,這意味著它將查找具有 標籤集的所有 Pod,並將流量發送給它們。基本上,如果您執行此操作, 您將從運行 v1 版本應用程序的 pod 或運行 v2 版本的 pod 獲得響應。

我們還有兩個 Kubernetes 部署,這些部署 運行了 v1 和 v2 代碼。除 標籤外,每個 pod 還將 標籤設置為 或 。

上圖中的所有內容都是可以從 Kubernetes 中開箱即用的。

進入 Istio 環節。為了能夠做到更智能化和基於權重的路由,我們需要安裝 Istio,然後將代理注入到我們的每個容器中,如下面的另一個圖片所示。下圖中的每個 pod 都有一個帶有 Istio 代理的容器(用藍色圖標表示)和運行應用的容器。在上圖中,我們只有一個容器在每個 pod 中運行——應用程序容器。

請注意,Istio 比圖中顯示的要多得多。我沒有展示在 Kubernetes 集群上部署的其他 Istio Pod 和服務——注入的 Istio 代理與這些 Pod 和服務進行通信,以便知道如何正確路由流量。有關 Istio 不同部分的深入解釋,請參閱此處的文檔。

如果我們現在可以調整 服務,那麼我們仍然會得到與第一個圖中的設置完全相同的結果:來自 和 pod 的隨機響應。唯一的區別在於網路流量從服務流向Pod的方式。在第二種情況下,對服務的任何調用都在 Istio 代理中結束,然後代理根據定義的路由規則決定將流量路由到哪裡。

就像 Kubernetes 一樣,Istio 路由規則也是使用 YAML 定義的,它們看起來像這樣:

上述路由規則接收請求 並將其重新路由到標記為 Pod 的請求 。這就是具有上述路由規則的圖表的樣子:

底部的 Istio 大圖標代表 Istio 部署/服務,其中包括正在讀取的路由規則。這些規則然後用於重新配置在每個 pod 內運行的 Istio 代理 sidecar。

有了這個規則,如果我們 curl 服務,我們只能從標有標籤為 (圖中的藍色連接器描述)的 pod 獲取響應。

現在我們已經了解了路由如何工作,我們可以研究 Fn ,部署它並查看它是如何工作的,以及我們是否可以使用 Istio 以某種方式設置路由。


我們將從 Kubernetes 上的一些 Fn 片段的基本圖表開始。您可以使用 Helm chart 將 Fn 部署在您的 Kubernetes 集群之上。

圖表頂部的 Fn API 服務是 Fn 的入口點,它用於管理您的 Function(創建,部署,運行等)——這是 在 Fn 項目中引用的 URL 。

該服務反過來將調用路由到 Fn 負載均衡器(即標記為 的任何 Pod )。然後,負載均衡器會發揮神奇的作用,並將調用路由到 pod 的實例。這作為 Kubernetes DaemonSet 的一部分部署,並且通常每個 Kubernetes 節點都有一個該 pod 的實例。

有了這些簡單的基礎知識,讓我們創建並部署一些 Function,並考慮如何進行流量路由。


如果您想遵循下面的教程,請確保已將 Fn 部署到您的 Kubernetes 群集(我正在使用 Docker for Mac )並安裝 Fn CLI 並運行以下命令來創建應用程序和一些功能:

使用上述命令,您已創建應用程序的根目錄,名為 。在這個目錄中,我們創建了兩個目錄,每個目錄下都有一個 Function:v1和一個v2。Boilerplate Go Function 使用 指定使用 Go 作為運行時。這是目錄的結構:

打開這 兩個目錄並更新返回的消息以包含版本號——我們這樣做的原因是可以快速區分哪個 Function 被調用。以下是v1的 的樣子( ):

更改完成後就可以將這些功能部署到在 Kubernetes 上運行的 Fn 服務。為此,您必須將 環境變數設置為指向您的 Docker 鏡像倉庫的用戶名。

因為我們在 Kubernetes 集群上運行 Fn,所以我們不能使用本地構建的映像 - 它們需要推送到Kubernetes集群可以訪問的 Docker 鏡像倉庫。

現在我們可以使用 Fn CLI 來部署這些函數:

上面的命令假設 Fn API 服務暴露在 localhost:80 上(默認情況下,如果您在 Docker for Mac 中使用Kubernetes 支持)。如果使用不同的集群,則可以將 FN_API_URL 替換為 fn-api 服務的外部 IP 地址。

在 Docker 構建和推送完成之後,我們的函數就被部署到 Fn 服務中了,我們可以嘗試調用它們。

部署到 Fn 服務的任何函數都有一個唯一的 URL,其中包含應用程序名稱和路由名稱。通過我們的應用程序名稱和路由,我們可以訪問已部署的函數 。所以,如果我們想調用 路由,我們可以這樣做:

同樣,調用 路由將返回 Hello V2 消息。

但函數在哪裡運行?

如果您在調用函數時查看正在創建/刪除的 pod ,您會注意到沒有真正改變——即沒有 pod 創建或刪除。原因是 Fn不會像 Kubernetes pod 一樣創建函數 ,因為這太慢了。相反,所有 Fn 函數的部署和調用都發生在 fn-service pod 中。然後,Fn 負載均衡器負責部署和路由到這些 pod ,以最優化的方式部署/執行函數。

因此,我們沒有函數的 Kubernetes pod/service ,但 Istio 要求我們擁有可以路由到的服務和 pod。在這種情況下,我們如何使用 Istio 呢 ?


讓我將函數從圖片中解放出來,並思考為了能讓 Istio 路由工作我們需要做什麼:

Kubernetes 服務—— hello 應用程序的入口點

針對 hello-app v1 的 Kubernetes deployment

針對 hello-app v2 的 Kubernetes deployment

正如 Istio 路由入門一節開頭部分所解釋的,我們還必須在兩個 deployment 中添加一個代表版本和 的標籤。服務上的選擇器會選擇 的標籤——特定於版本的標籤將由 Istio 路由規則添加。

為此,每個特定於版本的部署都需要最終以正確的路由(例如 )調用 Fn 負載均衡器。由於一切都在 Kubernetes 中運行,我們知道 Fn 負載均衡器服務的名稱,所以我們可以做到這一點。

因此,我們需要一個位於部署中的容器,它在調用時將呼叫轉發到特定路徑上的 Fn 負載均衡器。

這是圖中表示的上述想法:

我們有一個服務代表我們的應用程序和兩個特定於版本的部署,並直接路由到 Fn 服務中運行的 Function 。

簡單的代理

為了實現這一點,我們需要某種代理伺服器來接收所有調用並將它們轉發給 Fn 服務。下面是一個簡單的Nginx 配置,它完全符合我們的要求:

配置解釋:調用 ,就將其轉發到 ( 定義為上游),解析到 (這是 fn-api 在 Kubernetes 的 namespace 中的服務名稱)。

我用一個腳本創建了一個 Docker 鏡像,該腳本基於您傳入的上游和路由值生成 Nginx 配置。該鏡像在 Docker hub 上提供,您可以在這裡查看源代碼。

部署到 Kubernetes

現在,我們可以創建 Kubernetes YAML 文件,包括 service、deployment 以及我們將用於訪問函數的 ingress。

以下是 deployment 文件的摘錄,以顯示我們如何設置 、 環境變數和設置標籤。

和 環境變數由 simple-proxy 容器讀取,Nginx 的配置文件會根據這些值生成。

服務的 YAML 文件也沒什麼特別,我們只是將選擇器設置為 :

最後一部分是 Istio ingress,我們設置了將所有傳入流量路由到後端服務的規則:

要部署這些,您可以使用 來部署 ingress 和服務,使用 來注入 Istio 代理。

隨著一切部署完畢,你應該會得到以下 Kubernetes 資源:

hello-app-deployment-v1(使用指向 v1 路由的 simple-proxy 鏡像部署)

hello-app-deployment-v2(使用指向 v2 路由的 simple-proxy 鏡像部署)

hello-app-service(在 hello-app 部署中針對 v1 和 v2 pod 的服務)

指向 hello-app-service 的 ingress,並給增加註解,將 ingress.class 賦值為 「istio」

現在,如果我們調用 hello-app-service 或調用 ingress ,我們應該從 v1 和 v2 函數中獲得隨機響應。以下是對 ingress 進行調用的示例輸出:

你會注意到我們隨機獲得了 V1 和 V2 的響應 - 這正是我們現在想要的!


在我們的服務和部署已啟動並運行(和正在運行)的情況下,我們可以為 Fn 函數創建 Istio 路由規則。讓我們以一個簡單的 v1 規則開始,該規則將所有對 的調用( )路由到標記為的 的 pod 上:

您可以通過運行應用此規則 。查看運行中的路由的最佳方法是運行一個連續調用端點的循環——這樣您就可以看到混合(v1/v2)和全部v1的響應。

就像我們將 的路由規則定義為 100% 的權重那樣,我們可以類似地定義一條規則將所有內容路由到 ,或者將規則路由 50% 的流量 和 50% 的流量 ,如下面的演示所示。

GIF

一旦我證明了這一點,簡單的 curl 命令,好了,我停下來:)

幸運的是,Chad Arimura 在他關於 DevOps 對無伺服器的重要性的文章中進一步說明了這一點(警報:DevOps 不會消失)。他使用 Spinnaker 對在實際 Kubernetes 集群上運行的 Fn 函數進行加權藍綠部署。看看他的演示視頻:

該視頻已轉換為動圖,因為大與5M無法上傳到微信公眾號,請訪問網頁觀看:http://www.servicemesher.com/blog/traffic-routing-between-fn-functions-using-fn-project-and-istio-fd/

結論

每個人可能都會認同服務網格在無服務函數領域的重要性。如果使用服務網格(如路由、流量鏡像、故障注入和其他一些東西),可以獲得許多好處。

我看到的最大挑戰是缺乏以開發人員為中心的工具,讓開發人員能夠利用所有這些漂亮和酷炫的功能。設置這個項目和演示來運行幾次並不太複雜。

但是,這是兩個函數,它們就返回一個字元串,並沒有別的。這是一個簡單的演示。考慮運行數百或數千個函數並在它們之間建立不同的路由規則。然後管理所有這些函數。或者推出新版本並監控故障。

我認為在進行函數管理、服務網格管理、路由、其他酷炫的功能方面有很多的機會(和挑戰),因此對於每個參與者都很直觀。


對這篇文章的任何反饋我都非常歡迎!你也可以在 Twitter 和 GitHub 上關注我。如果你喜歡這一點,並希望在我寫更多東西時得到通知,你應該訂閱我的通訊!


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 ServiceMesher 的精彩文章:

容器、服務網格和 API 網關:從邊緣開始
Service Mesh中的通用數據平面API設計

TAG:ServiceMesher |