深度解析Istio系列之流量控制篇

得益於良好的模塊化設計,Istio的各個組件設計清晰,分工明確,幾個大的組件之間甚至可以獨立工作,所以接下來我們將逐一深入分析Istio的各個組件。本文首先詳細分析一下我們最常用的流量管理功能所對應的模塊——Pilot和Envoy。

Istio基本架構

Istio基本架構圖如下圖所示,網格東西向及南北向的流量控制,核心思路是由Pilot維護管理策略,並通過標準接口下發到Envoy Proxy中,由Envoy最終實現流量的轉發。
深度解析Istio系列之流量控制篇

Istio服務網格邏輯上分爲數據平面和控制平面:

  • 數據平面:由一組以Sidecar方式部署的智能代理(Envoy)組成,這些代理可以調節和控制微服務之間所有的網絡通信。
  • 控制平面:服務管理和配置代理來路由流量。

其中與流量管理相關的主要包括控制層面的Pilot以及數據層面的Envoy Proxy。

控制平面組件——Pilot

Pilot的基本架構如下圖所示。
深度解析Istio系列之流量控制篇

Pilot功能

根據上圖,Pilot主要實現下述功能:

1.統一服務模型

統一服務模型主要功能是從底層平臺獲取服務相關信息以及通過RuleAPI定義的服務間流量規則,以kubernetes爲例,統一服務模型從平臺上獲取註冊在Pod、Service、Node以及流量規則信息,獲取到各種信息後轉變成數據平面上可理解的數據格式存儲在Abstract Model中。

2. 標準數據平面API

獲取到各種服務信息以及流量規則之後,會通過該API下發到數據面的Sidecar中。

3. 業務DSL語言(Domain Specific Language)

SL語言提供了面向業務的高層抽象,可以被運維人員理解和使用。運維人員使用該DSL定義流量規則並下發到Pilot,這些規則被Pilot翻譯成數據面的配置,再通過標準API分發到Envoy實例,可以在運行期對微服務的流量進行控制和調整。

Pilot的規則DSL是採用K8S API Server中的Custom Resource (CRD)實現的,因此和其他資源類型如Service Pod Deployment的創建和使用方法類似,都可以用Kubectl進行創建。

通過運用不同的流量規則,可以對網格中微服務進行精細化的流量控制,如按版本分流,斷路器,故障注入,灰度發佈等。

Pilot實現

與Pilot相關的服務主要有兩個:

(1)Discovery Service

對應的docker爲gcr.io/istio-release/pilot,進程爲pilot-discovery,該組件的功能包括:

從Service Provider中獲取服務信息,除了這里主要介紹的Kubernetes之外,Istio還支持Consul作爲Service Provider。

從Kubernetes API Server中獲取流量規則(Kubernetes CRD Resource)。

將服務信息和流量規則轉化爲數據面可以理解的格式,通過標準的數據面API下發到網格中的各個Sidecar中。

(2)Kubernetes API Server

提供Pilot相關的CRD Resource的增、刪、改、查。和Pilot相關的CRD有以下幾種:

Virtualservice:用於定義路由規則,如根據來源或 Header 制定規則,或在不同服務版本之間分拆流量。

DestinationRule:定義目的服務的配置策略以及可路由子集。策略包括斷路器、負載均衡以及 TLS 等。

ServiceEntry:用 ServiceEntry 可以向Istio中加入附加的服務條目,以使網格內可以向Istio 服務網格之外的服務發出請求。

Gateway:爲網格配置網關,以允許一個服務可以被網格外部訪問。

EnvoyFilter:可以爲Envoy配置過濾器。由於Envoy已經支持Lua過濾器,因此可以通過EnvoyFilter啓用Lua過濾器,動態改變Envoy的過濾鏈行爲。我之前一直在考慮如何才能動態擴展Envoy的能力,EnvoyFilter提供了很靈活的擴展性。

數據平面組件——Envoy

Envoy實現

Istio通過K8s的Admission Webhook機制實現了sidecar的自動注入,Istio集羣中的每個微服務會被加入Envoy相關的容器。下面是官方示例productpage微服務的Pod內容,可見除productpage之外,Istio還在該Pod中注入了兩個容器gcr.io/istio-release/proxy_init和gcr.io/istio-release/proxyv2。

