Beyond Istio OSS——Istio服務網格的現狀與未來

affdc58a507e2a07d933f5a938499a4f.gif

c62a1af2c67b7d75dec8c97459d4433a.png

作者:宋凈超(Jimmy Song),原文地址:https://jimmysong.io/blog/beyond-istio-oss/

本文根據筆者在 GIAC 深圳 2022 年大會上的的演講《Beyond Istio OSS —— Istio 的現狀及未來》[1]?整理而成,演講幻燈片見?騰訊文檔?[2]?。

本文回顧了 Istio 開源近五年來的發展,并展望了 Istio 服務網格的未來方向。本文的主要觀點如下:

  • ??因為 Kubernetes、微服務、DevOps 及云原生架構的流行,導致服務網格技術的興起;

  • ? Kubernetes 和可編程代理,為 Istio 的出現打下了堅實的基礎;

  • ??雖然 eBPF 可以加速 Istio 中的透明流量劫持,但無法取代服務網格中的 sidecar;

  • ? Istio 的未來在于構建基于混合云的零信任網絡;

Istio 誕生的前夜

2013 年起,隨著移動互聯網的爆發,企業對應用迭代的效率要求更高,應用程序架構開始從單體轉向微服務,DevOps 也開始變得流行。同年隨著 Docker 的開源,解決了應用封裝和隔離的問題,使得應用在編排系統中調度變得更容易。2014 年 Kubernetes、Spring Boot 開源,Spring 框架開發微服務應用開始流行,在接下來的幾年間大批的 RPC 中間件開源項目出現,如 Google 在 2016 年發布 gRPC 1.0,螞蟻在 2018 年開源?SOFAStack[3]?等,微服務框架百花齊放。為了節約成本,增加開發效率,使應用更具彈性,越來越多的企業正在遷移上云,但這不僅僅是將應用搬到云上那么簡單,為了更高效地利用云計算,一套「云原生」方法和理念也呼之欲出。

Istio 開源時間線

Istio 開源發展時間線如下圖所示。

05f1d03680e57b24f6e77291dba5ccc7.jpeg
Istio 開源發展時間線示意圖

下面我們來簡單回顧下 Istio 開源大事件:

  • ? 2016 年 9 月:因為 Envoy 是 Istio 中的重要組成,Istio 的開源時間線應該有 Envoy 一部分。起初 Envoy 在 Lyft 內部僅作為邊緣代理,開源前已在 Lyft 內部得到大規模生產驗證并受到了 Google 工程師的注意?1[4],那時候 Google 正打算推出一個服務網格的開源項目。2017 年,Lyft 將 Envoy 捐獻給了?CNCF[5]?。

  • ? 2017 年 5 月:Istio 由 Google、IBM 和 Lyft 聯合宣布開源?2[6]。一開始就使用了微服務架構,確定了數據平面和控制平面的組成以及 Sidecar 模式。

  • ? 2018 年 3 月:Kubernetes 順利的成為從 CNCF 中第一個畢業的項目,變得越來越「無聊」,基礎 API 已經定型,CNCF 正式將服務網格(Service Mesh)寫入到了云原生的第二版定義?3[7]?中。筆者當前就職的公司?Tetrate[8]?,也是在那時由 Google Istio 初創團隊創業成立的。服務網格在中國開始爆發,ServiceMesher 社區也在螞蟻集團的支持下成立,在中國布道服務網格技術。

  • ? 2018 年 7 月:Istio 1.0 發布,號稱「生產可用」,Istio 團隊重組。

  • ? 2020 年 3 月:Istio 1.5 發布,架構回歸單體,發布周期確定,每三個月發布一個大版本,API 趨于穩定。

  • ? 2020 年至今:Istio 的發展主要著重于 Day 2 Operation 4[9]、性能優化和擴展性發面,多個圍繞 Istio 生態的開源項目開始出現,例如?Slime[10]?、Areaki[11]?、Merbridge[12]?。

為什么 Istio 會在 Kubernetes 之后出現?

微服務和容器化之后,異構語言使用的增加,服務的數量激增,容器的生命周期變短是導致服務網格出現的根本原因。

我們先來看下服務從部署在 Kubernetes 到 Istio 中架構的變遷,然后再探討架構演進過程中 Istio 的需求,下文假定讀者已了解?Kubernetes[13]?和?Istio 的架構?[14]?。

7955e1c5d71114c5f7586e600ef73893.jpeg
Kubernetes 到 Istio 的架構改變示意圖

從 Kubernetes 到 Istio,概括的講應用的部署架構有如下特點:

  • ? Kubernetes 管理應用的生命周期,具體來說,就是應用的部署和管理(擴縮容、自動恢復、發布策略);

  • ??基于 Kubernetes 的自動 sidecar 注入,實現了透明流量攔截。先通過 sidecar 代理攔截到微服務間流量,再通過控制平面配置管理微服務的行為。如今服務網格的部署模式也迎來了新的挑戰,sidecar 已經不是 Istio 服務網格所必須的,基于 gRPC 的無代理的服務網格?5[15]?也在測試中。

  • ??服務網格將流量管理從 Kubernetes 中解耦,服務網格內部的流量無須?kube-proxy?組件的支持, 通過類似于微服務應用層的抽象,管理服務間的流量,實現安全性和可觀察性功能。

  • ??控制平面通過 xDS 協議發放代理配置給數據平面,已實現 xDS 的代理有?Envoy[16]?和螞蟻開源的?MOSN[17]?。

  • ??Kubernetes 集群外部的客戶端訪問集群內部服務時,原先是通過 Kubernetes?Ingress[18]?,在有了 Istio 之后,會通過 Gateway 來訪問?6[19]

Kubernetes 容器編排與可編程代理 Envoy 為 Istio 的出現打下了堅實的基礎。

從上面 Kubernetes 到 Istio 的架構的轉變的描述中,我們可以看到為了讓開發者最小成本地管理服務間的流量,Istio 需要解決三個問題:

  1. 1.?透明劫持應用間的流量:Istio 開源最初的目標是成為網絡基礎設施,就像水和電人類的基礎設施一樣,我們使用水電不需要關心如何取水和發電,只需要打開水龍頭,按下開關即可。透明流量劫持對于開發者來說,就像使用水和電,不需要修改應用程序就可以快速使用 Istio 帶來的流量管理能力;

  2. 2.?代理集群的運維:如何為每個應用注入一個代理,同時高效地管理這些分布式的 sidecar 代理;

  3. 3.?可編程代理:代理可以通過 API 動態配置,還要有出色的性能與可擴展性;

以上三個條件對于 Istio 服務網格來說缺一不可,而且,從中我們可以看到,這些要求基本都是對于 sidecar 代理的要求,這個代理的選擇將直接影響該項目的走向與成敗。為了解決以上三個問題,Istio 選擇了 Kubernetes 容器編排和可編程代理 Envoy。

透明流量劫持

如果你使用的是如 gRPC 這類中間件開發微服務,在程序中集成 SDK 后,SDK 中的攔截器會自動為你攔截流量,如下圖所示。

78f49de6bb9b36fb2fb7816ee9984a0a.jpeg
gRPC 的攔截器示意圖

如何讓 Kubernetes pod 中的流量都通過代理呢?答案是在每個應用程序 pod 中注入一個代理,與應用共享網絡空間,再通過修改 pod 內的流量路徑,讓所有進出 pod 的流量都經過 sidecar,其架構如下圖所示。

cc04ed05110a76ad02331176d82d3096.jpeg
Istio 中的透明流量劫持示意圖

從圖中我們可以看到其中有一套非常復雜的 iptables 流量劫持邏輯(詳見?Istio 中的 Sidecar 注入、透明流量劫持及流量路由過程詳解?[20]?),使用 iptables 的好處是適用于任何 Linux 操作系統。但是這也帶來了一些副作用:

  1. 1. Istio 網格中所有的服務都需要在進出 pod 時都增加了一個網絡跳躍點(hop),雖然每次 hop 可能只有兩三毫秒,但是隨著網格中服務和服務間的依賴增加,這種延遲可能會顯著增加,對于那種追求低延遲的服務可能就不適用于服務網格了;

  2. 2. 因為 Istio 向數據平面中注入了大量的 sidecar,尤其是當服務數量增大時,控制平面需要下發更多的 Envoy 代理配置到數據平面,這樣會使數據平面占用大量的系統內存和網絡資源;

針對這兩個問題,如何優化服務網格呢?

  1. 1. 使用 proxyless 模式:取消 sidecar 代理,重新回到 SDK;

  2. 2. 優化數據平面:減少下發到數據平面的配置的頻率和大小;

  3. 3. eBPF:使用 eBPF 優化網絡劫持;

本文將在后面性能優化?[21]?一節講解這些細節。

Sidecar 運維管理

