Istio和Linkerd的CPU基準測試報告
作者:Michael Kipper
譯者:馬若飛
審校:宋淨超
原文:https://medium.com/@michael_87395/benchmarking-istio-linkerd-cpu-c36287e32781
編者按
作者是Shopify的工程師,公司在引入Istio作為服務網格的過程中發現消耗的計算成本過高。基於此問題,作者使用了公司內部開發的基準測試工具IRS對Istio和Linkerd的CPU使用情況做了測試和對比。測試結果發現Istio在CPU的使用上要比Linkerd耗費更多的資源。這為Istio的擁躉們敲響了警鐘,提醒大家Istio在生產化的道路上還有很多需要優化的地方。
背景
在Shopify,我們正在部署Istio作為服務網格。我們做的很不錯但遇到了瓶頸:成本。
Istio官方釋出的基準測試情況如下:
在Istio 1.1中一個代理每秒處理1000個請求大約會消耗0.6個vCPU。
對於服務網格中的第一個邊界(連線的兩端各有兩個代理),1200個核心的代理每秒處理100萬個請求。Google的價格計算器估計對於 n1-standard-64
機型每月每個核需要40美元,這使得這條單邊界的花費超過了5萬美元/每月/每100萬請求。
Ivan Sim 去年寫了一個關於服務網格延遲的很棒的文章 ,並保證會持續更新CPU和記憶體部分,但目前還沒有完成:
看起來values-istio-test.yaml將把CPU請求提升很多。如果我算的沒錯,控制平面大約有24個CPU,每個代理有0.5個CPU。這比我目前的個人賬戶配額還多。一旦我增加CPU配額的請求被批准,我將重新執行測試。
我需要親眼看看Istio是否可以與另一個開源服務網格相媲美:Linkerd.
安裝服務網格
首先,我在叢集中安裝了SuperGloo:
$ supergloo init installing supergloo version 0.3.12 using chart uri https://storage.googleapis.com/supergloo-helm/charts/supergloo-0.3.12.tgz configmap/sidecar-injection-resources created serviceaccount/supergloo created serviceaccount/discovery created serviceaccount/mesh-discovery created clusterrole.rbac.authorization.k8s.io/discovery created clusterrole.rbac.authorization.k8s.io/mesh-discovery created clusterrolebinding.rbac.authorization.k8s.io/supergloo-role-binding created clusterrolebinding.rbac.authorization.k8s.io/discovery-role-binding created clusterrolebinding.rbac.authorization.k8s.io/mesh-discovery-role-binding created deployment.extensions/supergloo created deployment.extensions/discovery created deployment.extensions/mesh-discovery created install successful!
我使用SuperGloo是因為它非常簡單,可以快速引導兩個服務網格,而我幾乎不需要做任何事情。我們並沒有在生產環境中使用SuperGloo,但是它非常適合這樣的任務。每個網格實際上有兩個命令。我使用了兩個叢集進行隔離——一個用於Istio,另一個用於Linkerd。
然後我用下面的命令安裝了兩個服務網格。
首先是Linkerd:
$ supergloo install linkerd --name linkerd +---------+--------------+---------+---------------------------+ | INSTALL |TYPE| STATUS|DETAILS| +---------+--------------+---------+---------------------------+ | linkerd | Linkerd Mesh | Pending | enabled: true| |||| version: stable-2.3.0| |||| namespace: linkerd| |||| mtls enabled: true| |||| auto inject enabled: true | +---------+--------------+---------+---------------------------+
然後是Istio:
$ supergloo install istio --name istio --installation-namespace istio-system --mtls=true --auto-inject=true +---------+------------+---------+---------------------------+ | INSTALL |TYPE| STATUS|DETAILS| +---------+------------+---------+---------------------------+ | istio| Istio Mesh | Pending | enabled: true| |||| version: 1.0.6| |||| namespace: istio-system| |||| mtls enabled: true| |||| auto inject enabled: true | |||| grafana enabled: true| |||| prometheus enabled: true| |||| jaeger enabled: true|
幾分鐘後的迴圈Crash後,控制平面穩定了下來。
安裝Istio自動注入
為了讓Istio啟用Envoy sidecar,我們使用 MutatingAdmissionWebhook
作為注入器。這超出了本文的討論範圍,但簡言之,控制器監視所有新的Pod許可,並動態新增sidecar和initContainer,後者具有 iptables
的能力。
在Shopify,我們自己寫了許可控制器來做sidecar注入,但根據基準測試的目的,我使用了Istio自帶的。預設情況下名稱空間上有 istio-injection: enabled
的標籤就可以自動注入:
$ kubectl label namespace irs-client-dev istio-injection=enabled namespace/irs-client-dev labeled $ kubectl label namespace irs-server-dev istio-injection=enabled namespace/irs-server-dev labeled
安裝Linkerd自動注入
要安裝Linkerd的sidecar注入,我們使用標註(我通過 kubectl edit
手動新增):
metadata: annotations: linkerd.io/inject: enabled
$ k edit ns irs-server-dev namespace/irs-server-dev edited $ k get ns irs-server-dev -o yaml apiVersion: v1 kind: Namespace metadata: annotations: linkerd.io/inject: enabled name: irs-server-dev spec: finalizers: - kubernetes status: phase: Active
Istio彈性模擬器(IRS)
我們開發了Istio彈性模擬器來嘗試一些在Shopify特有的流量場景。具體地說,我們想要一些可以用來建立任意拓撲結構的東西,來表示服務中可動態配置的特定部分,以模擬特定的工作負載。
限時搶購是一個困擾Shopify基礎設施的問題。更糟糕的是,Shopify實際上鼓勵商家進行更多的限時搶購。對於我們的大客戶來說,我們有時會提前得到預先計劃好的限時搶購的警告。而其他客戶完全是在白天或晚上的任何時候突然出現的。
我們希望IRS能夠執行表示拓撲和工作負載的“工作流”,它們在過去削弱了Shopify的基礎設施。我們引入服務網格的主要原因之一是在網路級別部署可靠和有彈性的功能,而其中重要的部分是證明它能夠有效地減輕過去的服務中斷。
IRS的核心是一個worker,它充當服務網格中的一個節點。可以在啟動時靜態配置worker,也可以通過REST API動態配置worker。我們使用worker的動態特性建立工作流作為迴歸測試。
一個工作流的例子如下:
-
啟動10臺伺服器作為服務
bar
,在100ns之後返回“200/OK” -
啟動10個客戶端,給每個
bar
服務傳送100RPS請求 -
每10秒下線一臺伺服器,在客戶端監控
5xx
的錯誤
在工作流的最後,我們可以檢查日誌和指標來確定測試的通過/失敗。通過這種方式,我們既可以瞭解服務網格的效能,也可以迴歸測試關於彈性的假設。
( 注意:我們在考慮開源IRS,但目前還不是時候 )
IRS做服務網格基準測試
基於這個目的,我們安裝了下面一些IRS worker:
-
irs-client-loadgen
:3個複製集給irs-client
傳送100RPS請求 -
irs-client
:3個複製集接受請求,等待100ms然後轉發請求給irs-server
-
irs-server
:3個複製集100ms後返回200/OK
通過此設定,我們可以測量9個endpoint之間的穩定流量。在 irs-client-loadgen
和 irs-server
上的sidecar各接收總計100個RPS,而 irs-client
則接收200個RPS(入站和出站)。
我們通過DataDog監控資源使用情況,因此沒有維護Prometheus叢集。
結果
控制平面
首先來看看控制平面的CPU使用情況。