1.初始化容器器proxy_init

Productpage的Pod中有一個InitContainer proxy_init,InitContrainer是K8S提供的機制,用於在Pod中執行一些初始化任務,在Initialcontainer執行完畢並退出後,纔會啓動Pod中的其它container。

在proxy_init中執行iptables.sh腳本,該腳本的作用是通過配置iptable來劫持Pod中的流量。

2.運行時Sidecar容器器proxyv2

Envoy的大部分配置都是dynamic resource,包括網格中服務相關的service cluster, listener, route規則等。這些dynamic resource是通過xDS接口從Istio控制面中動態獲取的。但Envoy如何知道xDS server的地址呢?這是在Envoy初始化配置文件中以static resource的方式配置的。

在Proxyv2容器運行時,有兩個進程pilot-agent和envoy。

1)pilot-agent進程

該進程根據K8S API Server中的配置信息生成Envoy的配置文件,並負責啓動Envoy進程。注意Envoy的大部分配置信息都是通過xDS接口從Pilot中動態獲取的,因此Agent生成的只是用於初始化Envoy的少量靜態配置。

2)envoy進程

Envoy由Pilot-agent進程啓動,啓動後,Envoy讀取Pilot-agent爲它生成的配置文件,然後根據該文件的配置獲取到Pilot的地址,通過數據面標準API的xDS接口從pilot拉取動態配置信息,包括路路由(route),監聽器器(listener),服務集羣(cluster)和服務端點(endpoint)。Envoy初始化完成後,就根據這些配置信息對微服務間的通信進行尋址和路由。

Envoy相關概念

數據面組件中涉及的概念比較多,這裏列舉如下。

  • Host:能夠進行網絡通信的實體(在手機或服務器等上的應用程序)。在 Envoy 中主機是指邏輯網絡應用程序。只要每臺主機都可以獨立尋址,一塊物理硬件上就運行多個主機。
  • Downstream:下游(downstream)主機連接到 Envoy,發送請求並或獲得響應。
  • Upstream:上游(upstream)主機獲取來自 Envoy 的鏈接請求和響應。
  • Cluster:集羣(cluster)是 Envoy 連接到的一組邏輯上相似的上游主機。Envoy 通過服務發現發現集羣中的成員。Envoy 可以通過主動運行狀況檢查來確定集羣成員的健康狀況。Envoy 如何將請求路由到集羣成員由負載均衡策略確定。
  • Mesh:一組互相協調以提供一致網絡拓撲的主機。Envoy mesh 是指一組 Envoy 代理,它們構成了由多種不同服務和應用程序平臺組成的分佈式系統的消息傳遞基礎。
  • 運行時配置:與 Envoy 一起部署的帶外實時配置系統。可以在無需重啓 Envoy 或更改 Envoy 主配置的情況下,通過更改設置來影響操作。
  • Listener: 偵聽器(listener)是可以由下游客戶端連接的命名網絡位置(例如,端口、unix域套接字等)。Envoy 公開一個或多個下游主機連接的偵聽器。一般是每臺主機運行一個 Envoy,使用單進程運行,但是每個進程中可以啓動任意數量的 Listener(監聽器),目前只監聽 TCP,每個監聽器都獨立配置一定數量的(L3/L4)網絡過濾器。Listenter 也可以通過 Listener Discovery Service(LDS)動態獲取。
  • Listener filter:Listener 使用 listener filter(監聽器過濾器)來操作鏈接的元數據。它的作用是在不更改 Envoy 的核心功能的情況下添加更多的集成功能。Listener filter 的 API 相對簡單,因爲這些過濾器最終是在新接受的套接字上運行。在鏈中可以互相銜接以支持更複雜的場景,例如調用速率限制。
  • Envoy 已經包含了多個監聽器過濾器。
  • Http Route Table:HTTP 的路由規則,例如請求的域名,Path 符合什麼規則,轉發給哪個 Cluster。
  • Health checking:健康檢查會與SDS服務發現配合使用。但是,即使用其他服務發現方式,也有相應需要進行主動健康檢查的情況。
  • xDS:xDS 是一個關鍵概念,它是一類發現服務的統稱,通過對 xDS 的請求來動態更新 Envoy 配置,其包括如下幾類:
    CDS:Cluster Discovery Service
    EDS:Endpoint Discovery Service
    SDS:Service Discovery Service
    RDS:Route Discovery Service
    LDS:Listener Discovery Service

