Service Mesh——後 Kubernetes 時代的微服務

本文是之前所寫內容的從新修訂並收錄於 ServiceMesher 社區的 Istio Handbook 中,其餘章節仍在編纂中。html

剛據說 Service Mesh 並試用過 Istio 的人可能都會有下面幾個疑問:node

  1. 爲何 Istio 要綁定 Kubernetes 呢?
  2. Kubernetes 和 Service Mesh 分別在雲原生中扮演什麼角色?
  3. Istio 擴展了 Kubernetes 的哪些方面?解決了哪些問題?
  4. Kubernetes、xDS 協議(EnvoyMOSN 等)與 Istio 之間又是什麼關係?
  5. 到底該不應上 Service Mesh?

這一節咱們將試圖帶您梳理清楚 Kubernetes、xDS 協議以及 Istio Service Mesh 之間的內在聯繫。此外,本節還將介紹 Kubernetes 中的負載均衡方式,xDS 協議對於 Service Mesh 的意義以及爲何說及時有了 Kubernetes 還須要 Istio。nginx

使用 Service Mesh 並非說與 Kubernetes 決裂,而是水到渠成的事情。Kubernetes 的本質是經過聲明式配置對應用進行生命週期管理,而 Service Mesh 的本質是提供應用間的流量和安全性管理以及可觀察性。假如你已經使用 Kubernetes 構建了穩定的微服務平臺,那麼如何設置服務間調用的負載均衡和流量控制?git

Envoy 創造的 xDS 協議被衆多開源軟件所支持,如 IstioLinkerdMOSN 等。Envoy 對於 Service Mesh 或雲原生來講最大的貢獻就是定義了 xDS,Envoy 本質上是一個 proxy,是可經過 API 配置的現代版 proxy,基於它衍生出來不少不一樣的使用場景,如 API Gateway、Service Mesh 中的 Sidecar proxy 和邊緣代理。github

本節包含如下內容api

  • 說明 kube-proxy 的做用。
  • Kubernetes 在微服務管理上的侷限性。
  • 介紹 Istio Service Mesh 的功能。
  • 介紹 xDS 包含哪些內容。
  • 比較 Kubernetes、Envoy 和 Istio Service Mesh 中的一些概念。

重要觀點

若是你想要提早了解下文的全部內容,那麼能夠先閱讀下面列出的本文中的一些主要觀點:安全

  • Kubernetes 的本質是應用的生命週期管理,具體來講就是部署和管理(擴縮容、自動恢復、發佈)。
  • Kubernetes 爲微服務提供了可擴展、高彈性的部署和管理平臺。
  • Service Mesh 的基礎是透明代理,經過 sidecar proxy 攔截到微服務間流量後再經過控制平面配置管理微服務的行爲。
  • Service Mesh 將流量管理從 Kubernetes 中解耦,Service Mesh 內部的流量無需 kube-proxy 組件的支持,經過爲更接近微服務應用層的抽象,管理服務間的流量、安全性和可觀察性。
  • xDS 定義了 Service Mesh 配置的協議標準。
  • Service Mesh 是對 Kubernetes 中的 service 更上層的抽象,它的下一步是 serverless。

Kubernetes vs Service Mesh

下圖展現的是 Kubernetes 與 Service Mesh 中的的服務訪問關係(每一個 pod 一個 sidecar 的模式)。服務器

kubernetes 對比 service mesh

流量轉發markdown

Kubernetes 集羣的每一個節點都部署了一個 kube-proxy 組件,該組件會與 Kubernetes API Server 通訊,獲取集羣中的 service 信息,而後設置 iptables 規則,直接將對某個 service 的請求發送到對應的 Endpoint(屬於同一組 service 的 pod)上。網絡

服務發現

Service Mesh 中的服務註冊

Istio Service Mesh 能夠沿用了 Kubernetes 中的 service 作服務註冊,還能夠經過控制平面的平臺適配器對接其餘服務發現系統,而後生成數據平面的配置(使用 CRD 聲明,保存在 etcd 中),數據平面的透明代理(transparent proxy)以 sidecar 容器的形式部署在每一個應用服務的 pod 中,這些 proxy 都須要請求控制平面來同步代理配置。之因此說是透明代理,是由於應用程序容器徹底無感知代理的存在,該過程 kube-proxy 組件同樣須要攔截流量,只不過 kube-proxy 攔截的是進出 Kubernetes 節點的流量,而 sidecar proxy 攔截的是進出該 Pod 的流量,詳見理解 Istio Service Mesh 中 Envoy Sidecar 代理的路由轉發