Istio 是在 Kubernetes 的基礎上構建的,它可以利用 Kubernetes 的容器編排和生命周期管理,在 Kubernetes 創建 pod 時,通過準入控制器自動向 pod 中注入 sidecar。

為了解決 Sidecar 的資源消耗問題,有人為服務網格提出了有四種部署模式,如下圖所示。

8760fe984cc8e4806ec2c4ce67a5be23.jpeg
服務網格的四種部署模式示意圖

下表中詳細對比了這四種部署方式,它們各有優劣,具體選擇哪種根據實際情況而定。

模式內存開銷安全性故障域運維
Sidecar 代理因為為每個 pod 都注入一個代理,所以開銷最大。由于 sidecar 必須與工作負載一起部署,工作負載有可能繞過 sidecar。Pod 級別隔離,如果有代理出現故障,只影響到 Pod 中的工作負載。可以單獨升級某個工作負載的 sidecar 而不影響其他工作負載。
節點共享代理每個節點上只有一個代理,為該節點上的所有工作負載所共享,開銷小。對加密內容和私鑰的管理存在安全隱患。節點級別隔離,如果共享代理升級時出現版本沖突、配置沖突或擴展不兼容等問題,則可能會影響該節點上的所有工作負載。不需要考慮注入 Sidecar 的問題。
Service Account / 節點共享代理服務賬戶 / 身份下的所有工作負載都使用共享代理,開銷小。工作負載和代理之間的連接的認證及安全性無法保障。節點和服務賬號之間級別隔離,故障同 “節點共享代理”。同 “節點共享代理”。
帶有微代理的共享遠程代理因為為每個 pod 都注入一個微代理,開銷比較大。微代理專門處理 mTLS,不負責 L7 路由,可以保障安全性。當需要應用 7 層策略時,工作負載實例的流量會被重定向到 L7 代理上,若不需要,則可以直接繞過。該 L7 代理可以采用共享節點代理、每個服務賬戶代理,或者遠程代理的方式運行。同 “Sidecar 代理”。

服務網格的四種部署模式對比

可編程代理

Flomesh 的張曉輝曾在?為什么需要可編程代理?[22]?博客中詳細說明了代理軟件的發展演化過程,我下面將引用他的一些觀點,說明可編程代理 Envoy 在 Istio 中的關鍵作用。

下圖展示了代理從配置到可編程模式的演化過程,及每個階段中的代表性代理軟件。

f8d15e7f3ea9cbecf6e4c9e4362f8bb7.jpeg
代理軟件的演化示意圖

整個代理演化過程都是隨著應用從本地和單體,越來越走向大規模和分布式。下面我將簡要概括代理軟件的發展過程:

  • ??配置文件時代:幾乎所有軟件都有配置文件,代理軟件因為其相對復雜的功能,更離不開配置文件。該階段的代理主要使用 C 語言開發,包括其擴展模塊,突出的代理本身的能力。這也是我們使用代理最原始最基礎的形式,這些代理包括 Nginx、Apache HTTP Server、Squid[23]?等;

  • ??配置語言時代:這個時代的代理,更具擴展性和靈活性,比如動態數據獲取和配套的邏輯判斷。代表性代理包括擴?Varnish[24]?和 HAProxy;

  • ??腳本語言時代:從腳本語言的引入開始,代理軟件才真正走向的可編程,我們可以更方便的使用腳本在代理中增加動態邏輯,增加了開發效率。代表性的代理是 Nginx 及其支持的腳本語言;

  • ??集群時代:隨著云計算的普及,大規模部署和動態配置 API 成了代理所必需的能力,而且隨著網絡流量的增加,大規模代理集群也應運而生。這個時代的代表性代理有 Envoy、Kong 等;

  • ??云原生時代:多租戶、彈性、異構混合云、多集群、安全和可觀測,這些都是云原生時代對代理所提出的更高要求,代表性軟件有 Istio、Linkerd、Pypi[25]?,它們都為代理構建了控制平面。

這些都是服務網格嗎?

現在我將列舉一些流行的服務網格開源項目,讓我們一起探索服務網格的發展規律和本質。下表對比了當前流行的服務網格開源項目?7[26]

對比項IstioLinkerdConsul ConnectTraefik MeshKumaOpen Service Mesh (OSM)
當前版本1.142.111.121.41.51.0
許可證Apache License 2.0Apache License 2.0Mozilla LicenseApache License 2.0Apache License 2.0Apache License 2.0
發起者Google、IBM、LyftBuoyantHashiCorpTraefik LabsKongMicrosoft
服務代理Envoy,支持 gRPC 的 proxyless 模式Linkerd2-proxy[27]默認為?Envoy[28]?,可替換Traefik Proxy[29]Envoy[30]Envoy[31]
入口控制器Envoy,自定義的 Ingress,支持 Kubernetes Gateway API無內置Envoy,支持 Kubernetes Gateway API無內置Kong支持 Contour、Nginx,兼容其他
治理Istio Community 和 Open Usage Commons,已提議捐獻給 CNCFCNCF查看?貢獻指南?[32]查看?貢獻指南?[33]CNCFCNCF

服務網格開源項目對比表

上表中列出的都是服務網格,下面再簡單評論一下這些項目:

  • ??Istio[34]?:目前最流行的服務網格項目之一,在中國幾乎成為了服務網格的代名詞;

  • ??Linkerd[35]?:最早出現的服務網格,「Service Mesh」概念提出者,第一個進入 CNCF 的服務網格項目,使用自研的 Rust 語言編寫輕量級 sidecar 代理;

  • ??Traefik Mesh[36]?:由 Traefik 推出的服務網格項目,使用 Treafik proxy 作為 sidecar,支持 SMI(接下來會提到),它的特點是對應用的無侵入性,不會在 pod 中注入 sidecar;

  • ??Kuma[37]?:由 Kong 推出的服務網格項目,使用 Envoy 作為 Sidecar 代理,特色是使用 Kong 自家的網關作為入口網關;

  • ??Consul Connect[38]?:Consul 服務網格,使用 Envoy 作為 sidecar 代理;

  • ??Open Service Mesh[39]?:由微軟開源的服務網格,使用 Envoy 作為 sidecar,兼容 SMI(同樣是微軟提出);

另外還有幾個項目,也服務網格領域也經常被提及,但它們都不是服務網格:

  • ??Envoy[40]?:Envoy 本身只是代理,也經常被作為其他基于 Envoy 的服務網格的 sidecar,也經常被用來構建 API Gateway;

  • ??Service Mesh Performance(SMP)[41]?:標準化了服務網格值的指標,通過捕獲基礎設施容量、服務網格配置和工作負載元數據的細節來描述任何部署的性能;

  • ??Service Mesh Interface(SMI)[42]?:它不是服務網格,而只是一套服務網格實現標準,與 OAM、SPIFFE、CNI、CSI 等類似都是定義接口標準,具體實現就不一而足了。目前 Traefik Mesh 和 Open Service Mesh 聲明支持該規范;

  • ??Network Service Mesh[43]?:有必要提一下這個項目,因為經常有人把它錯認為是一個服務網格。實際上,它面向的是三層網絡,使用它可以在不更換 CNI 插件的前提下,連接多云 / 混合云。它并不是我們所定義的「服務網格」,而是服務網格的一個有力補充(雖然名字里帶有服務網格比較有迷惑性)。

縱觀以上項目,我們可以看出大部分服務網格項目的發起者都是根據代理起家,然后做控制平面。而且 Istio、Consul Connect、Open Service Mesh、Kuma 都是使用 Envoy 作為 sidecar 代理。只有 Linkerd 和 Traefik Mesh 推出了自己的代理。而所有的服務網格項目都支持 sidecar 模式。除了 Istio、Linkerd、Consul Connect 已應用于生產上,其他服務網格項目還沒有看到被大規模在生產上使用。

Istio 的性能優化

在 Istio 1.5 版本確定了穩定的架構之后,社區的主要精力在于優化 Istio 的性能。下面我將向你詳細介紹 Istio 中的性能優化方法,包括:

  • ??采用 Proxyless 模式;

  • ??使用 eBPF 優化流量劫持;

  • ??控制平面性能優化;

  • ??數據平面性能優化;

Proxyless 模式

Proxyless 模式是 Istio 在 1.11 版本中提出的實驗特性 ——?基于 gRPC 和 Istio 的無 sidecar 代理的服務網格?[44]?。使用該模式可以直接將 gRPC 服務添加到 Istio 中,而不需要再向 Pod 中注入 Envoy 代理。下圖展示了 sidecar 模式與 proxyless 模式的對比圖。

6fd7726b211eb1fc9f4ca3dd7acfd800.jpeg
Sidecar 模式 vs Proxyless 模式

