服務網格現狀之我見

語言: CN / TW / HK

本文根據 2021 年 11 月 22 日晚我應極客邦邀請在「極客時間訓練營」的直播分享《雲原生漫談:聊聊 Service Mesh 的現狀》整理而成。

本來極客時間是想邀請我分享雲原生的,但我覺得那個範圍太大,在一次分享中只能泛泛而談,無法聚焦到一個具體的點,因此我想還是先聚焦在服務網格這一個專題上吧。雲原生社群最近倒是在做一個 雲原生系列的分享 ,大家可以關注下。

這是我今天分享的大綱:

  1. 第一探討下服務網格跟雲原生的關係
  2. 第二是給大家陳述下我觀察到的目前社群裡關於服務網格有哪些爭論
  3. 第三是給大家介紹幾個服務網格的相關的開源專案
  4. 最後是暢想下服務網格未來的發展

服務網格與雲原生的關係

首先我們將探討下服務網格與雲原生的關係。

服務網格——容器編排大戰後的產物

如果你關注雲原生領域足夠早的話,應該還會對 2015 到 2017 年間的容器編排大戰記憶猶新。關於服務網格的起源已經無需多言。2017 年 Kubernetes 獲得了容器大戰的勝利,微服務的理念已經深入人心,容器化的趨勢可謂勢不可擋。Kubernetes 架構趨向成熟,慢慢變得無聊,以 Linkerd、Istio 為代表的服務網格技術進入了 CNCF 定義的雲原生關鍵技術視野中。

服務網格將微服務中的通用的功能給下沉到了基礎設施層,讓開發者可以更加專注於業務邏輯,從而加快服務交付,這與整個雲原生的理念的一致的。你不需要再在應用中整合笨重的 SDK,為不同語言開發和維護 SDK,應用部署完後,使用服務網格進行 Day 2 操作即可。

Kubernetes 設計之初就是按照雲原生的理念設計的,雲原生中有個重要概念就是微服務的架構設計,當將單體應用拆分微服務後, 隨著服務數量的增多,如何微服務進行管理以保證服務的 SLA 呢?為了從架構層面上解決這個問題,解放程式設計師的創造性,避免繁瑣的服務發現、監控、分散式追蹤等事務,服務網格應運而生。

來源: http://developers.redhat.com/blog/2016/12/09/spring-cloud-for-microservices-compared-to-kubernetes

服務網格被譽為下一代微服務,從右面這幅圖裡我們可以看到微服務的一些關注點,這些關注點很多與 Kubernetes 的功能是重合的,既然這些作為平臺級的功能 Kubernetes 已經提供了,為什麼還要使用服務網格呢?其實 Kubernetes 關注的還是應用的生命週期,它管理的物件是資源和部署,對於服務的管控力度很小。而服務網格正好彌補了這個缺陷。服務網格可以連線、控制、觀察和保護微服務。

Kubernetes vs xDS vs Istio

這幅圖展示的是 Kubernetes 和 Istio 的分層架構圖。從圖中我們可以看到 kube-proxy 的設定是全域性的,無法對每個服務進行細粒度的控制,Kubernetes 可以做的只有拓撲感知路由、將流量就近路由,為 Pod 設定進出站的網路策略。

而服務網格通過 sidecar proxy 的方式將 Kubernetes 中的流量控制從服務層中抽離出來,為每個 Pod 中注入代理,並通過一個控制平面來操控這些分散式代理。這樣可以實現更大的彈性。

Kube-proxy 實現了一個 Kubernetes 服務的多個 pod 例項之間的流量負載均衡,但如何對這些服務之間的流量進行精細化控制–比如將流量按百分比劃分給不同的應用版本(這些應用版本都是同一個服務的一部分,但在不同的部署上),或者做金絲雀釋出(灰度釋出)和藍綠髮布?

