
Istio 如今是 Service Mesh 中最火熱的項目了,它主要負責對服務網格中的流量進行管理,包括動態服務發現、服務路由、彈性功能等。它做爲 Service Mesh 的控制平面,配合 Envoy 做爲數據平面,構成了 Service Mesh 中流量管理體系。java
Istio 體系中流量管理配置以及相關機制比較冗雜,本文會盡可能從總體上進行描述,不摳細節,以求有一個宏觀的理解。node
爲何須要 Service Mesh
咱們首先要明白爲何會催生出 service mesh 這樣的架構,而要理解這一點,咱們須要對比 2 種東西,即傳統微服務架構以及原生 k8s 架構。c++
傳統微服務
咱們知道現有的微服務架構已經比較成熟了,擁有完善的服務註冊發現與服務治理功能(包括限流熔斷、負載均衡、流量路由等),那麼仍然困擾咱們的是什麼呢?git
現有的微服務框架幾乎都是集成於客戶端 sdk 的,開發者在本身的應用中集成微服務框架 sdk,從而具備服務治理相關功能,那麼這會帶來 2 個幾乎沒法避免的問題:應用須要不斷更新代碼從而更新客戶端 sdk,而這中間可能出現各類依賴衝突;應用集成並使用客戶端 sdk 依賴於開發者的素質,經常致使效率低下。github
這種狀況下,咱們天然而然地會想到使用 sidecar,將原先在 sdk 中的邏輯搬到 sidecar 上,在運維的時候與應用服務集成在一塊兒,造成一種較 sdk 集成更先進的邊車模式。這種方式對應用代碼幾乎沒有侵入,而且也不受開發者的水平限制,徹底作到了控制與邏輯的分離。固然做爲易用性的代價,咱們會失去一些性能。面試
sidecar 模式是 service mesh 相較微服務架構最主要的優勢之一,而這在 service mesh 架構中也稱爲"數據平面"。api
原生 k8s
這裏咱們思考的是在 k8s 之上,咱們還有什麼不知足?k8s 使用 kube-dns 以及 kube-proxy 配合 service 的概念支持了服務的註冊與發現,意味着咱們有了能夠在 k8s 上構建微服務的基礎。但在實際生產中,咱們每每須要對流量更精細的管控,咱們但願對單個 pod 或者一組 pod 的流量進行管理,而不只僅是 service 的維度。例如一個需求是咱們須要將 endpoints 下的一部分 pod 做爲 v1 版本,其他做爲 v2 版本,而/v1 前綴的請求都將調度到 v1 版本,/v2 前綴的請求調度到 v2 版本。網絡
sidecar 做爲數據平面與每個應用部署在同一 pod 中,這意味着咱們能夠作到對 pod 級別的流量作管理了,而具體實現這一邏輯的就是 service mesh 中的另外一層:"控制平面"了。架構
Istio 的架構
Istio 是目前 Service Mesh 領域最火熱的架構,咱們來看看 Istio 的總體架構。負載均衡