從上圖中我們可以看到,雖然 proxyless 模式不使用 proxy 進行數據平面通信,但仍然需要一個 agent(即?pilot-agent) 來進行初始化和與控制平面的通信。首先,agent 在啟動時生成一個引導文件?[45]?,與為 Envoy 生成引導文件的方式相同。這告訴 gRPC 庫如何連接到?istiod,在哪里可以找到用于數據平面通信的證書,向控制平面發送什么元數據。接下來,agent 作為 xDS proxy,代表應用程序與?istiod?進行連接和認證。最后,agent 獲取并輪換數據平面通信中使用的證書,這其實與 Sidecar 模式的流程是一樣的,只是將 Envoy 代理的功能內置到 SDK 中了。

服務網格的本質不是 Sidecar 模式,也不是配置中心或透明流量攔截,而是標準化的服務間通信標準。

有人說 proxyless 模式又回到了基于 SDK 開發微服務的老路,服務網格的優勢喪失殆盡,那還能叫做服務網格嗎?8[46]?其實這也是一種對性能的妥協 —— 如果你主要使用 gRPC 來開發微服務的話,只需要維護不同語言的 gRPC 版本,即可以通過控制平面來管理微服務了。

Envoy xDS 已經成為服務網格中服務間通信的事實標準。

使用 eBPF 優化流量劫持

在透明流量劫持?[47]?一節,我們可以看到一個服務間的流量在到達目的地 pod 時經過的 iptables 規則和路徑,其中需要經過多條 iptables 規則,如?PREROUTINGISTIO_INBOUNDISTIO_IN_REDIRECTOUTPUTISTIO_OUTPUTPOSTROUTING?等。假設現在有一個服務 A 想要調用非本地主機上的另一個 pod 中的服務 B,經過的網絡堆棧如下圖所示。

346e9c5fd8d67926d084c1a5359e0301.jpeg
非同主機 Pod 間的服務訪問路徑(iptables 模式)

從圖中我們可以看到整個調用流程中經過四次 iptables,其中 Pod A 中的從 Envoy 的出站(iptables2)和 Pod B 中的從 eth0 的入站(iptables3)的 iptables 路由是無法避免的,那么剩下的兩個 iptables1 和 iptables4 是否可以優化呢?讓兩個 socket 直接通信,不就可以縮短網絡路徑了嗎?這就需要通過 eBPF 編程,使得:

  • ? Service A 的流量從直接發送到 Envoy 的 Inbound socket 上;

  • ? Pod B 中 Envoy 接收到入站流量后,已經確定流量是要發送給本地的服務,直接對接 Outbound socket 與 Service B;

使用 eBPF 模式的透明流量攔截網絡路徑如下圖所示。

deb0fa895600abd444c47d88d3335940.jpeg
非同主機 Pod 間的服務訪問路徑(eBPF 模式)

如果要訪問的服務 A 和服務 B 在同一個節點上,那么網絡路徑將更短。

de8968770a594ae87eed41dae1c9517c.jpeg
同主機 Pod 間的網絡訪問路徑(eBPF 模式)

同一個節點中的服務間訪問完全繞過了 TCP/IP 堆棧,變成了 socket 間的直接訪問。

什么是 eBPF?

我們知道修改 Linux 內核代碼很難,新特性發布到內核中需要很長的周期。eBPF 是一個框架,允許用戶在操作系統的內核內加載和運行自定義程序。也就是說,有了 eBPF,你不需要直接修改內核,就可以擴展和改變內核的行為。下面我將簡要的為大家介紹一下 eBPF:

  • ? eBPF 程序加載到內核中后需要通過驗證器的驗證才可以運行,驗證器可以防止 eBPF 程序超越權限的訪問,這樣可以確保內核的安全;

  • ? eBPF 程序是附著于內核事件上的,當有進入或退出內核函數時被觸發;

  • ??內核空間的 eBPF 程序必須使用能夠支持生成 eBPF 字節碼格式的編譯器的語言編寫,目前你可以用 C 和 Rust 語言編寫 eBPF 程序;

  • ? eBPF 程序對于不同的 Linux 版本存在兼容性問題;

由于 eBPF 程序可以直接監聽和操作 Linux 內核,具有對系統最底層的透視,就可以在流量管理、可觀測性和安全發揮作用。有關 eBPF 的詳細介紹請參考筆者翻譯的《什么是 eBPF》[48]?電子書。

開源項目?Merbridge[49]?正是利用 eBPF 縮短了透明流量劫持的路徑,優化了服務網格的性能。關于 Merbridge 實現的一些細節,請參考?Istio 博客?[50]?。

注意

Merbridge 使用的 eBPF 函數需要 Linux 內核版本 ≥ 5.7。

乍看上去 eBPF 似乎從更底層實現了 Istio 的功能,更大有取代 sidecar 的趨勢。但是 eBPF 也存在很多局限性,導致在可以預見的未來無法取代服務網格和 Sidecar。如果取消 sidecar 轉而使用每個主機一個代理的模式,會導致:

  1. 1. 代理失敗的爆炸半徑擴大到整個節點,即一個代理失敗了,代理所在節點上的所有工作負載都會受到影響;

  2. 2. 使得安全問題更加復雜,因為一個節點上保存在太多負載的證書,一旦被攻擊,會存在秘鑰泄露的風險;

  3. 3. 主機上的 Pod 之間的流量爭搶問題,即節點上如果有一個工作負載消耗掉代理的所有資源,其他工作負載將無法獲得流量;

而且 eBPF 主要負責三 / 四層流量,可以與 CNI 一起運行,但是七層流量使用 eBPF 來處理就不太合適了。

在可以預見的未來 eBPF 技術無法取代服務網格和 Sidecar。

關于 eBPF 與服務網格的關系的更詳細介紹請參考博客請暫時拋棄使用 eBPF 取代服務網格和 Sidecar 模式的幻想?[51]?。

控制平面性能優化

以上兩種優化都是針對數據平面進行的,我們再來看下控制平面的性能優化。你可以把服務網格想象成是一場演出,控制平面是總導演,數據平面是所有演員,導演不參與演出,但是負責指揮演員。如果這場演出的情節很簡單,時長又很短,那要每個演員分配的戲份就會很少,排練起來就會很容易;如果是一個大型演出,演員的數量多,情節有很復雜,要想排練好這場演出,一個導演可能是不夠的,他指揮不了這么多演員,因此我們需要多名副導演(擴大控制平面實例數量);我們還需要給演員準備好臺詞和腳本,如果演員也可以一個鏡頭完成一連串的臺詞和場景的表演(減少都數據平面的打擾,批量推送更新),那我們的排練是不是更加高效?

從上面的類比中,你應該可以找到控制平面性能優化的方向了,那就是:

  • ??減少需要推送的配置大小;

  • ??批處理代理推送;

  • ??擴大控制平面規模;

減少需要推送的配置

控制平面性能優化最直接的方式就是減少要向數據平面推送的代理配置大小。假設有工作負載 A,如果僅將與 A 相關的代理配置(即 A 依賴的服務)推送給 A,而不是將網格內所有服務的配置都推送給 A,這樣就可以大大壓縮要推送的工作負載范圍及配置大小。Istio 中的 Sidecar 資源可以幫助我們實現這一點。下面是 Sidecar 配置示例:

apiVersion:?networking.istio.io/v1alpha3
kind:?Sidecar
metadata:name:?defaultnamespace:?cn-bj
spec:workloadSelector:labels:app:?app-aegress:-?hosts:-?"cn-bj/*"

我們通過?workloadSelector?字段可以限制該 Sidecar 配置適用的工作負載范圍,而?egress?字段可以確定該工作負載依賴的服務范圍,這樣控制平面就可以僅向服務 A 推送其依賴的服務配置,大大減低要向數據平面推送的配置大小,減少了服務網格的內存和網絡消耗。

批處理代理配置推送

控制平面 Istiod 向數據平面推送代理配置的過程比較復雜,下圖展示了其中的流程。

6e17d9aa4eae61966df6aa969563e33b.jpeg
Istiod 向數據平面推送代理配置的流程圖

管理員配置 Istio 網格后,Istiod 中推送代理配置的流程是這樣的:

  1. 1. 管理員更新 Istio 配置的事件會觸發數據平面代理的配置同步;

  2. 2.?Istio 的?DiscoveryServer?組件監聽到這些事件后不會立即將配置推送到數據平面,而是將這些事件添加到隊列中,持續合并一段時間內的事件,這個過程叫做去抖動(debouncing),就是為了防止頻繁的更新數據平面配置;

  3. 3. 在去抖動周期過后,這些事件將被推送到隊列中;

  4. 4. Istiod 會限制同時推送的請求數量,以加快推送進度;

  5. 5. 事件被轉換成 Envoy 的配置推送到數據平面的工作負載上;