Service Mesh 的劣勢

由於 Kubernetes 每一個節點上都會運行衆多的 Pod,將原先 kube-proxy 方式的路由轉發功能置於每一個 pod 中,將致使大量的配置分發、同步和最終一致性問題。爲了細粒度地進行流量管理,必將添加一系列新的抽象,從而會進一步增長用戶的學習成本,但隨着技術的普及,這樣的狀況會慢慢地獲得緩解。

Service Mesh 的優點

kube-proxy 的設置都是全局生效的,沒法對每一個服務作細粒度的控制,而 Service Mesh 經過 sidecar proxy 的方式將 Kubernetes 中對流量的控制從 service 一層抽離出來,能夠作更多的擴展。

kube-proxy 組件

在 Kubernetes 集羣中,每一個 Node 運行一個 kube-proxy 進程。kube-proxy 負責爲 Service 實現了一種 VIP(虛擬 IP)的形式。 在 Kubernetes v1.0 版本,代理徹底在 userspace 實現。Kubernetes v1.1 版本新增了 iptables 代理模式,但並非默認的運行模式。從 Kubernetes v1.2 起,默認使用 iptables 代理。在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理模式。關於 kube-proxy 組件的更多介紹請參考 kubernetes 簡介:service 和 kube-proxy 原理使用 IPVS 實現 Kubernetes 入口流量負載均衡

kube-proxy 的缺陷

kube-proxy 的不足之處

首先,若是轉發的 pod 不能正常提供服務,它不會自動嘗試另外一個 pod,固然這個能夠經過 liveness probes 來解決。每一個 pod 都有一個健康檢查的機制,當有 pod 健康情況有問題時,kube-proxy 會刪除對應的轉發規則。另外,nodePort 類型的服務也沒法添加 TLS 或者更復雜的報文路由機制。

Kube-proxy 實現了流量在 Kubernetes service 多個 pod 實例間的負載均衡,可是如何對這些 service 間的流量作細粒度的控制,好比按照百分比劃分流量到不一樣的應用版本(這些應用都屬於同一個 service,但位於不一樣的 deployment 上),作金絲雀發佈(灰度發佈)和藍綠髮布?Kubernetes 社區給出了 使用 Deployment 作金絲雀發佈的方法,該方法本質上就是經過修改 pod 的 label 來將不一樣的 pod 劃歸到 Deployment 的 Service 上。

Kubernetes Ingress vs Istio Gateway

上文說到 kube-proxy 只能路由 Kubernetes 集羣內部的流量,而咱們知道 Kubernetes 集羣的 Pod 位於 CNI 建立的外網絡中,集羣外部是沒法直接與其通訊的,所以 Kubernetes 中建立了 ingress 這個資源對象,它由位於 Kubernetes 邊緣節點(這樣的節點能夠是不少個也能夠是一組)的 Ingress controller 驅動,負責管理南北向流量,Ingress 必須對接各類 Ingress Controller 才能使用,好比 nginx ingress controllertraefik。Ingress 只適用於 HTTP 流量,使用方式也很簡單,只能對 service、port、HTTP 路徑等有限字段匹配來路由流量,這致使它沒法路由如 MySQL、Redis 和各類私有 RPC 等 TCP 流量。要想直接路由南北向的流量,只能使用 Service 的 LoadBalancer 或 NodePort,前者須要雲廠商支持,後者須要進行額外的端口管理。有些 Ingress controller 支持暴露 TCP 和 UDP 服務,可是隻能使用 Service 來暴露,Ingress 自己是不支持的,例如 nginx ingress controller,服務暴露的端口是經過建立 ConfigMap 的方式來配置的。

Istio Gateway 的功能與 Kubernetes Ingress 相似,都是負責集羣的南北向流量。Istio Gateway 描述的負載均衡器用於承載進出網格邊緣的鏈接。該規範中描述了一系列開放端口和這些端口所使用的協議、負載均衡的 SNI 配置等內容。Gateway 是一種 CRD 擴展,它同時複用了 sidecar proxy 的能力,詳細配置請參考 Istio 官網

xDS 協議