Kubernetes 社群給出了一個使用 Deployment 做金絲雀釋出的方法,本質上是通過修改 pod 的標籤來給部署的服務分配不同的 pod。

目前在中國最流行的服務網格開源實現是 Istio,也有很多公司對 Istio 進行了二次開發,比如螞蟻、網易、騰訊等,其實 Istio 是在 Envoy 的基礎上開發的,從它開源的第一天起就預設使用了 Envoy 作為它的分散式代理。Envoy 開創性的創造了 xDS 協議,用於分散式閘道器配置,大大簡化了大規模分散式網路的配置。2019 年螞蟻開源的 MOSN 同樣支援了 xDS。Envoy 還是 CNCF 中最早畢業的專案之一,經過大規模的生產應用考驗。可以說 Istio 的誕生已經有了很好的基礎。

下表是 Kubernetes、xDS、Istio 三者之間的資源抽象對比。

Kubernetes xDS Istio 服務網格
Endpoint Endpoint WorkloadEntry
Service Route VirtualService
kube-proxy Route DestinationRule
kube-proxy Listener EnvoyFilter
Ingress Listener Gateway
Service Cluster ServiceEntry

kube-proxy 元件、xDS 和 Istio 對流量管理的抽象後,現在我們僅從流量管理的角度來看看這三個元件 / 協議的比較。請注意,三者並不完全等同。Kubernetes 更加註重的是應用層面的流量管理,xDS 是更加抽象的協議層面的配置下發,而 Istio 是服務層面的配置。

服務網格——雲原生網路基礎設施

在列舉過以上 Kubernetes 和服務網格的對比後,我們可以看出服務網格在雲原生應用架構中的地位。那就是構建一個雲原生網路基礎設施,具體來說就是:

  • 流量管理:控制服務間的流量和API呼叫流,使呼叫更可靠,增強不同環境下的網路魯棒性。
  • 可觀測性:瞭解服務之間的依賴關係和它們之間的性質和流量,提供快速識別定位問題的能力。
  • 策略實施:通過配置網格而不是以改變程式碼的方式來控制服務之間的訪問策略。
  • 服務識別與安全:提供在網格里的服務可識別性和安全性保護。

社群裡關於 Istio 和服務網格的爭論

然而構建基礎設施,可謂牽一髮而動全身。理想很豐滿,現實很骨感。關於服務網格和 Istio,在社群中也不乏爭論。我們來看看有這些爭論主要有哪些。

這裡列舉了我在社群中觀察到的關於 Istio 和服務網格最常見的幾個問題。

  1. 有人在生產使用 Istio 嗎?
  2. 為 pod 注入 sidecar 後帶來的大量資源消耗,影響應用效能?
  3. Istio 支援的協議有限,不易擴充套件?
  4. Istio 太過複雜,老的服務遷移成本太高,業界經驗太少,學習曲線陡峭?

第一個問題,也是很多人剛加入社群和了解這門技術的時候,問的第一個問題,那是有人在生產使用 Istio 嗎?

隨著對 Istio 研究的深入,很多人就會丟擲第二個問題,為 pod 注入 sidecar 後帶來的大量資源消耗,會影響應用效能嗎?

如果能問到第三個問題,說明對 Istio 有比較強的需求了,大多是使用了自定義的 RPC,對 Istio 的協議擴充套件有需求。 最後一個問題是抱怨 Istio 的概念太過複雜,也沒有一個清晰的遷移路徑可以使用,學習曲線太過陡峭。

下面我將一一回答這些問題。

Istio 架構穩定,生產可用,生態漸起

首先我們來看下 Istio 的釋出時間表,1.12 版本在上週剛剛釋出,這裡列舉了從它開源到 1.8 版本釋出的時間表。2018 年可以說是服務網格爆發之年,Tetrate 也在這一年成立。自1.5 版本起 Istio 正式確立了當前的架構。Istio 社群也也舉辦了豐富多彩的活動,2021 年 3 月首屆 IstioCon 召開,7 月 Istio Meetup China 在北京舉行,2022 年 1 月,Service Mesh Summit 2022 也將在上海舉行。