從以上流程中我們可以看出,優化配置推送的關鍵就是步驟 2 中去抖動周期和步驟 4 中的限流設置。有這樣幾個環境變量可以幫助你設置控制平面的推送:

  • ??PILOT_DEBOUNCE_AFTER:指定去抖動的時間,將事件添加到推送隊列中,默認為 100 毫秒;

  • ??PILOT_DEBOUNCE_MAX:指定允許事件去抖動的最長時間,如果在這段時間內事件沒有新的變化則推送事件,默認為 10 秒;

  • ??PILOT_ENABLE_EDS_DEBOUNCE:指定端點更新是否符合去抖動規則或具有優先權并立即落入推送隊列,默認是開啟的,關閉它后可以加速 EDS 推送;

  • ??PILOT_PUSH_THROTTLE:指定同時處理的推送請求,默認是 100;

關于這些環境變量的默認值和具體配置請參考?Istio 文檔?[52]?。

這些值究竟如何設置,可以遵循以下原則:

  • ??如果控制平面資源空閑,為了加快配置更新的傳播速度,你可以:

    • ??縮短去抖動周期,增加推送次數;

    • ??增加同時處理的推送請求數量;

  • ??如果控制平面飽和,為了降低性能瓶頸,你可以:

    • ??延遲去抖動周期,減少推送次數;

    • ??增加同時處理的推送請求的數量;

至于如何設置最優解,需要結合你的可觀測系統來調試。

擴大控制平面規模

如果設置去抖動批處理和 Sidecar 還無法優化控制平面性能的話,最后的選擇就是擴大控制平面的規模,包括擴大單個 Istiod 實例的資源和增加 Istiod 的實例個數,究竟采用哪種擴展方式視情況而定:

  • ??當單個 Istiod 的資源占用飽和時,優先推薦你擴大 Istiod 的實例大小,這通常是因為服務網格中有太多的資源(Istio 的自定義資源,如 VirtualService、DestinationRule 等)需要處理;

  • ??如果增加 Istiod 實例的 CPU 和內存依然不起效的話,增加 Istiod 的實例個數,這樣可以分散單個實例要管理的工作負載數量;

數據平面性能優化

Apache SkyWalking 可以作為 Istio 提供可觀測性工具,還可以幫助我們在進行服務動態調試和故障排除剖析服務的性能,其最新推出的?Apache SkyWalking Rover[53]?組件可以利用 eBPF 技術來準確定位 Istio 的關鍵性能問題?9[54]。在數據平面,我們可以通過以下方式來增加 Envoy 的吞吐量以優化 Istio 的性能:

  • ??禁用 Zipkin 追蹤或減少采樣率

  • ??簡化訪問日志格式

  • ??禁用 Envoy 的訪問日志服務(ALS)

以上優化方式對 Envoy 吞吐量的影響數據請參閱?使用 eBPF 準確定位服務網格的關鍵性能問題?[55]?。

Envoy —— 服務網格的領銜主演

我們知道服務網格是由數據平面和控制平面組成的,從上面的服務網格開源項目列表中我們可以看到,服務網格開源項目大部分都是基于 Envoy,然后開發自己的控制平面。還記得我在本文前面將服務網格比作演出嗎?在這場服務網格的演出中,毫無疑問 Envoy 就是領銜主演 —— Envoy 發明的 xDS 協議,基本成為服務網格的通用 API。下面展示的是 Envoy 的架構圖。

41c7f264c67e791a93a21e562802f293.jpeg
Envoy 架構圖

xDS 是 Envoy 區別于其他代理的關鍵,它的代碼和解析流程十分復雜?10[56],直接擴展起來也很有難度。下面展示的是 Istio 組件拓撲圖,從圖中我們可以看到 Istio 數據平面的 Sidecar 容器中不止有?envoy?這一個進程,還有一個?pilot-agent?進程。

f64fffc3f81075b5ea1a90855c758847.jpeg
Istio 組件拓撲圖

pilot-agent?進程的作用如下:

  • ??作為?envoy?的父進程,負責 Envoy 的生命周期管理;

  • ??接收來自控制平面的推送,配置代理和證書;

  • ??收集 Envoy 統計信息,匯總 sidecar 的統計數據供 Prometheus 搜集;

  • ??內置本地 DNS 代理,用于解析 Kubernetes DNS 解析不了的集群內部域名的場景;

  • ??對 Envoy 和 DNS 代理進行健康檢查;

從以上功能中我們可以看出?pilot-agent?進程主要是用于與 Istiod 交互,為 Envoy 起到指揮和輔助的作用,Istio 的核心組件是 Envoy。那么 Envoy 會不會「演而優則導」,不再配合 Istio,構建一套自己的控制平面呢?

在 Sidecar 容器中,pilot-agent?就像是 Envoy 的 “Sidecar”。

請讀者思考一下

pilot-agent?的功能能否直接內置到 Envoy 中,從而取消?pilot-agent?呢?

Envoy Gateway 統一服務網格網關

在 Kubernetes 中,除 Service 資源對象之外,最早用來暴露集群中服務的資源對象是 Ingress。使用 Ingress 你只需要為集群開放一個對外的訪問點即可,通過 HTTP Hosts 和?path?來路由流量到具體的服務。相對于直接在?service?資源上暴露服務來說,可以減少集群的網絡訪問點(PEP)11[57]?,降低集群被網絡攻擊的風險。使用 Ingress 訪問集群內的服務流程如下圖所示。

b625d0f8c8b20ad8d3a9182accd7cf10.jpeg
Kubernetes Ingress 流量訪問流程圖

在 Kubernetes 之前,API Gateway 軟件就已經被廣泛用作邊緣路由了,在引用 Istio 時又增加了 Istio 自定義的 Gateway 資源,使得訪問 Istio 服務網格中的資源又多了一種選擇,如下圖所示。

4834baf81892be2441b2c40e166aac21.jpeg
訪問 Istio 網格中的服務的方式

現在,要想暴露單個 Istio 網格中的服務,NodePortLoadBalance、Istio 自定義 Gateway、Kubernetes Ingress 和 API Gateway 軟件,如何選擇?如果是多集群服務網格,客戶端如何訪問網格內的服務?我們的服務網格領銜主演 Envoy 已經在這方面做足了功夫,被以多種形式使用:

  • ? Sidecar Proxy:正如在前文中?[58]?提到的,Istio、Kuma、Consul Connect 都使用了 Envoy 作為 sidecar 代理;

  • ? Kubernetes Ingress Controller/API Gateway:Contour[59]?、Emissary[60]?、Hango[61]?、Gloo[62]?等;

這些項目利用 Envoy 來實現服務網格和 API 網關,其中有很多功能重疊,同時又有很多專有功能,或者缺乏社區多樣性,這種現狀由于 Envoy 社區沒有提供控制平面實現而導致的。為了改變現狀,Envoy 社區發起了?Envoy Gateway[63]?項目,該項目旨在結合現有的基于 Envoy 的 API Gateway 相關項目的經驗?12[64],利用帶有一些 Envoy 特定擴展的?Kubernetes Gateway API[65]?降低 Envoy 用戶使用網關的門檻。因為 Envoy Gateway 仍然通過 xDS 下發配置給 Envoy 代理,因此你還可以用它來管理支持 xDS 的網關,如 Istio Gateway。

我們現在所見的網關基本都是在單集群中作為入口網關,對于多集群和多網格就無能為力了。為了應對多集群,我們需要在 Istio 之上再添加一層網關,和一個全局的控制平面以在多集群間路由流量,如下圖所示。

d82b3355332c84f9c6e65f754aed9d1b.jpeg
關于兩級網關的簡要介紹
  • ??一級網關(下文簡稱 T1)位于應用邊緣,用于多集群環境。同一應用會同時托管在不同的集群上,T1 網關將對該應用的請求流量在這些集群之間路由。

  • ??二級網關(下文簡稱 T2)位于一個的集群邊緣,用于將流量路由到該集群內由服務網格管理的服務。

通過在 Istio 控制平面以外增加一層全局控制平面和 API,來實現多集群服務網格管理。將 T1 網關部署為集群,可以防止單點故障。想要了解關于兩級網關的更多內容,請參考通過兩級網關設計來路由服務網格流量?[66]?。

T1 網關的配置如下所示:

apiVersion:?gateway.tsb.tetrate.io/v2
kind:?Tier1Gateway
metadata:name:?service1-tier1group:?demo-gw-grouporganization:?demo-orgtenant:?demo-tenantworkspace:?demo-ws
spec:workloadSelector:namespace:?t1labels:app:?gateway-t1istio:?ingressgatewayexternalServers:-?name:?service1hostname:?servicea.example.comport:?80tls:?{}clusters:-?name:?cluster1weight:?75-?name:?cluster2weight:?25