Envoy配置

Envoy的配置包含兩部分,初始化配置和動態更新的配置。

1.Envoy初始配置
Pilot-agent進程根據啓動參數和K8S API Server中的配置信息生成Envoy的初始配置文件,並負責啓動Envoy進程。從ps命令輸出可以看到Pilot-agent在啓動Envoy進程時傳入了pilot地址和zipkin地址,併爲Envoy生成了一個初始化配置文件envoy-rev0.json。

2.Envoy動態更新配置
通過管理接口獲取完整配置。從Envoy初始化配置文件中,我們可以大致看到Istio通過Envoy來實現服務發現和流量管理的基本原理。即控制面將xDS server信息通過static resource的方式配置到Envoy的初始化配置文件中,Envoy啓動後通過xDS server獲取到dynamic resource,包括網格中的service信息及路由規則。
深度解析Istio系列之流量控制篇

詳細流程如下:

  1. Pilot-agent根據啓動參數和K8S API Server中的配置信息生成Envoy的初始配置文件envoy-rev0.json,該文件告訴Envoy從xDS server中獲取動態配置信息,並配置了了xDS server的地址信息,即控制面的Pilot。
  2. Pilot-agent使用envoy-rev0.json啓動Envoy進程。
  3. Envoy根據初始配置獲得Pilot地址,採用xDS接口從Pilot獲取到Listener,Cluster,Route等d動態配置信息。
  4. Envoy根據獲取到的動態配置啓動Listener,並根據Listener的配置,結合Route和Cluster對攔截到的流量進行處理。

服務間交互流程

下圖表述了服務與服務之間通過sidecar進行交互的流程。
深度解析Istio系列之流量控制篇

基本流程分析如下:

  1. Productpage發起對Details的調用:http://details:9080/details/0
  2. 請求被Pod的iptable規則攔截,轉發到15001端口。
  3. Envoy的Virtual Listener在15001端口上監聽,收到了該請求。
  4. 請求被Virtual Listener根據原目標IP(通配)和端口(9080)轉發到0.0.0.0_900這個listener。
    深度解析Istio系列之流量控制篇
  5. 根據0.0.0.0_9080 listener的http_connection_manager filter配置,該請求採用"9080" route進行分發。
    深度解析Istio系列之流量控制篇
  6. "9080"這個route的配置中,host name爲details:9080的請求對應的cluster爲outbound|9080||details.default.svc.cluster.local。
    深度解析Istio系列之流量控制篇
  7. outbound|9080||details.default.svc.cluster.local cluster爲動態資源,通過eds查詢得到其endpoint爲192.168.206.21:9080。
    深度解析Istio系列之流量控制篇
  8. 請求被轉發到192.168.206.21,即Details服務所在的Pod,被iptable規則攔截,轉發到15001端口。
  9. Envoy的Virtual Listener在15001端口上監聽,收到了該請求。
  10. 請求被Virtual Listener根據請求原目標地址IP(192.168.206.21)和端口(9080)轉發到192.168.206.21_9080這個listener。
  11. 根據92.168.206.21_9080 listener的http_connection_manager filter配置,該請求對應的cluster爲 inbound|9080||details.default.svc.cluster.local 。
    深度解析Istio系列之流量控制篇
  12. inbound|9080||details.default.svc.cluster.local cluster配置的host爲127.0.0.1:9080。
  13. 請求被轉發到127.0.0.1:9080,即Details服務進行處理。

參考鏈接

https://zhaohuabing.com/post/2018-09-25-istio-traffic-management-impl-intro/

https://istio.io/zh/docs/concepts/what-is-istio/

https://www.cnblogs.com/xishuai/p/microservices-and-service-mesh.html

深度解析Istio系列之流量控制篇

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章