Istio 分爲數據平面以及控制平面,數據平面以 sidecar 的形式與應用部署在一塊兒,承載其流量的發送與接收,而控制平面則是經過配置和控制消息來組織編排網絡的邏輯,並下發給數據平面。
咱們簡單講一下其中的組件:
-
Envoy: Envoy 是 c++開發的高性能代理,在 Istio 中被用於數據平面(圖中即 Proxy),控制應用的入站和出站流量,而在 Istio 中,它擁有了動態服務發現、負載均衡、Http2/gRpc 代理、熔斷器、健康檢查、故障注入等多種特性,固然這些都須要控制平面配合下發指令實現。
-
Mixer: Mixer 是 Istio 控制平面的組件之一,用於執行訪問控制和遙測(在最新版本已經沒有了)
-
Pilot: Pilot 就是實現流量管理的關鍵組件了,爲 Envoy 提供服務發現、智能路由、彈性功能(超時/重試/熔斷),咱們在後面也會詳細描述。
-
Citadel: Citadel 經過內置的身份和證書管理,能夠支持強大的服務到服務以及最終用戶的身份驗證和流量加密。
-
Galley: Galley 是 Istio 的配置驗證、提取、處理和分發組件。
Istio 中流量管理的基礎概念
流量管理是 Istio 中最基礎和最重要的功能了。咱們以前說到咱們的真實訴求每每是但願指定某個 pod 或者一組特定的 pod 接收流量,最基礎的方式是經過人肉運維搞定,但更優雅地是將其委託給 Istio 自己,Istio 會經過 Pilot 與 Envoy 代理搞定這一切。
怎麼搞定這一切呢,既然 kubernetes 中 service 的抽象概念知足不了咱們的需求,很天然地咱們嘗試去抽象一些更上層的概念來解決問題。Istio 也是如此,咱們來說一下其中主要的一些基本概念(至於具體的配置,因爲篇幅限制跳過):
-
VirtualService: 顧名思義,其實能夠理解爲對 service 的一層抽象,用於定義路由規則,控制流量路由到匹配的 service 子集(VirtualService)。同時你能夠爲每一個 VirtualService 設置一些獨立的網絡彈性屬性,例如超時、重試等。
-
DestinationRule: 通常是 VirtualService 路由生效後定義目的服務的策略,包括斷路器、負載均衡等。固然它也能夠定義可路由子集,即 VirtualService 中的路由規則能夠徹底委託給 DestinationRule。
-
ServiceEntry: 這是用於將 Istio 服務網格外部的服務添加到內部服務註冊的,也就是說你能訪問外部服務了。
-
Gateway: 用於控制南北流量的網關了,將 VirtualService 綁定到 Gateway 上,就能夠控制進入的 HTTP/TCP 流量了。
-
EnvoyFilter: 主要爲 Envoy 配置過濾器,用於動態擴展 Envoy 的能力。
控制面 Pilot 的流量管理
在 Istio 的控制平面中,Pilot 是負責流量管理的組件,也是本文的主角。Pilot 總體架構以下(來自old_pilot_repo,不過總體出入不大):

咱們看到 pilot 主要包含 2 個組件,即 Discovery services 和 Agent。
-
Agent: 該進程對應的是 pilot-agent,負責生產 Envoy 配置文件和管理 Envoy 生命週期。它和 Proxy(即 Envoy)以及具體應用 Service A/B 在同一 Pod 中部署。
-
Discovery services: 該進程對應的是 pilot-discovery,負責 pilot 中最關鍵的邏輯,即服務發現與流量管理。Discovery services 通常是和應用分開使用單獨的 deployment 部署的。它會和 2 個類型的數據打交道。一是圖中 k8s API Server 中的服務信息,即 service、endpoint、pod、node 等資源。其二就是 K8s API Server 中的一些 CRD 資源,包括了上述的 VritualService、DestinationRule、Gateway、ServiceEntry 等 Istio 控制面的流量規則配置信息。而後 Discovery services 會將這兩部分數據轉換爲數據面能夠理解的格式,並經過標準的 API 下發到各個數據面 (Envoy)sidecar 中。
Pilot Agent
pilot agent 它不是本文的主角,咱們簡單介紹一下。它主要的工做包括:
-
生成 envoy 的相關配置,這裏是指少部分的靜態配置,畢竟大多動態配置是經過標準 xDS 接口從 Pilot 獲取的。
-
負責 envoy 進程的監控與管理工做,好比 envoy 掛了負責重啓 envoy,或者配置變動後負責 reload envoy。
-
啓動 envoy 進程
Pilot-discovery
pilot-discovery 是 pilot 中的關鍵組件,咱們進行較爲詳細的描述。
總體模型
pilot-discovery 的總體模型以下所示:

pilot-discovery 有兩部分輸入信息:
-
來自 istio 控制平面的信息,也就是圖中的 Rules API,包括 VirtualService、DestinationRule 等,這些信息以 kubernetes CRD 資源的形式保存在 kubernetes api server 中。
-
來自於服務註冊中心的服務註冊信息,也就是圖中的 kubernetes、mesos、cloud foundry 等。固然咱們默認都認爲是 kubernetes,下文相關描述也默認 kubernetes。
爲了支持對不一樣服務註冊中心的支持,因此須要有一個統一的數據存儲模型,即 Abstract Model,和一個轉換器 Platform Adapter 來實現各服務註冊中心數據到 Abstract Model 的數據轉換。固然除了註冊中心數據外,Platform Adapter 還需將 VirtualService、DestinationRule 等 CRD 資源信息轉換成 Abstract Model。
基於統一數據存儲模型 Abstract Model,pilot-discovery 爲數據面提供了控制信息服務,也就是所謂的 xds api 服務,從而得以將控制信息下發到數據面 envoy。
接下來咱們講講 pilot-discovery 的一個總體流程。
初始化工做
pilot-discovery 首先乾的事兒是進行一些初始化,初始化的工做內容包括:
-
建立一個 kubernetes client。想要與 kubernetes api server 交互那天然須要 kubeClient,kubeClient 有 2 種建立方式。一種是使用特定的 kubeConfig 文件從而聯通 kubernetes api server。另外一種是使用 in cluster config 方式,也就是若是自己在 kubernetes 集羣中,能夠經過感知集羣上下文的方式自動完成配置。
-
多集羣配置。現實狀況下,咱們可能會有多個 kubernetes 集羣,一種方式是每一個 kubernetes 集羣搭建一套 Istio,但也多是多個集羣共用一個 Istio。那麼 Istio 就須要鏈接其餘遠程 kubernetes 集羣了,它被稱爲 remote cluster,Istio 在一個 map 中保存每一個 remote cluster 的遠程訪問信息。
-
配置和 Mixer 相關的東西,這裏不詳細描述。
-
初始化和配置存儲中心的鏈接。以前說過 Istio 中的諸多流量管理相關的配置,包括 VirtualService、DestinationRule 等,這些都是須要保存在存儲中心(不是指 Etcd)的。Istio 支持將這些配置經過文件存儲或者 kubernetes CRD 的方式進行存儲,固然基本上是後者。當 CRD 資源完成註冊以後,還會建立一個 config controller 來對 CRD 資源的 crud 事件進行處理。
-
配置和註冊中心的鏈接。這裏的註冊中心基本上指的是 kubernetes,如上所述,咱們須要對 kubernetes 中的 pod、service、endpoints 等信息進行監聽,固然咱們也須要一個 service controller 來進行事件處理。
-
初始化 pilot-discovery 服務。因爲 envoy sidecar 是經過鏈接 pilot-discovery 服務來獲取服務註冊發現信息以及流量控制策略的,因此這裏須要初始化 discovery 服務,包括提供 REST 協議的服務以及提供 gRPC 協議的服務。
-
一些健康檢查以及監控。
流量策略等 CRD 信息處理
咱們以前講 Istio 中流量策略等相關規則都是以 kubernetes CRD 的形式保存在 kubernetes api server 背後的 Etcd 中的,包括 VirtualService、DestinationRule。這些 CRD 資源當完成註冊後,還建立了 config controller 來處理 CRD 的事件。
config controller 主要內容包括對每一個 CRD 資源實現一個 list/watch,而後爲其 Add、Update、Delete 等事件建立一個統一的流程框架,即將 CRD 對象事件封裝成一個 Task 並 push 到一個 queue 裏。隨後啓動協程依次處理 CRD 資源事件,即從 queue 中取出 Task 對象,並調用其 ChainHandler。
服務註冊信息處理
服務註冊信息指的默認爲 kubernetes 服務註冊信息(固然也支持其餘註冊中心,但比較小衆),即 pod、service、endpoints、node 等資源。咱們以前講 Pilot 建立了一個 service controller 來實現對 kubernetes 資源的監控和處理。
service controller 的邏輯和 config controller 基本一致。爲每種 kubernetes 資源都實現了一個 list/watch,而後將其 Add、Update、Delete 事件封裝成 Task 對象 push 到 queue 中,隨後啓動協程從 queue 中取出並調用 CHainHandler。
暴露針對 Envoy 的控制信息服務
咱們知道,Envoy 是經過與 Pilot 暴露的信息服務交互從而獲得服務發現/路由策略等相關信息的。pilot-discovery 建立了 gRPC 協議的 discovery 服務,經過 xDS api 與 Envoy 交互,包括 eds、cds、rds、lds 等。具體細節咱們以後描述。
數據面 Envoy 與 xDS 服務
數據平面是 sidecar 方式部署的智能代理,在 Istio 體系中,數據面每每是由 Envoy 擔任。Envoy 能夠調整控制服務網格之間的網絡通訊,是控制面流量管理的實際執行者。
Envoy xDS 是爲 Istio 控制平面與數據平面通訊設計的一套 api 協議,也就是下發流量管理配置的關鍵。
Envoy 中的基本概念
首先在瞭解 xDS 以前,咱們須要瞭解 Envoy 中的一些基本概念:
-
Host: 可以進行網絡通訊的實體。在 Envoy 中主機是指邏輯網絡應用程序,一塊物理硬件上能夠運行多個主機,只要它們是獨立尋址的。
-
Downstream: 下游主機鏈接到 Envoy,發送請求並接受響應。
-
Upstream: 上游主機獲取來自 Envoy 的鏈接請求和響應。
-
Cluster: 表示 Envoy 鏈接到的一組上游主機集羣。Envoy 經過服務發現發現集羣中的成員,Envoy 能夠經過主動運行情況檢查來肯定集羣成員的健康情況。
-
Endpoint: 即上游主機標識,包括端點的地址和健康檢查配置。
-
Listener: 監聽器,Envoy 暴露一個或多個監聽器給下游主機(downstream)鏈接,當監聽器監聽到請求時候,對請求的處理會所有抽象爲 Filter,例如 ReadFilter、WriteFilter、HttpFilter 等。
-
Listener filter: 過濾器,在 Envoy 指一些可插拔和可組合的邏輯處理層,是 Envoy 的核心邏輯處理單元。
-
Http Router Table: 即 Http 路由規則,例如請求的什麼域名轉發到什麼集羣(cluster)。
Envoy 架構
Envoy 總體架構以下所示:

Envoy 的工做流程爲下游主機(Host A)發送請求至上游主機(Host B/C/D),Envoy 攔截請求(代理注入及流量劫持咱們不詳細描述),Listener 監聽到下游主機請求後將請求內容抽象爲 Filter Chains,並根據流量策略相關的配置信息路由至相應的上游主機集羣(Cluster),從而完成路由轉發、負載均衡、流量策略等能力。
上述的流量策略相關的配置信息主要以動態配置的方式由 xDS api 實現,也是咱們關注的重點。此外,Envoy 做爲流量代理還能夠將部分配置以靜態配置的方式寫入文件中,啓動時候直接加載。
xDS 服務
所謂 xDS,這裏的 x 是一個代詞,在 Istio 中,主要包括 cds(cluster discovery service)、eds(endpoint discovery service)、rds(route discovery service)、lds(listener discovery service),ads(aggregated discovery service)則是對這些 api 的一個封裝。
在以上 api 引入的概念中,endpoint 表示一個具體的應用實例,對應 ip 和端口,相似 kubernetes 中的一個 pod。cluster 是一個應用集羣,對應一個或多個 endpoint,相似 kubernetes 中 service 的概念(實際上應該更小一些)。route 即當咱們作相似灰髮、金絲雀發佈時,同一個服務會運行多個版本,每一個版本對應一個 cluster,這時就須要經過 route 規則規定請求如何路由到某個版本的 cluster 上。
在實際請求過程當中,xDS 接口採用的順序以下:
-
CDS 首先更新 Cluster 數據
-
EDS 更新相應 Cluster 的 Endpoint 信息
-
LDS 更新 CDS/EDS 相應的 Listener
-
RDS 最後更新新增 Listener 相關的 Route 配置
-
刪除再也不使用的 CDS/EDS 配置
不過目前這個流程都已整合在 ADS 中,即聚合的服務發現,ADS 經過一個 gRPC 流以保證各個 xDS 接口的調用順序。
咱們以前講過 pilot-discovery 的工做包括會建立一個 discovery 服務。如今它會與每個 Envoy 創建一個雙向 streaming 的 gRPC 鏈接,Envoy proxy 則會經過 ADS 接口按照上述的調用邏輯發起請求,並將 Pilot 的流量管理關鍵概念 VirtualService、DestinationRule 等組裝成 cluster、endpoint、router、listener 等 envoy 配置。最終這些動態配置會做用在每個 Envoy Proxy 上,當 Envoy listener 監聽到下游主機請求時,就能夠根據這些配置完成實際的動態服務發現、流量管理等功能。
若是你想學好JAVA這門技術,也想在IT行業拿高薪,能夠進來看看 ,羣裏有:Java工程化、高性能及分佈式、高性能、深刻淺出。高架構。性能調優、Spring,MyBatis,Netty源碼分析和大數據等多個知識點。
若是你想拿高薪的,想學習的,想就業前景好的,想跟別人競爭能取得優點的,想進阿里面試但擔憂面試不過的,你均可以來,加V:psk12221 (小白和廣告勿擾)

看完三件事❤️
若是你以爲這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
-
點贊,轉發,有大家的 『點贊和評論』,纔是我創造的動力。
-
關注公衆號 『 java爛豬皮 』,不按期分享原創知識。
-
同時能夠期待後續文章ing🚀

做者:fredalxin
地址:https://fredal.xin/istio-traffic-management