該配置將?servicea.example.com?通過 T1 網關暴露到網格外,并將網格外訪問該服務的流量的?75%?轉發到?cluster125%?的流量轉發到?cluster2,另外為了應對多集群中的流量、服務和安全配置,Tetrate 旗艦產品 Tetrate Service Bridge 中還增加了 一系列 Group API,詳見?TSB 文檔?[67]?。

Istio 開源生態

Istio 開源在至今已經五年多了,近兩年來出現了很多基于 Istio 的開源項目,其中比較代表性的有:

  • ??網易開源的 Slime

  • ??騰訊開源的 Aeraki

  • ??Istio 官方對 Wasm 插件的支持

它們的出現使得 Istio 更加智能化并擴展了 Istio 的適用范圍。

Slime

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

我們在前文的控制平面性能優化?[69]?中提到了通過「減少需要推送的配置」的方式來優化 Istio 的性能,但是 Istio 無法做到自動識別無法依賴以最優化需要推送到每個 sidecar 的代理配置,Slime 提供了?lazyload?控制器,可以幫助我們實現配置懶加載,用戶無須手動配置?SidecarScope?13[70],Istio 可以按需加載服務配置和服務發現信息。

下圖展示的是 Slime 作為 Istio 的管理平面更新數據平面配置的流程圖。

872e018f3d6faf90e2fe55b9989d15fa.jpeg
使用 Slime 更新 Istio 數據平面配置的流程圖

其中,Global Proxy 使用 Envoy 構建,在每個需要啟動配置懶加載的命名空間中部署一個或在整個網格中只部署一個,所有缺失服務發現信息的調用(你也可以手動配置服務調用關系),都會被兜底路由劫持到 Global Proxy,經過其首次轉發后,Slime 便可感知到被調用方的信息,然后根據其對應服務的 VirtualService,找到服務名和真實后端的映射關系,將兩者的都加入 SidecarScope,以后該服務的調用就不再需要經過 Global Proxy 了。

數據平面配置更新的具體步驟如下:

  1. 1. Slime Operator 根據管理員的配置在 Kubernetes 中完成 Slime 組件的初始化,開發者創建符合 Slime CRD 規范的配置并應用到 Kubernetes 集群中;

  2. 2. Slime 持續監聽 Slime CRD 的創建;

  3. 3. Slime 查詢 Prometheus 中保存的相關服務的監控數據,結合 Slime CRD 中自適應部分的配置,將 Slime CRD 轉換為 Istio CRD,同時將其推送到 Global Proxy 中;

  4. 4. Istio 監聽 Istio CRD 的創建;

  5. 5. Istio 將代理的配置信息推送到數據平面相應的 Sidecar Proxy 中;

因為數據平面中的所有服務的首次調用都通過 Global Proxy,該 Proxy 可以記錄所有服務的調用和依賴信息,根據該依賴信息更新 Istio 中 Sidecar 資源的配置;當某個服務的調用鏈被 VirtualService 中的路由信息重新定義時, Global Proxy 原有記錄就失效了,需要一個新的數據結構來維護該服務的調用關系。Slime 創建了名為?ServiceFence?的 CRD 來維護服務調用關系以解決服務信息缺失問題,詳見?Slime 簡介?[71]?。

Aeraki

Aeraki Mesh[72]?是騰訊云在 2021 年 3 月開源的一個服務網格領域的項目,基于 Istio 擴展其對七層協議的支持,專注于解決 Istio 中的?非 HTTP 協議的服務治理,已于 2022 年 6 月進入 CNCF Sandbox。

下圖展示了 Aeraki 將非 HTTP 協議納入到 Istio 網格中的流程圖。

49e830cd76fae6a8ae25a892c4a10a40.jpeg
Aeraki 將非 HTTP 協議納入到 Istio 網格中的流程圖

其詳細流程如下:

  1. 1. Aeraki 的 X2Istio 組件對接服務注冊中心,獲取非 HTTP 服務的注冊信息,并生成 ServiceEntry 向 Istio 中注冊;

  2. 2. Aeraki 作為 Istio 之上的管理平面,它從 Istio 中獲取 ServiceEntry 配置;

  3. 3.?Aeraki 通過端口命名規判斷服務的協議類型(如?tcp-metaprotocol-dubbo),然后生成 MetaProtocol Proxy Filter(兼容 EnvoyFilter)配置,同時修改 RDS 地址,將其指向 Aeraki;

  4. 4. Istio 使用 xDS 協議將配置(LDS、CDS、EDS 等)下發給數據平面;

  5. 5. Aeraki 根據服務注冊表中的信息和用戶設置生成路由規則,通過 RDS 發送給數據平面;

在 Istio 中接入非 HTTP 服務的整個流程中的關鍵是?MetaProtocol Proxy?。Istio 默認支持 HTTP/HTTP2、TCP 和 gRPC 協議,實驗性支持 Mongo、MySQL 和 Redis 協議?14[73]。若要使用 Istio 路由其他協議的流量,不僅需要修改 Istio 控制平面并擴展 Envoy,這將帶來巨大的工作量,而且不同協議共享通用的控制邏輯,這還會帶來很多重復性工作。MetaProtocol Proxy 是在 Envoy 代碼基礎上的擴展,為七層協議統一實現了服務發現、負載均衡、RDS 動態路由、流量鏡像、故障注入、本地 / 全局限流等基礎能力,大大降低了在 Envoy 上開發第三方協議的難度。

下圖展示的 MetaProtocol Proxy 的架構圖。

13d63ba03495e0eca7fed56946f3f51b.jpeg
MetaProtocol Proxy 架構圖

當我們想擴展 Istio 使其支持 Kafka、Dubbo、Thrift 等其他七層協議時,只需要實現上圖中的編解碼的接口(Decode 和 Encode),就可以基于 MetaProtocol 快速開發一個第三方協議插件。MetaProtocol Proxy 是在 Envoy 基礎上的擴展,因此你仍然可以使用多種語言為其開發過濾器,并使用?EnvoyFilter?資源將配置下發到數據平面。

WasmPlugin API

WasmPlugin[74]?是 Istio 1.12 版本引入的 API,作為代理擴展機制,我們可以使用它將自定義和第三方的 Wasm 模塊添加到數據平面中。下圖中展示了如何在 Istio 中使用 WasmPlugin。

2a213a4e5979ff488000656f80248213.jpeg
在 Istio 中使用 WasmPlugin 的流程圖

具體步驟如下:

  1. 1.?用戶使用?Proxy-Wasm SDK[75]?(目前有 AssemblyScript、C++、Rust、Zig 和 Go 語言版本)來開發擴展,并構建成 OCI 鏡像(如 Docker 鏡像)上傳到鏡像倉庫;

  2. 2.?用戶編寫?WasmPlugin?配置并應用到 Istio;

  3. 3.?Istio 控制平面根據?WasmPlugin?配置中的工作負載選擇配置,將 Wasm 模塊注入到指定的 Pod 中;

  4. 4.?Sidecar 中的?pilot-agent?15[76]?從遠程或本地文件中獲取 Wasm 模塊并將其加載到 Envoy 中運行;

誰應該使用 Istio?

好了,說了這么說,這跟你有什么關系呢?Istio 跟你的關系取決于你的角色:

  • ??如果你是平臺負責人,應用服務網格后,可能增強你的平臺可觀測性,具有了一個統一的平臺來管理微服務,你將是直接受益者,也應該是服務網格的主要實施者;

  • ??如果是應用程序開發者,也會從服務網格中收益,因為你可以更加專屬于業務邏輯,而不用擔心重試策略、TLS 等其他非功能性問題;

下圖展示了服務網格的采用路徑。

a74ec8e793586877effa5a8de39a66ed.jpeg
服務網格的采用路徑

是否采用服務網格取決于你公司的技術發展階段,應用是否實現容器化和微服務,對多語言的需求,是否需要 mTLS 以及對性能損耗的接納度等。

服務網格在云原生技術棧中的定位

技術的發展日新月異,近兩年來有一些新技術出現,似乎挑戰了服務網格的地位,更有人聲稱可以直接取代現有經典的 sidecar 模式的服務網格?16[77],我們不要被外界嘈雜的聲音所迷惑,認清服務網格在云原生技術棧中的定位。

一味地推廣某項技術而忽略它的適用場景,就是耍流氓。

下圖展示的是云原生技術堆棧。

c7a0224fff937f50f5a14b174b6a9c97.jpeg
云原生技術堆棧示意圖