Linkerd 控制平面: ~22 mcores

Istio控制平面:~750 mcores
Istio控制平面比Linkerd多使用了大約 35倍的CPU 。不可否認,這是一個開箱即用的安裝,大部分Istio的CPU使用來自遙測,當然它可以被關閉(以犧牲功能為代價)。即使移除Mixer仍然會有超過100個mcore,這仍然比Linkerd多使用了 4倍的CPU 。
Sidecar代理
接下來,我們看一下sidecar代理的使用情況。這應該與請求速率成線性關係,但是每個sidecar都有一些開銷,這會影響曲線的形狀。

Linkerd:~100 mcore 為irs-client,~50 mcore 為irs-client-loadgen
這些結果是有道理的,因為客戶端代理接收的流量是loadgen代理的兩倍:對於來自loadgen的每個出站請求,客戶端接收一個入站請求和一個出站請求。

Istio/Envoy:~155 mcore 為irs-client, ~75 mcore 為irs-client-loadgen
Istio的sidecar我們看到了同樣的結果。
總的來說,Istio/Envoy代理比Linkerd多使用了大約 50%的CPU 。
我們看到在服務端也是一樣的情況:

Linkerd:~50 mcores 為 irs-server

Istio/Envoy:~80 mcores 為 irs-server
在服務端,Istio/Envoy代理比Linkerd多使用了大約 60%的CPU 。
結論
對於這種綜合的工作負載,Istio的Envoy代理使用的CPU比Linkerd多了50%以上。Linkerd的控制平面使用了Istio的一小部分,尤其是在考慮“核心”元件時。
我們仍在嘗試解決如何減輕一些CPU開銷——如果您有自己的見解或想法,我們很樂意聽取您的意見。
推薦閱讀
Linkerd 2.0 GA版本釋出——由叢集級Service Mesh轉變為組合式Service Sidecar
應用程式安全性和正確性的責任不能推卸給Istio或任何服務網格
使用服務網格提高安全性:Christian Posta帶你探索Istio的新功能