下面這張圖你們在瞭解 Service Mesh 的時候可能都看到過,每一個方塊表明一個服務的實例,例如 Kubernetes 中的一個 Pod(其中包含了 sidecar proxy),xDS 協議控制了 Istio Service Mesh 中全部流量的具體行爲,即將下圖中的方塊連接到了一塊兒。

Service Mesh 示意圖

xDS 協議是由 Envoy 提出的,在 Envoy v2 版本 API 中最原始的 xDS 協議指的是 CDS(Cluster Discovery Service)、EDS(Endpoint Discovery service)、LDS(Listener Discovery Service) 和 RDS(Route Discovery Service),後來在 v3 版本中又發展出了 Scoped Route Discovery Service(SRDS)、Virtual Host Discovery Service (VHDS)、Secret Discovery Service(SDS)、Runtime Discovery Service(RTDS)詳見 xDS REST and gRPC protocol

下面咱們以各有兩個實例的 service,來看下 xDS 協議。

xDS 協議

上圖中的箭頭不是流量進入 Proxy 後的路徑或路由,也不是實際順序,而是想象的一種 xDS 接口處理順序,其實 xDS 之間也是有交叉引用的。

支持 xDS 協議的代理經過查詢文件或管理服務器來動態發現資源。歸納地講,對應的發現服務及其相應的 API 被稱做

xDS

。Envoy 經過**訂閱(subscription)**方式來獲取資源,訂閱方式有如下三種:

  • 文件訂閱:監控指定路徑下的文件,發現動態資源的最簡單方式就是將其保存於文件,並將路徑配置在 ConfigSource 中的 path 參數中。
  • gRPC 流式訂閱:每一個 xDS API 能夠單獨配置 ApiConfigSource,指向對應的上游管理服務器的集羣地址。
  • 輪詢 REST-JSON 輪詢訂閱:單個 xDS API 可對 REST 端點進行的同步(長)輪詢。

以上的 xDS 訂閱方式詳情請參考 xDS 協議解析。Istio 使用 gRPC 流式訂閱的方式配置全部的數據平面的 sidecar proxy。

文章中介紹了 Istio pilot 的整體架構、proxy 配置的生成、pilot-discovery 模塊的功能,以及 xDS 協議中的 CDS、EDS 及 ADS,關於 ADS 詳情請參考 Envoy 官方文檔

xDS 協議要點

最後總結下關於 xDS 協議的要點:

  • CDS、EDS、LDS、RDS 是最基礎的 xDS 協議,它們能夠分別獨立更新。
  • 全部的發現服務(Discovery Service)能夠鏈接不一樣的 Management Server,也就是說管理 xDS 的服務器能夠是多個。
  • Envoy 在原始 xDS 協議的基礎上進行了一些列擴充,增長了 SDS(祕鑰發現服務)、ADS(聚合發現服務)、HDS(健康發現服務)、MS(Metric 服務)、RLS(速率限制服務)等 API。
  • 爲了保證數據一致性,若直接使用 xDS 原始 API 的話,須要保證這樣的順序更新:CDS –> EDS –> LDS –> RDS,這是遵循電子工程中的先合後斷(Make-Before-Break)原則,即在斷開原來的鏈接以前先創建好新的鏈接,應用在路由裏就是爲了防止設置了新的路由規則的時候卻沒法發現上游集羣而致使流量被丟棄的狀況,相似於電路里的斷路。
  • CDS 設置 Service Mesh 中有哪些服務。
  • EDS 設置哪些實例(Endpoint)屬於這些服務(Cluster)。
  • LDS 設置實例上監聽的端口以配置路由。
  • RDS 最終服務間的路由關係,應該保證最後更新 RDS。

Envoy

Envoy 是 Istio Service Mesh 中默認的 Sidecar,Istio 在 Enovy 的基礎上按照 Envoy 的 xDS 協議擴展了其控制平面,在講到 Envoy xDS 協議以前咱們還須要先熟悉下 Envoy 的基本術語。下面列舉了 Envoy 裏的基本術語及其數據結構解析,關於 Envoy 的詳細介紹請參考 Envoy 官方文檔,至於 Envoy 在 Service Mesh(不只限於 Istio) 中是如何做爲轉發代理工做的請參考網易雲劉超的這篇深刻解讀 Service Mesh 背後的技術細節 以及理解 Istio Service Mesh 中 Envoy 代理 Sidecar 注入及流量劫持,本文引用其中的一些觀點,詳細內容再也不贅述。