我們可以看到,在云原生技術堆棧圖中的「云基礎設施」、「中間件」和「應用」層都列舉了一些標志性的開源項目,這些項目構建了它們所在領域的標準:

  • ??在云基礎設施領域,Kubernetes 統一了容器編排和應用生命周期管理的標準,Operator 模式奠定了擴展 Kubernetes API 及第三方應用接入的標準;

  • ??在中間件領域,服務網格承擔起了云原生技術棧中的七層網絡、可觀測性和安全等多個方面的部分或全部責任,它運行在應用程序下層,對于應用程序來說幾乎是無感知的;Dapr(分布式應用程序運行時)定義云原生中間件的能力模型,開發者可以在應用中集成 Dapr 的多語言 SDK,面向 Dapr 提供的分布式能力編程,而不用關心應用所運行的環境及對接的后端基礎設施。因為在和應用程序運行在同一個 Pod 中的 Dapr 運行時(Sidecar 模式部署,其中包含各種構建塊)自動幫我們對接了后端組件(Component);

  • ??在應用程序領域:OAM 旨在建立一個應用模型標準,通過組件、特征、策略和工作流來一個應用程序,詳見云原生資料庫?[78]?;

下圖展示了 Istio 在云原生部署中定位于七層網格管理。

f809a6d6252bcbd17bbc61f35af10e42.jpeg
Istio 在云原生架構中定位在七層網絡

Dapr 與 Istio 是什么關系?

在云原生技術棧中,Istio 和 Dapr 同時位于中間件層,它們之間有很多區別和聯系。

Istio 和 Dapr 之間的相同點:

  • ? Istio 和 Dapr 都可以使用 Sidecar 模式的部署模型;

  • ??同屬于中間件,同樣可以管理服務間通信;

Istio 和 Dapr 之間的不同點:

  • ??目標不同:Istio 的目標是構建零信任網絡,定義服務間通信標準,Dapr 目標是構建標準的中間件能力的 API;

  • ??架構不同:Istio = Envoy + 透明流量劫持 + 控制平面,Dapr = 多語言 SDK + 標準化 API + 分布式能力組件;

  • ??面向的人群不同:但是應用 Istio 對于開發者來說幾乎無感知,主要需要基礎設施運維團隊實施,而應用 Dapr 需要開發者自主選擇集成 Dapr SDK;

服務網格的未來

我在前文中介紹了 Istio 的發展脈絡及開源生態,接下來我將為大家介紹 Istio 服務網格的未來趨勢:

  • ??構建零信任網絡

  • ??成為混合云管理平臺的網絡基礎設施

服務網格的未來在于成為零信任網絡和混合云的基礎設施。

這也是筆者所在的公司企業級服務網格提供商?Tetrate[79]?的努力方向,我們致力于構建一個基于零信任的適用于任意環境、任意負載的應用感知網絡。下面展示的是 Tetrate 旗艦產品?Tetrate Service Bridge[80]?的架構圖。

8e835a10c521c22e1d14014b0e2c420f.jpeg
TSB 架構圖

Tetrate 公司是由 Istio 項目的發起人創立的,TSB 是基于開源的 Istio、Envoy 和 Apache SkyWalking 開發的。我們同時積極得貢獻上游社區,并參與了旨在簡化將 Envoy 網關使用的?Envoy Gateway[81]?項目的創建(上圖中的 XCP 即使用 Envoy 構建的網關)。

零信任

零信任(Zero Trust)是 IstioCon 2022 里的一個重要話題,Istio 正在成為零信任網絡的一個重要組成部分。

什么是零信任?

零信任(Zero Trust)是一種安全理念,而不是一種所有安全團隊都要遵循的最佳實踐。零信任概念的提出是為了給云原生世界帶來更安全的網絡。零信任是一種理論狀態,即網絡內的所有消費者不僅沒有任何權限,而且也不具備對周圍網絡的感知。零信任的主要挑戰是就越來越細化的授權和和對用戶授權的時間限制。關于更多零信任的介紹,請閱讀這篇博客?[82]?。

身份認證

零信任網絡中最重要的是面向身份的控制而不是面向網絡的控制。Istio 1.14 中增加了對 SPIRE 的支持,SPIRE(SPIFFE Runtime Environment,CNCF 孵化項目) 是 SPIFFE(Secure Production Identity Framework For Everyone,CNCF 孵化項目) 的一個實現。在 Kubernetes 中我們使用?ServiceAccount[83]?為 Pod 中的工作負載提供身份信息,其核心是基于 Token(使用 Secret 資源存儲)來表示負載身份。而 Token 是 Kubernetes 集群中的資源,對于多集群及運行在非 Kubernetes 環境(例如虛擬機)中的負載,如何統一它們的身份?這就是 SPIFFE 要解決的問題。

SPIFFE 的目的是基于零信任的理念,建立一個開放、統一的工作負載身份標準,這有助于建立一個零信任的全面身份化的數據中心網絡。SPIFFE 的核心是通過簡單 API 定義了一個生命周期短暫的加密身份文件 —— SVID(SPFFE Verifiable Identity Document),用作工作負載認證時使用的身份文件(基于 X.509 證書或 JWT 令牌)。SPIRE 可以根據管理員定義的策略自動輪換 SVID 證書和秘鑰,動態地提供工作負載標識,同時 Istio 可以通過 SPIRE 動態的消費這些工作負載標識。

基于 Kubernetes 的 SPIRE 架構圖如下所示。

6f9d869d34cbc68e081055e1ce8c2978.jpeg
SPIRE 部署在 Kubernetes 中的架構圖

Istio 中原先是使用 Istiod 中 Citadel 服務?17[84]?負責服務網格中證書管理,通過 xDS(準確的說是 SDS API)協議將證書下發給數據平面。有了 SPIRE 之后,證書管理的工作就交給了 SPIRE Server。SPIRE 同樣支持 Envoy SDS API,我們在 Istio 中啟用 SPIRE 之后,進入工作負載 Pod 中的流量在被透明攔截到 Sidecar 中后,會經過一次身份認證。身份認證的目的是對比該工作負載的身份,與它所運行的環境信息(所在的節點、Pod 的 ServiceAccount 和 Namespace 等)是否一致,以防止偽造身份。請參考?如何在 Istio 中集成 SPIRE[85]?以了解如何在 Istio 中使用 SPIRE 做身份認證。

我們可以使用?Kubernetes Workload Registrar[86]?在 Kubernetes 中部署 SPIRE,它會為我們自動注冊 Kubernetes 中的工作負載并生成 SVID。該注冊機是 Server-Agent 架構,它在每個 Node 上部署一個 SPIRE Agent,Agent 與工作負載通過共享的 UNIX Domain Socket 通信。零信任網絡中每個流量會話都需要經過身份認證,Istio 在透明流量劫持時,Sidecar 同時對流量請求進行身份認證。下圖展示了在 Istio 中使用 SPIRE 進行身份認證的過程。

659e1ed43f46da2a30517c2357b60ea1.jpeg
Istio 中基于 SPIRE 的工作負載身份認證過程示意圖

Istio 中使用 SPIRE 進行工作負載認證的步驟如下:

  1. 1.?工作負載的 sidecar 中的?pilot-agent?通過共享的 UDS 調用 SPIRE Agent 來獲取 SVID 并緩存在 SPIRE Agent 中用于后續身份認證;

  2. 2. SPIRE Agent 詢問 Kubernetes(準確的說是節點上的 kubelet)獲取工作負載的信息,如所在的 namespace、節點名稱、服務賬號等;

  3. 3. Kubelet 把從 API 服務器中查詢到的信息返回給工作負載驗證器;

  4. 4. 驗證器將 kubelet 返回的結果與 SPIRE 查詢得到的身份信息比對,如果相同,則將正確的 SVID 緩存返回給工作負載,如果不同則認證失敗,拒絕流量請求;

關于工作負載的注冊和認證的詳細過程請參考?SPIRE 文檔?[87]?。

NGAC

當每個工作負載都有準確的身份之后,如何對這些身份的權限進行限制?Kubernetes 中默認使用 RBAC 來做訪問控制,正如其名,這種訪問控制是基于角色的,雖然使用起來比較簡單,但是對于大規模集群,存在角色爆炸問題 —— 即存在太多角色,而且角色的類型不是一成不變的,難以對角色權限機型跟蹤和審計。另外 RBAC 中的角色的訪問權限是固定,沒有規定短暫的使用權限,也沒有考慮位置、時間或設備等屬性。使用 RBAC 的企業很難滿足復雜的訪問控制要求,以滿足其他組織需求的監管要求。

NGAC,即下一代訪問控制,采用將訪問決定數據建模為 DAG (有向無環圖)的方法。NGAC 可以實現系統化、策略一致的訪問控制方法,以高精細度授予或拒絕用戶管理能力。NGAC 由?NIST[88]?(美國國家標準與技術研究所)開發,目前已用于?Tetrate Service Bridge[89]?中的權限管理。關于為什么選擇 NGAC,而不是 ABAC 和 RBAC 的更多內容請參考博客?為什么應該選擇使用 NGAC 作為權限控制模型?[90]?。

混合云