Istio 有著龐大的社群以及 供應商和使用者群體 。目前主流公有云全都支援了 Istio 服務網格,如阿里雲、華為雲、騰訊雲、網易雲等,Istio 的官網上也列舉了幾十個社群使用者,雲原生社群 Istio SIG 還陸續舉辦了八場 Istio 大咖說 ,百度、騰訊、網易、小紅書、小電科技都來分享過他們的 Istio 實踐。

還有很多企業基於 Istio 做了二次開發或者適配或者為其開發外掛,可以說是 Istio 架構已穩定,生產可用,生態正在萌芽中。

服務網格對應用效能的影響

服務網格為了做到對應用程式透明,預設採用了 iptables 流量劫持的方式,當服務數量大的時候會有大量的 iptables 規則,影響網路效能,你可以使用 eBPF 這樣的技術來提供應用效能,但是該技術對作業系統核心的版本要求比較高,很少有企業能夠達到。

來源: http://cloudnative.to/blog/istio-dns-proxy/

還有一種方式,也是 小紅書使用的方式 ,那就是利用 Istio 1.8 中引入的智慧 DNS 代理功能。首先使用 ServiceEntry 定義服務,讓所有服務屬於一個 VIP 範圍,再利用 Istio 的智慧 DNS 代理功能,讓sidecar只攔截 VIP 網段的流量,這樣可以減少 iptables 規則,從而提高效能。如果想深入瞭解這個做法的細節,大家可以去瀏覽 Istio 大咖說第八期的分享視訊

Istio 在初期是將整個網格內的所有服務的路由資訊全量下發到所有的 proxy sidecar 中,會導致 sidecar 佔用大量資源,後來 Istio 引入了 Sidecar 資源 來精細化控制需要下發的代理配置範圍,另外還有企業自己開發了配置懶載入功能,例如騰訊雲開源的 Aeraki 、網易開源的 Slime 都可以實現配置懶載入。我們會在 Istio 開源生態中介紹這兩個開源專案。

最後是一個涉及到 Sidecar proxy 運維的問題,如何在保證流量不斷的情況下,升級所有 Envoy 代理,這個阿里開源的 OpenKruise 中的 SidecarSet 資源已經給出瞭解決方案。

另外 Sidecar 的引入帶來的資源消耗以及網路延遲也是在合理的範圍內,大家可以參考 Istio 官方部落格上的 Service Mesh 基準效能測試

擴充套件 Istio 服務網格

下一個問題是關於擴充套件 Istio 服務網格的。目前官方社群給出的方案是使用 WebAssembly,目前這種擴充套件方式在國內用的還比較少,而且效能也堪憂。我觀察到的大部分解決方案都是自定義 CRD,基於 Istio 構建服務網格管理平面。

另外,讓 Istio 支援異構環境,適用於一切工作負載,如虛擬機器、容器,這個對於終端使用者來說也有很強的需求,因為這可以讓使用者很方便的從傳統負載遷移應用到服務網格中。最後是多叢集、多網格的混合雲流量管理,這個屬於比較高階的需求了。

陡峭的學習曲線

以下列舉的是 Istio 學習資源:

Istio 開源至今已有 4 年時間,2018 年時我和敖小劍一起建立了 ServiceMesher 社群,當時組織過 9 次 Service Mesh Meetup,同其他服務網格愛好者一起翻譯了 Istio 的官方文件。我還在今年初參與了 IstioCon 2021 的籌辦及首屆 Istio Meetup China。可以說是親眼目睹了國內服務網格技術的應用和發展,在這期間也寫過和翻譯過大量的文章,加入 Tetrate 後,我還參與釋出了 Istio 基礎教程,免費提供給大家學習。同時 Tetrate 也推出了認證 Istio 管理員考試,用於培養更多行業人才。