Envoy proxy 架構圖

基本術語

下面是您應該瞭解的 Enovy 裏的基本術語:

  • Downstream(下游):下游主機鏈接到 Envoy,發送請求並接收響應,即發送請求的主機。
  • Upstream(上游):上游主機接收來自 Envoy 的鏈接和請求,並返回響應,即接受請求的主機。
  • Listener(監聽器):監聽器是命名網地址(例如,端口、unix domain socket 等),下游客戶端能夠鏈接這些監聽器。Envoy 暴露一個或者多個監聽器給下游主機鏈接。
  • Cluster(集羣):集羣是指 Envoy 鏈接的一組邏輯相同的上游主機。Envoy 經過服務發現來發現集羣的成員。能夠選擇經過主動健康檢查來肯定集羣成員的健康狀態。Envoy 經過負載均衡策略決定將請求路由到集羣的哪一個成員。

Envoy 中能夠設置多個 Listener,每一個 Listener 中又能夠設置 filter chain(過濾器鏈表),並且過濾器是可擴展的,這樣就能夠更方便咱們操做流量的行爲,例如設置加密、私有 RPC 等。

xDS 協議是由 Envoy 提出的,如今是 Istio 中默認的 sidecar proxy,但只要實現 xDS 協議理論上都是能夠做爲 Istio 中的 sidecar proxy 的,例如螞蟻金服開源的 MOSN

Istio Service Mesh

Istio service mesh 架構圖

Istio 是一個功能十分豐富的 Service Mesh,它包括以下功能:

  • 流量管理:這是 Istio 的最基本的功能。
  • 策略控制:經過 Mixer 組件和各類適配器來實現,實現訪問控制系統、遙測捕獲、配額管理和計費等。
  • 可觀測性:經過 Mixer 來實現。
  • 安全認證:Citadel 組件作密鑰和證書管理。

Istio 中的流量管理

Istio 中定義了以下的 CRD 來幫助用戶進行流量管理:

  • GatewayGateway 描述了在網絡邊緣運行的負載均衡器,用於接收傳入或傳出的HTTP / TCP鏈接。
  • VirtualServiceVirtualService 實際上將 Kubernetes 服務鏈接到 Istio Gateway。它還能夠執行更多操做,例如定義一組流量路由規則,以便在主機被尋址時應用。
  • DestinationRuleDestinationRule 所定義的策略,決定了通過路由處理以後的流量的訪問策略。簡單的說就是定義流量如何路由。這些策略中能夠定義負載均衡配置、鏈接池尺寸以及外部檢測(用於在負載均衡池中對不健康主機進行識別和驅逐)配置。
  • EnvoyFilterEnvoyFilter 對象描述了針對代理服務的過濾器,這些過濾器能夠定製由 Istio Pilot 生成的代理配置。這個配置初級用戶通常不多用到。
  • ServiceEntry:默認狀況下 Istio Service Mesh 中的服務是沒法發現 Mesh 外的服務的,ServiceEntry 可以在 Istio 內部的服務註冊表中加入額外的條目,從而讓網格中自動發現的服務可以訪問和路由到這些手工加入的服務。

Kubernetes vs xDS vs Istio

在閱讀完上文對 Kubernetes 的 kube-proxy 組件、xDS 和 Istio 中流量管理的抽象概念以後,下面將帶您僅就流量管理方面比較下三者對應的組件/協議(注意,三者不能夠徹底等同)。

Kubernetes xDS Istio Service Mesh
Endpoint Endpoint -
Service Route VirtualService
kube-proxy Route DestinationRule
kube-proxy Listener EnvoyFilter
Ingress Listener Gateway
Service Cluster ServiceEntry

總結

若是說 Kubernetes 管理的對象是 Pod,那麼 Service Mesh 中管理的對象就是一個個 Service,因此說使用 Kubernetes 管理微服務後再應用 Service Mesh 就是水到渠成了,若是連 Service 你也不想管了,那就用如 knative 這樣的 serverless 平臺,但這就是後話了。

Envoy/MOSN 的功能也不僅是作流量轉發,以上概念只不過是 Istio 在 Kubernetes 之上新增一層抽象層中的冰山一角,但由於流量管理是服務網格最基礎也是最重要的功能,因此這將成爲本書的開始。

參考

相關文章
相關標籤/搜索