在實際應用中,我們可能出于負載均衡、隔離開發和生產環境、解耦數據處理和數據存儲、跨云備份和災難恢復以及避免廠商鎖定等原因,在多種環境下部署多個 Kubernetes 集群。Kubernetes 社區提供了「集群聯邦」功能可以幫助我們創建多集群架構,例如下圖所示的一種常用的 Kubernetes 多集群架構,其中 Host Cluster 作為控制平面,有兩個成員集群,分別是 West 和 East。

637d1788a3cdf1c04f7df43dd00780ef.jpeg
Kubernetes 集群聯邦架構

集群聯邦要求 Host 集群與成員集群的之間的網絡能夠互通,對成員集群之間的網絡連接性沒有要求。Host 集群作為 API 入口,外界所有對 Host 集群的資源請求會轉發到成員集群中。Host 集群中部署有集群聯邦的控制平面,其中的 「Push Reconciler」會將聯邦中的身份、角色及角色綁定傳播到所有的成員集群中。集群聯邦只是簡單地將多個集群簡單的「連接到了一起」,在多個集群之間復制工作負載,而成員集群之間的流量無法調度,也無法實現真正的多租戶。

集群聯邦不足以實現混合云,為了實現真正意義上的混合云,就要讓集群之間做到互聯互通,同時實現多租戶。TSB 在 Istio 之上構建一個多集群管理的通用控制平面,然后再增加一個管理平面來管理多集群,提供多租戶、管理配置、可觀察性等功能。下面是 Istio 管理平面的多租戶和 API 示意圖。

b9210a7d973db72f1c6140aef32c5339.jpeg
TSB 在 Istio 之上構建的管理平面示意圖

TSB 為管理混合云,基于 Istio 構建了一個管理平面,新建了 Tenant 和 Workspace 的資源,并通過選擇器,將網關組、流量組和安全組應用到對應集群中的工作負載上。關于 TSB 的詳細架構請參考?TSB 文檔?[91]?。

更多

如果你想了解更多關于 Istio 和云原生的內容,下面有一些資料分享給你:

  • ??為了幫助大家更好的了解 Istio 和云原生,筆者在 2020 年發起了云原生社區?[92]?,歡迎大家加入我們一起探索后 Kubernetes 時代的云原生新范式;

  • ??2022 年 6 月,云原生社區著的《深入理解 Istio —— 云原生服務網格進階實戰》[93]?已圖書由電子工業出版社出版,歡迎大家購買;

  • ??筆者于 2022 年 5 月,將之前所作電子書、教程和譯文全部遷移到了云原生資料庫?[94]?,歡迎閱讀和留言評論。

引用鏈接

[1]?《Beyond Istio OSS —— Istio 的現狀及未來》:?https://giac.msup.com.cn/2022sz/course?id=16093
[2]?騰訊文檔:?https://docs.qq.com/pdf/DRWxETHNDZmRsS0l5
[3]?SOFAStack:?https://www.sofastack.tech/
[4]?1:?https://jimmysong.io/blog/beyond-istio-oss/#fn:1
[5]?CNCF:?https://cncf.io/
[6]?2:?https://jimmysong.io/blog/beyond-istio-oss/#fn:2
[7]?3:?https://jimmysong.io/blog/beyond-istio-oss/#fn:3
[8]?Tetrate:?https://tetrate.io/
[9]?4:?https://jimmysong.io/blog/beyond-istio-oss/#fn:4
[10]?Slime:?https://github.com/slime-io/slime/
[11]?Areaki:?https://github.com/aeraki-mesh/aeraki
[12]?Merbridge:?https://github.com/merbridge/merbridge
[13]?Kubernetes:?https://lib.jimmysong.io/kubernetes-handbook/architecture/
[14]?Istio 的架構:?https://istio.io/latest/zh/docs/ops/deployment/architecture/
[15]?5:?https://jimmysong.io/blog/beyond-istio-oss/#fn:5
[16]?Envoy:?https://envoyproxy.io/
[17]?MOSN:?https://mosn.io/
[18]?Ingress:?https://lib.jimmysong.io/kubernetes-handbook/concepts/ingress/
[19]?6:?https://jimmysong.io/blog/beyond-istio-oss/#fn:6
[20]?Istio 中的 Sidecar 注入、透明流量劫持及流量路由過程詳解:?https://jimmysong.io/blog/sidecar-injection-iptables-and-traffic-routing/
[21]?性能優化:?https://jimmysong.io/blog/beyond-istio-oss/#performance-optimizing
[22]?為什么需要可編程代理:?https://cloudnative.to/blog/what-and-why-programmable-proxy/
[23]?Squid:?http://www.squid-cache.org/
[24]?Varnish:?https://varnish-cache.org/
[25]?Pypi:?https://flomesh.io/
[26]?7:?https://jimmysong.io/blog/beyond-istio-oss/#fn:7
[27]?Linkerd2-proxy:?https://github.com/linkerd/linkerd2-proxy
[28]?Envoy:?https://www.envoyproxy.io/
[29]?Traefik Proxy:?https://traefik.io/traefik/
[30]?Envoy:?https://www.envoyproxy.io/
[31]?Envoy:?https://www.envoyproxy.io/
[32]?貢獻指南:?https://github.com/hashicorp/consul/blob/master/.github/CONTRIBUTING.md
[33]?貢獻指南:?https://github.com/traefik/mesh/blob/master/CONTRIBUTING.md
[34]?Istio:?https://istio.io/
[35]?Linkerd:?https://linkerd.io/
[36]?Traefik Mesh:?https://traefik.io/traefik-mesh/
[37]?Kuma:?https://kuma.io/
[38]?Consul Connect:?https://www.consul.io/docs/connect
[39]?Open Service Mesh:?https://openservicemesh.io/
[40]?Envoy:?https://envoyproxy.io/
[41]?Service Mesh Performance(SMP):?https://smp-spec.io/
[42]?Service Mesh Interface(SMI):?https://smi-spec.io/
[43]?Network Service Mesh:?https://networkservicemesh.io/
[44]?基于 gRPC 和 Istio 的無 sidecar 代理的服務網格:?https://lib.jimmysong.io/translation/grpc-proxyless-service-mesh/
[45]?引導文件:?https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md#xdsclient-and-bootstrap-file
[46]?8:?https://jimmysong.io/blog/beyond-istio-oss/#fn:8
[47]?透明流量劫持:?https://jimmysong.io/blog/beyond-istio-oss/#traffic-intercept
[48]?《什么是 eBPF》:?https://lib.jimmysong.io/what-is-ebpf/
[49]?Merbridge:?https://github.com/merbridge/merbridge
[50]?Istio 博客:?https://istio.io/latest/zh/blog/2022/merbridge/
[51]?請暫時拋棄使用 eBPF 取代服務網格和 Sidecar 模式的幻想:?https://jimmysong.io/blog/ebpf-sidecar-and-service-mesh/
[52]?Istio 文檔:?https://istio.io/latest/docs/reference/commands/pilot-agent/#envvars
[53]?Apache SkyWalking Rover:?https://github.com/apache/skywalking-rover
[54]?9:?https://jimmysong.io/blog/beyond-istio-oss/#fn:9
[55]?使用 eBPF 準確定位服務網格的關鍵性能問題:?https://lib.jimmysong.io/blog/pinpoint-service-mesh-critical-performance-impact-by-using-ebpf/#introducing-skywalking-rover
[56]?10:?https://jimmysong.io/blog/beyond-istio-oss/#fn:10
[57]?11:?https://jimmysong.io/blog/beyond-istio-oss/#fn:11
[58]?前文中:?https://jimmysong.io/blog/beyond-istio-oss/#are-they-service-mesh
[59]?Contour:?https://github.com/projectcontour/contour
[60]?Emissary:?https://github.com/emissary-ingress/emissary
[61]?Hango:?https://github.com/hango-io/hango-gateway
[62]?Gloo:?https://github.com/solo-io/gloo
[63]?Envoy Gateway:?https://github.com/envoyproxy/gateway
[64]?12:?https://jimmysong.io/blog/beyond-istio-oss/#fn:12
[65]?Kubernetes Gateway API:?https://gateway-api.sigs.k8s.io/
[66]?通過兩級網關設計來路由服務網格流量:?https://lib.jimmysong.io/blog/designing-traffic-flow-via-tier1-and-tier2-ingress-gateways/
[67]?TSB 文檔:?https://docs.tetrate.io/service-bridge/1.4.x
[68]?Slime:?https://github.com/slime-io/slime/
[69]?控制平面性能優化:?https://jimmysong.io/blog/beyond-istio-oss/#control-plane-perf-optimizing
[70]?13:?https://jimmysong.io/blog/beyond-istio-oss/#fn:13
[71]?Slime 簡介:?https://jimmysong.io/blog/slime-intro/
[72]?Aeraki Mesh:?https://github.com/aeraki-mesh/aeraki
[73]?14:?https://jimmysong.io/blog/beyond-istio-oss/#fn:14
[74]?WasmPlugin:?https://istio.io/latest/docs/reference/config/proxy_extensions/wasm-plugin/
[75]?Proxy-Wasm SDK:?https://github.com/proxy-wasm
[76]?15:?https://jimmysong.io/blog/beyond-istio-oss/#fn:15
[77]?16:?https://jimmysong.io/blog/beyond-istio-oss/#fn:16
[78]?云原生資料庫:?https://lib.jimmysong.io/cloud-native-handbook/intro/define-cloud-native-app/
[79]?Tetrate:?https://www.tetrate.io/
[80]?Tetrate Service Bridge:?https://www.tetrate.io/tetrate-service-bridge/
[81]?Envoy Gateway:?https://github.com/envoyproxy/gateway
[82]?這篇博客:?https://jimmysong.io/blog/what-is-zero-trust/
[83]?ServiceAccount:?https://lib.jimmysong.io/kubernetes-handbook/auth/serviceaccount/
[84]?17:?https://jimmysong.io/blog/beyond-istio-oss/#fn:17
[85]?如何在 Istio 中集成 SPIRE:?https://jimmysong.io/blog/how-to-integrate-spire-with-istio/
[86]?Kubernetes Workload Registrar:?https://github.com/spiffe/spire/blob/main/support/k8s/k8s-workload-registrar/README.md
[87]?SPIRE 文檔:?https://lib.jimmysong.io/kubernetes-handbook/concepts/spire/
[88]?NIST:?https://www.nist.gov/
[89]?Tetrate Service Bridge:?https://www.tetrate.io/tetrate-service-bridge/
[90]?為什么應該選擇使用 NGAC 作為權限控制模型:?https://jimmysong.io/blog/why-you-should-choose-ngac-as-your-access-control-model/
[91]?TSB 文檔:?https://docs.tetrate.io/service-bridge/1.4.x/en-us/concepts/architecture
[92]?云原生社區:?https://cloudnative.to/
[93]?《深入理解 Istio —— 云原生服務網格進階實戰》:?https://jimmysong.io/blog/istio-service-mesh-book/
[94]?云原生資料庫:?https://lib.jimmysong.io/