雲原生社群組織了 Istio SIG,還推出了 Istio 大咖說直播欄目,為大家分享 Istio 服務網格實踐經驗。

下圖是 Istio 基礎教程 的首頁截圖。

如果你是剛開始接觸服務網格和 Istio,可以先從 Istio 基礎教程開始學起。這個線上系列課程是圖文並茂的中文課程,可以免費參加。

好了,我們再來了解下服務網格的社群專案。

Istio 開源生態

下表中羅列的是基於 Istio 的開源專案。

專案名稱 開源時間 類別 描述 主導公司 Star 數量 與 Istio 的關係
Envoy 2016年 9 月 網路代理 雲原生高效能邊緣/中間服務代理 Lyft 18300 預設的資料平面
Istio 2017 年 5 月 服務網格 連線、保護、控制和觀察服務。 Google 28400 控制平面
Emissary Gateway 2018 年 2 月 閘道器 用於微服務的 Kubernetes 原生 API 閘道器,基於 Envoy 構建 Ambassador 3500 可連線 Istio
APISIX 2019 年 6 月 閘道器 雲原生 API 閘道器 API7 7400 可作為 Istio 的資料平面執行也可以單獨作為閘道器
MOSN 2019 年 12 月 代理 雲原生邊緣閘道器及代理 螞蟻 3400 可作為 Istio 資料平面
Slime 2021 年 1月 擴充套件 基於 Istio 的智慧服務網格管理器 網易 204 為 Istio 增加一個管理平面
GetMesh 2021 年 2 月 工具 Istio 整合和命令列管理工具 Tetrate 91 實用工具,可用於 Istio 多版本管理
Aeraki 2021 年 3 月 擴充套件 管理 Istio 的任何七層負載 騰訊 280 擴充套件多協議支援
Layotto 2021 年 6 月 執行時 雲原生應用執行時 螞蟻 325 可以作為 Istio 的資料平面
Hango Gateway 2021 年 8 月 閘道器 基於 Envoy 和 Istio 構建的 API 閘道器 網易 187 可與 Istio 整合

從 2017 年 5 月 Istio 開源至今也有 4 年多了,雖然該專案在 GitHub 上已經有很高的關注度,併發布了 10 幾個版本,但其開源生態還在萌芽期。這張表列舉了 Istio 生態中的開源專案,統計截止到 2021 年 11 月 11 日,表格按照開源時間排序。這些專案在 Istio 服務網格之上增強了閘道器、擴充套件和實用工具等。我將挑選其中 2 個來著重分享下。

Slime:基於 Istio 的智慧服務網格管理器

Slime 是由網易數帆微服務團隊開源的一款基於 Istio 的智慧網格管理器。Slime 基於 Kubernetes Operator 實現,可作為 Istio 的 CRD 管理器,無縫對接 Istio,無須做任何定製化改造,定義動態的服務治理策略,從而達到自動便捷使用 Istio 和 Envoy 高階功能的目的。

Slime 試圖解決以下問題:

  • 在 Istio 中如何實現高階擴充套件的問題,比如擴充套件 HTTP 外掛,限流功能比較單薄,無法根據服務的資源使用率做到自適應限流
  • 解決 Sidecar 配置全量下發消耗大量資源導致應用效能變差的問題

Slime 解決以上問題的答案是構建 Istio 的管理平面,其核心思路是:

  • 構建可拔插控制器
  • 資料平面監控
  • CRD 轉換

下圖是 Istio 作為 Istio 管理平面的流程圖。

Slime 管理 Istio 的具體步驟如下:

  1. Slime Operator 根據管理員的配置在 Kubernetes 中完成 Slime 元件的初始化;
  2. 開發者建立符合 Slime CRD 規範的配置並應用到 Kubernetes 叢集中;
  3. Slime 查詢 Prometheus 中儲存的相關服務的監控資料,結合 Slime CRD 中自適應部分的配置,將 Slime CRD 轉換為 Istio CRD,同時將其推送到 Global Proxy 中;
  4. Istio 監聽 Istio CRD 的建立;
  5. Istio 將 Sidecar Proxy 的配置資訊推送到資料平面相應的 Sidecar Proxy 中;

下圖展示的 Slime 的內部架構圖。

作為 Istio 的管理平面,可以將 Slime 的核心看做是 Istio 的一個 Operator。

Slime 內部分為三大元件:

  • slime-boot :在 Kubernetes 上部署 Slime 模組的 operator。
  • slime-controller :Slime 的核心元件,監聽 Slime CRD 並將其轉換為Istio CRD。
  • slime-metric :用於獲取服務 metrics 資訊的元件,slime-controller 會根據其獲取的資訊動態調整服務治理規則。

下圖展示的是 Slime 自適應限流的架構圖。

Envoy 內建的限流元件功能單一,只能以例項維度配置限流值,無法做到根據應用負載的自適應限流。Slime 通過與 Prometheus metric server 對接,實時的獲取監控情況,來動態配置限流值。

Slime 的自適應限流的流程分為兩部分,一部分為 SmartLimiter 到 EnvoyFilter 的轉換,另一部分為獲取監控資料。目前 Slime 支援從 Kubernetes Metric Server 獲取服務的CPU、記憶體、副本數等資料。Slime 還對外提供了一套監控資料介面(Metric Discovery Server),通過 MDS,可以將自定義的監控指標同步給限流元件。

Slime 建立的 CRD SmartLimiter 用於配置自適應限流。其的配置是接近自然語義,例如希望在 CPU 超過 80% 時觸發服務 A 的訪問限制,限額為 30QPS,對應的 SmartLimiter 定義如下:

apiVersion: microservice.netease.com/v1alpha1
kind: SmartLimiter
metadata:
  name: a
  namespace: default
spec:
  descriptors:
  - action:
      fill_interval:
        seconds: 1
      quota: "30/{pod}"    # 30 為該服務的額度,
將其均分給每個 pod,加入有 3 個 pod,則每個 pod 的限流為 10
    condition: "{cpu}>0.8" # 根據監控項{cpu}的值自動填充該模板

Aeraki:非侵入式的 Istio 擴充套件工具集

Aeraki 是騰訊雲在 2021 年 3 月開源的,它的架構與 Slime 類似。它從 Istio 中拉取服務資料,根據 ServiceEntry 和流量規則生成 Envoy 配置,也就是 EnvoyFilter 推送到 Istio 中。簡而言之,你可以把 Aeraki 看做 Istio 中管理的七層協議的 Operator。

下圖是 Aeraki 的架構圖。

來源: http://cloudnative.to/blog/istiocon-layer7-traffic/

Aeraki 作為一個獨立元件部署,可以很方便地作為一個外掛和 Istio 進行整合。

Aeraki 可以根據 Istio 版本和 Kubernetes 叢集相關資訊自動進行調整配置,避免了 EnvoyFilter 的手動建立和維護工作。Aeraki 建立了面向七層協議 CRD 隱藏了 Envoy 的配置細節,遮蔽了不同 Istio 版本生成的預設 Envoy 配置的差異,對於運維非常友好。

服務網格的未來發展

最後我想講一下對於服務網格未來發展的一些看法。

讓 Istio 適用於一切環境和一切工作負載

我們看到了網易、騰訊主要是通過構建 Operator 來擴充套件 Istio,然而這種擴充套件對於多叢集管理來說並不夠用。我們知道我們目前的基礎設施很多是在向雲原生化或者是容器化轉型,那麼就存在一個容器、虛擬機器等共存的環境。這就是異構環境,這些不同環境的流量如何統一管理呢?其實使用 Istio 是可以做到的。同樣是要在 Istio 之上構建一個管理平面,並增加一個抽象層,增加適用於叢集管理的 CRD,比如叢集流量配置、叢集策略配置等。另外還要在每個叢集中部署一個 Gateway,統一連線到一個邊緣代理,讓所有的叢集互聯。這也是 Tetrate Service Bridge 的產品理念。