獲取更多云原生社區資訊,加入微信群,請加入云原生社區,點擊閱讀原文了解更多。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284368.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284368.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284368.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

js多維數組扁平化

數組扁平化,就是將多維數組碾平為一維數組,方便使用。 一:例如,一個二維數組 var arr [a, [b, 2], [c, 3, x]],將其扁平化: 1. 通過 apply 借用數組的 concat 方法: [].concat.apply([], arr)…

第16講 用戶程序的結構與執行

轉載于:https://www.cnblogs.com/atuo/p/5609843.html

兩種方法清除Excel保護密碼

一、利用VBA腳本直接清除 打Excel,打開腳本編輯器(AltF11)或者如圖,右鍵sheet名稱 輸入代碼并運行,即可清除密碼保護: Sub DeletePW()ActiveSheet.Protect DrawingObjects:True, Contents:True, AllowFil…

jsonp-反向代理-CORS解決JS跨域問題的個人總結

jsonp-反向代理-CORS解決JS跨域問題的個人總結 網上說了很多很多,但是看完之后還是很混亂,所以我自己重新總結一下。解決 js 跨域問題一共有8種方法, jsonp(只支持 get)反向代理CORSdocument.domain iframe 跨域windo…

URAL 1682 Crazy Professor (并查集)

【題目鏈接】 http://acm.timus.ru/problem.aspx?space1&num1682 【題目大意】 給出k,從1開始不斷地加一并把這個數寫在黑板上,如果寫上的數字和之前的數字滿足   (ab*b)%k0或者(ba*a)%k0就在他們之間連一條線,如果黑板上出現環就結束…

利用Python隨機或暴力生成密碼

""" Title: python 密碼生成 Author: JackieZheng Date: 2022-04-09 12:47:33 LastEditTime: 2022-04-09 14:00:46 LastEditors: Please set LastEditors Description: FilePath: \\pythonCode\\python_pwd_generater.py """import itertools im…

EasyNetQ-用于使用 RabbitMQ 的 .NET API開源的工具庫

Part1介紹EasyNetQ 的目標是提供一個庫,用于在 .NET 中使用 RabbitMQ 盡可能簡單。為了做到這一點,它通過強制執行一些簡單的約定來以靈活性換取簡單性。這些包括:消息應該由 .NET 類型表示。消息應按其 .NET 類型進行路由。這意味著消息是由…

python 中 __name__ 的使用

1. 如果模塊是被導入,__name__的值為模塊名字2. 如果模塊是被直接執行,__name__的值為’__main__’Py1.py #!/usr/bin/env python def test():print __name__ ,__name__ if __name__ __main__:test() Py2.py #!/usr/bin/env pyt…

第6章 循環

6.1 range 函數用來創建一個數字列表,它的范圍是從起始數字開始到結束數字之前 1 >>> for x in range(0,5): 2 print(Hello %s % x) 3 4 Hello 0 5 Hello 1 6 Hello 2 7 Hello 3 8 Hello 4 1 >>> print(list(range(10,20))) 2 [10, 11, 12, …

C# 實例解釋面向對象編程中的依賴反轉原則

在面向對象編程中,SOLID 是五個設計原則的首字母縮寫,旨在使軟件設計更易于理解、靈活和可維護。這些原則是由美國軟件工程師和講師羅伯特C馬丁(Robert Cecil Martin)提出的許多原則的子集,在他2000年的論文《設計原則與設計模式》中首次提出…

Linux學習筆記之一————什么是Linux及其應用領域

1.1認識Linux 1)什么是操作系統 2)現實生活中的操作系統 win7 Mac Android iOS 3) 操作系統的發展史 (1)Unix 1965年之前的時候,電腦并不像現在一樣普遍,它可不是一般人能碰的起的,…

Flex中寬度計算

flex 有三個屬性值,分別是 flex-grow, flex-shrink, flex-basis,默認值是 0 1 auto。 發現網上詳細介紹他們的文章比較少, 今天就詳細說說他們,先一個一個看。 flex-grow 定義項目的放大比例,默…

Lucene詳解

一.lucene原理 Lucene 是apache軟件基金會一個開放源代碼的全文檢索引擎工具包,是一個全文檢索引擎的架構,提供了完整的查詢引擎和索引引擎,部分文本分析引擎。它不是一個完整的搜索應用程序,而是為你的應用程序提供索引和搜索功能…

.NET 6.0中使用Identity框架實現JWT身份認證與授權

原文作者:Sarathlal Saseendran原文鏈接:https://www.c-sharpcorner.com/article/jwt-authentication-and-authorization-in-net-6-0-with-identity-framework/翻譯:沙漠盡頭的狼(谷歌翻譯加持)介紹微軟于 2021 年 11 …

adb devices 里面有很多 emulator-XXXX的解決方法

2019獨角獸企業重金招聘Python工程師標準>>> adb kill-server 轉載于:https://my.oschina.net/sfshine/blog/700354

MQ(Message Queue)簡介

一、何為MQ? MQ全稱為Message Queue, 消息隊列(MQ)是一種應用程序對應用程序的通信方法。應用程序通過讀寫出入隊列的消息(針對應用程序的數據)來通信,而無需專用連接來鏈接它們。消息傳遞指的是程序之間通…

【GlobalMapper精品教程】015:矢量面圖層的創建及數字化操作

本文講解在Globalmapper中文23.0中創建矢量面狀數據(政區數據),并進行面狀數據采集及編輯的詳細操作流程,數據為配套案例數據包中的data015.rar。 參考閱讀: ArcGIS實驗教程——實驗三:矢量數據采集與編輯(矢量化) 文章目錄 一、認識工具條1. 數字化(創建)工具條2. 選…

Blazor University (39)JavaScript 互操作 —— 更新 document title

原文鏈接:https://blazor-university.com/javascript-interop/calling-javascript-from-dotnet/updating-the-document-title/更新 document title源代碼[1]在創建 Blazor 布局[2]部分中,我們看到了 Blazor 應用程序如何存在于 HTML(或 cshtm…

IIS 日志文件位置

IIS 6 Log files location IIS 6中日志文件的位置%windir%\System32\LogFilesIIS 7 Log files location IIS的日志文件的位置%SystemDrive%\inetpub\logs\LogFiles用戶每打開一次網頁,iis 都會記錄用戶IP、訪問的網頁地址、訪問時間、訪問狀態等信息,這些…

APP測試流程和測試點

1 APP測試基本流程 1.1流程圖 1.2測試周期 測試周期可按項目的開發周期來確定測試時間,一般測試時間為兩三周(即15個工作日),根據項目情況以及版本質量可適當縮短或延長測試時間。正式測試前先向主管確認項目排期。 1.3測試資源 測…