下圖展示的 Tetrate Service Bridge 架構圖。

API 閘道器與服務網格的融合

下圖展示了使用 Istio Gateway、Kubernetes Ingress、API Gateway 及 NodePort/LB 暴露 Istio mesh 中服務的四種方式。

其中陰影表示的是 Istio mesh,mesh 中的的流量屬於叢集內部(東西向)流量,而客戶端訪問 Kubernetes 叢集內服務的流量屬於外部(南北向)流量。不過因為 Ingress、Gateway 也是部署在 Kubernetes 叢集內的,這些節點訪問叢集內其他服務的流量就難以歸屬了。

在 Istio mesh 中你可以使用多種 Kubernetes Ingress Controller 來充當入口閘道器,當然你還可以直接使用 Istio 內建的 Istio 閘道器,對於策略控制、流量管理和用量監控可以直接通過 Istio 閘道器來完成,這樣做的好處是通過 Istio 的控制平面來直接管理閘道器,而不需要再借助其他工具。但是對於 API 宣告週期管理、複雜的計費、協議轉換和認證等功能,傳統的 API 閘道器可能更適合你。所以,你可以根據自己的需求來選擇,也可以組合使用。

下表中列出了 Istio Mesh 中暴露服務的四種方式。

方式 控制器 功能
NodePort/LoadBalancer Kubernetes 負載均衡
Kubernetes Ingress Ingress Controller 負載均衡、TLS、虛擬主機、流量路由
Istio Gateway Istio 負載均衡、TLS、虛擬主機、高階流量路由、其他 Istio 的高階功能
API 閘道器 API Gateway 負載均衡、TLS、虛擬主機、流量路由、API 生命週期管理、許可權認證、資料聚合、賬單和速率限制

目前有些傳統的反向代理也在向 Service Mesh 方向發展,如 Nginx 構建了 Nginx Service Mesh,Traefik 構建了 Traefik Mesh。還有的 API 閘道器產品也向 Service Mesh 方向挺進,比如 Kong 發展出了 Kuma。在未來,我們會看到更多 API 閘道器、反向代理和服務網格的融合產品出現。

你是否真的需要服務網格?

在使用服務網格前,請考慮以下問題:

  • 你的團隊多少人裡投入服務網格開發?使用 Kubernetes、Istio 的經驗?
  • 你有多少微服務?這些微服務使用什麼語言?
  • 你的服務都執行在哪些平臺上?
  • 你的應用已經容器化並使用 Kubernetes 管理了嗎?
  • 你的服務有多少是部署在虛擬機器、有多少是部署到 Kubernetes 叢集上,比例如何?
  • 你的團隊有制定轉移到雲原生架構的計劃嗎?
  • 你想使用 Istio 的什麼功能?Istio 的穩定性是否能夠滿足你的需求?
  • 你是否可以忍受 Istio 帶來的效能損耗?
  • 你選擇自建或者採購?

總結

最後總結一下今天的分享:

  • 從容器編排爭霸到服務網格,我們可以看到雲原生乃至整個雲端計算就是標準之爭。
  • 服務網格的目標是成為雲原生的網路基礎設施,任重而道遠。
  • 服務網格只是雲原生龐大技術棧中的一環,不要一葉障目,技術的發展是永無止境的。
  • Istio 架構已經穩定,生產可用,生態正處於萌芽中。
  • 對於終端使用者來說適合自己的才是最好的。

本人才疏學淺,因為時間的原因,很多內容沒有深入展開和探討,最後歡迎大家加入 雲原生社群 Istio SIG 一起交流學習 Istio 和服務網格技術。