必讀!Istio Service Mesh中的流量管理概念解析

本文來自 Istio 官方中文文檔,由 ServiceMesher 社區負責維護。
git

本頁概述了 Istio 中流量管理的工做原理,包括流量管理原則的優勢。本文假設你已經閱讀了 Istio 是什麼?並熟悉 Istio 的頂層設計架構。有關單個流量管理功能的更多信息,您能夠在本節其餘指南中瞭解。github

Pilot 和 Envoy

Istio 流量管理的核心組件是 Pilot,它管理和配置部署在特定 Istio 服務網格中的全部 Envoy 代理實例。它容許您指定在 Envoy 代理之間使用什麼樣的路由流量規則,並配置故障恢復功能,如超時、重試和熔斷器。它還維護了網格中全部服務的規範模型,並使用這個模型經過發現服務讓 Envoy 瞭解網格中的其餘實例。算法

每一個 Envoy 實例都會維護負載均衡信息,這些信息來自 Pilot 以及對負載均衡池中其餘實例的按期健康檢查。從而容許其在目標實例之間智能分配流量,同時遵循其指定的路由規則。後端

流量管理的好處

使用 Istio 的流量管理模型,本質上是將流量與基礎設施擴容解耦,讓運維人員能夠經過 Pilot 指定流量遵循什麼規則,而不是指定哪些 pod/VM 應該接收流量——Pilot 和智能 Envoy 代理會幫咱們搞定。所以,例如,您能夠經過 Pilot 指定特定服務的 5% 流量能夠轉到金絲雀版本,而沒必要考慮金絲雀部署的大小,或根據請求的內容將流量發送到特定版本。api

Istio 中的流量管理
Istio 中的流量管理

將流量從基礎設施擴展中解耦,這樣就可讓 Istio 提供各類流量管理功能,這些功能在應用程序代碼以外。除了 A/B 測試的動態請求路由,逐步推出和金絲雀發佈以外,它還使用超時、重試和熔斷器處理故障恢復,最後還能夠經過故障注入來測試服務之間故障恢復策略的兼容性。這些功能都是經過在服務網格中部署的 Envoy sidecar/代理來實現的。服務器

Pilot 負責部署在 Istio 服務網格中的 Envoy 實例的生命週期管理。微信

Pilot 架構
Pilot 架構

如上圖所示,Pilot 維護了網格中的服務的規範表示,這個表示是獨立於底層平臺的。Pilot 中的平臺特定適配器負責適當填充此規範模型。例如,Pilot 中的 Kubernetes 適配器實現必要的控制器來監視 Kubernetes API server 中 pod 註冊信息、ingress 資源以及用於存儲流量管理規則的第三方資源的更改。該數據被翻譯成規範表示。Envoy 特定配置是基於規範表示生成的。網絡

Pilot 公開了用於服務發現負載均衡池路由表的動態更新的 API。這些 API 將 Envoy 從平臺特有的細微差異中解脫出來,簡化了設計並提高了跨平臺的可移植性。架構

運維人員能夠經過 Pilot 的 Rules API 指定高級流量管理規則。這些規則被翻譯成低級配置,並經過 discovery API 分發到 Envoy 實例。併發

請求路由

Pilot 所述,特定網格中服務的規範表示由 Pilot 維護。服務的 Istio 模型和在底層平臺(Kubernetes、Mesos 以及 Cloud Foundry 等)中的表達無關。特定平臺的適配器負責從各自平臺中獲取元數據的各類字段,而後對服務模型進行填充。

Istio 引入了服務版本的概念,能夠經過版本(v1v2)或環境(stagingprod)對服務進行進一步的細分。這些版本不必定是不一樣的 API 版本:它們多是部署在不一樣環境(prod、staging 或者 dev 等)中的同一服務的不一樣迭代。使用這種方式的常見場景包括 A/B 測試或金絲雀部署。Istio 的流量路由規則能夠根據服務版原本對服務之間流量進行附加控制。

服務之間的通信

服務版本的處理。
服務版本

如上圖所示,服務的客戶端不知道服務不一樣版本間的差別。它們可使用服務的主機名或者 IP 地址繼續訪問服務。Envoy sidecar/代理攔截並轉發客戶端和服務器之間的全部請求和響應。

運維人員使用 Pilot 指定路由規則,Envoy 根據這些規則動態地肯定其服務版本的實際選擇。該模型使應用程序代碼可以將它從其依賴服務的演進中解耦出來,同時提供其餘好處(參見 Mixer)。路由規則讓 Envoy 可以根據諸如 header、與源/目的地相關聯的標籤和/或分配給每一個版本的權重等標準來進行版本選擇。

Istio 還爲同一服務版本的多個實例提供流量負載均衡。能夠在服務發現和負載均衡中找到更多信息。

Istio 不提供 DNS。應用程序能夠嘗試使用底層平臺(kube-dns、mesos-dns 等)中存在的 DNS 服務來解析 FQDN。

Ingress 和 Egress

Istio 假定進入和離開服務網絡的全部流量都會經過 Envoy 代理進行傳輸。經過將 Envoy 代理部署在服務以前,運維人員能夠針對面向用戶的服務進行 A/B 測試、部署金絲雀服務等。相似地,經過使用 Envoy 將流量路由到外部 Web 服務(例如,訪問 Maps API 或視頻服務 API)的方式,運維人員能夠爲這些服務添加超時控制、重試、斷路器等功能,同時還能從服務鏈接中獲取各類細節指標。

經過 Envoy 的 Ingress 和 Egress。
請求流

服務發現和負載均衡

服務註冊:Istio 假定存在服務註冊表,以跟蹤應用程序中服務的 pod/VM。它還假設服務的新實例自動註冊到服務註冊表,而且不健康的實例將被自動刪除。諸如 Kubernetes、Mesos 等平臺已經爲基於容器的應用程序提供了這樣的功能。爲基於虛擬機的應用程序提供的解決方案就更多了。

服務發現:Pilot 使用來自服務註冊的信息,並提供與平臺無關的服務發現接口。網格中的 Envoy 實例執行服務發現,並相應地動態更新其負載均衡池。

發現與負載均衡
發現與負載均衡

如上圖所示,網格中的服務使用其 DNS 名稱訪問彼此。服務的全部 HTTP 流量都會經過 Envoy 自動從新路由。Envoy 在負載均衡池中的實例之間分發流量。雖然 Envoy 支持多種複雜的負載均衡算法,但 Istio 目前僅容許三種負載均衡模式:輪循、隨機和帶權重的最少請求。

除了負載均衡外,Envoy 還會按期檢查池中每一個實例的運行情況。Envoy 遵循熔斷器風格模式,根據健康檢查 API 調用的失敗率將實例分類爲不健康和健康兩種。換句話說,當給定實例的健康檢查失敗次數超過預約閾值時,將會被從負載均衡池中彈出。相似地,當經過的健康檢查數超過預約閾值時,該實例將被添加回負載均衡池。您能夠在處理故障中瞭解更多有關 Envoy 的故障處理功能。

服務能夠經過使用 HTTP 503 響應健康檢查來主動減輕負擔。在這種狀況下,服務實例將當即從調用者的負載均衡池中刪除。

故障處理

Envoy 提供了一套開箱即用,可選的的故障恢復功能,對應用中的服務大有裨益。這些功能包括:

  1. 超時
  2. 具有超時預算,並可以在重試之間進行可變抖動(間隔)的有限重試功能
  3. 併發鏈接數和上游服務請求數限制
  4. 對負載均衡池中的每一個成員主動(按期)運行健康檢查
  5. 細粒度熔斷器(被動健康檢查)——適用於負載均衡池中的每一個實例

這些功能可使用 Istio 的流量管理規則在運行時進行動態配置。

對超載的上游服務來講,重試之間的抖動極大的下降了重試形成的影響,而超時預算確保調用方服務在可預測的時間範圍內得到響應(成功/失敗)。

主動和被動健康檢查(上述 4 和 5 )的組合最大限度地減小了在負載均衡池中訪問不健康實例的機會。當將其與平臺級健康檢查(例如由 Kubernetes 或 Mesos 支持的檢查)相結合時, 能夠確保應用程序將不健康的 Pod/容器/虛擬機快速地從服務網格中去除,從而最小化請求失敗和延遲產生影響。

總之,這些功能使得服務網格可以耐受故障節點,並防止本地故障致使的其餘節點的穩定性降低。

微調

Istio 的流量管理規則容許運維人員爲每一個服務/版本設置故障恢復的全局默認值。然而,服務的消費者也能夠經過特殊的 HTTP 頭提供的請求級別值覆蓋超時重試的默認值。在 Envoy 代理的實現中,對應的 Header 分別是 x-envoy-upstream-rq-timeout-msx-envoy-max-retries

FAQ

Q:

在 Istio 中運行的應用程序是否仍須要處理故障?

是的。Istio能夠提升網格中服務的可靠性和可用性。可是,應用程序仍然須要處理故障(錯誤)並採起適當的回退操做。例如,當負載均衡池中的全部實例都失敗時,Envoy 將返回 HTTP 503。應用程序有責任實現必要的邏輯,對這種來自上游服務的 HTTP 503 錯誤作出合適的響應。

Q:

已經使用容錯庫(例如 Hystrix )的應用程序,是否會由於 Envoy 的故障恢復功能受到破壞?

不會。Envoy對應用程序是徹底透明的。在進行服務調用時,由 Envoy 返回的故障響應與上游服務返回的故障響應不會被區分開來。

Q:

同時使用應用級庫和 Envoy 時,怎樣處理故障?

假如對同一個目的服務給出兩個故障恢復策略(例如,兩次超時設置——一個在 Envoy 中設置,另外一個在應用程序庫中設置),當故障發生時,兩個限制都將被觸發。例如,若是應用程序爲服務的 API 調用設置了 5 秒的超時時間,而運維人員配置了 10 秒的超時時間,那麼應用程序的超時將會首先啓動。一樣,若是 Envoy 的熔斷器在應用熔斷器以前觸發,對該服務的 API 調用將從 Envoy 收到 503 錯誤。

故障注入

雖然 Envoy sidecar/proxy 爲在 Istio 上運行的服務提供了大量的故障恢復機制,但測試整個應用程序端到端的故障恢復能力依然是必須的。錯誤配置的故障恢復策略(例如,跨服務調用的不兼容/限制性超時)可能致使應用程序中的關鍵服務持續不可用,從而破壞用戶體驗。

Istio 能在不殺死 Pod 的狀況下,將協議特定的故障注入到網絡中,在 TCP 層製造數據包的延遲或損壞。咱們的理由是,不管網絡級別的故障如何,應用層觀察到的故障都是同樣的,而且能夠在應用層注入更有意義的故障(例如,HTTP 錯誤代碼),以檢驗和改善應用的彈性。

運維人員能夠爲符合特定條件的請求配置故障,還能夠進一步限制遭受故障的請求的百分比。能夠注入兩種類型的故障:延遲和中斷。延遲是計時故障,模擬網絡延遲上升或上游服務超載的狀況。中斷是模擬上游服務的崩潰故障。中斷一般以 HTTP 錯誤代碼或 TCP 鏈接失敗的形式表現。

有關詳細信息,請參閱 Istio 的流量管理規則

規則配置

Istio 提供了一個簡單的配置模型,用來控制 API 調用以及應用部署內多個服務之間的四層通訊。運維人員可使用這個模型來配置服務級別的屬性,這些屬性能夠是斷路器、超時、重試,以及一些普通的持續發佈任務,例如金絲雀發佈、A/B 測試、使用百分比對流量進行控制,從而完成應用的逐步發佈等。

例如,將 reviews 服務 100% 的傳入流量發送到 v1 版本,這一需求能夠用下面的規則來實現:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - route:
 - destination:
 host: reviews
 subset: v1複製代碼

這個配置的用意是,發送到 reviews 服務(在 host 字段中標識)的流量應該被路由到 reviews 服務實例的 v1 子集中。路由中的 subset 制定了一個預約義的子集名稱,子集的定義來自於目標規則配置:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - name: v1
 labels:
 version: v1
 - name: v2
 labels:
 version: v2複製代碼

子集中會指定一或多個標籤,用這些標籤來區分不一樣版本的實例。假設在 Kubernetes 上的 Istio 服務網格之中有一個服務,version: v1 表明只有標籤中包含 「version:v1」 的 Pod 纔會收到流量。

規則可使用 istioctl 客戶端工具 進行配置,若是是 Kubernetes 部署,還可使用 kubectl 命令完成一樣任務,可是隻有 istioctl 會在這個過程當中對模型進行檢查,因此咱們推薦使用 istioctl。在配置請求路由任務中包含有配置示例。

Istio 中包含有四種流量管理配置資源,分別是 VirtualServiceDestinationRuleServiceEntry 以及 Gateway。下面會講一下這幾個資源的一些重點。在網絡參考中能夠得到更多這方面的信息。

Virtual Service

是在 Istio 服務網格內對服務的請求如何進行路由控制?VirtualService 中就包含了這方面的定義。例如一個 Virtual Service 能夠把請求路由到不一樣版本,甚至是能夠路由到一個徹底不一樣於請求要求的服務上去。路由能夠用不少條件進行判斷,例如請求的源和目的地、HTTP 路徑和 Header 以及各個服務版本的權重等。

規則的目標描述

路由規則對應着一或多個用 VirtualService 配置指定的請求目的主機。這些主機能夠是也能夠不是實際的目標負載,甚至能夠不是同一網格內可路由的服務。例如要給到 reviews 服務的請求定義路由規則,可使用內部的名稱 reviews,也能夠用域名 bookinfo.comVirtualService 能夠定義這樣的 host 字段:

hosts:
 - reviews
 - bookinfo.com複製代碼

host 字段用顯示或者隱式的方式定義了一或多個徹底限定名(FQDN)。上面的 reviews,會隱式的擴展成爲特定的 FQDN,例如在 Kubernetes 環境中,全名會從 VirtualService 所在的集羣和命名空間中繼承而來(好比說 reviews.default.svc.cluster.local)。

在服務之間分拆流量

每一個路由規則都須要對一或多個有權重的後端進行甄別並調用合適的後端。每一個後端都對應一個特定版本的目標服務,服務的版本是依靠標籤來區分的。若是一個服務版本包含多個註冊實例,那麼會根據爲該服務定義的負載均衡策略進行路由,缺省策略是 round-robin

例以下面的規則會把 25% 的 reviews 服務流量分配給 v2 標籤;其他的 75% 流量分配給 v1

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - route:
 - destination:
 host: reviews
 subset: v1
 weight: 75
 - destination:
 host: reviews
 subset: v2
 weight: 25複製代碼

超時和重試

缺省狀況下,HTTP 請求的超時設置爲 15 秒,可使用路由規則來覆蓋這個限制:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - route:
 - destination:
 host: ratings
 subset: v1
 timeout: 10s複製代碼

還能夠用路由規則來指定某些 http 請求的重試次數。下面的代碼能夠用來設置最大重試次數,或者在規定時間內一直重試,時間長度一樣能夠進行覆蓋:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - route:
 - destination:
 host: ratings
 subset: v1
 retries:
 attempts: 3
 perTryTimeout: 2s複製代碼

注意請求的重試和超時還能夠針對每一個請求分別設置

請求超時任務中展現了超時控制的相關示例。

錯誤注入

在根據路由規則向選中目標轉發 http 請求的時候,能夠向其中注入一或多個錯誤。錯誤能夠是延遲,也能夠是退出。

下面的例子在目標爲 ratings:v1 服務的流量中,對其中的 10% 注入 5 秒鐘的延遲。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - fault:
 delay:
 percent: 10
 fixedDelay: 5s
 route:
 - destination:
 host: ratings
 subset: v1複製代碼

接下來,在目標爲 ratings:v1 服務的流量中,對其中的 10% 注入 HTTP 400 錯誤。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - fault:
 abort:
 percent: 10
 httpStatus: 400
 route:
 - destination:
 host: ratings
 subset: v1複製代碼

有時會把延遲和退出同時使用。例以下面的規則對從 reviews:v2ratings:v1 的流量生效,會讓全部的請求延遲 5 秒鐘,接下來把其中的 10% 退出:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - match:
 - sourceLabels:
 app: reviews
 version: v2
 fault:
 delay:
 fixedDelay: 5s
 abort:
 percent: 10
 httpStatus: 400
 route:
 - destination:
 host: ratings
 subset: v1複製代碼

能夠參考錯誤注入任務,進行這方面的實際體驗。

條件規則

能夠選擇讓規則只對符合某些要求的請求生效:

1. 使用工做負載 label 限制特定客戶端工做負載。例如,規則能夠指示它僅適用於實現 reviews 服務的工做負載(pod)的調用:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - match:
 sourceLabels:
 app: reviews
    ...複製代碼

sourceLabels 的值取決於服務的實現。例如,在 Kubernetes 中,它可能與相應 Kubernetes 服務的 pod 選擇器中使用的 label 相同。

以上示例還能夠進一步細化爲僅適用於 reviews 服務版本 v2 的調用:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - match:
 - sourceLabels:
 app: reviews
 version: v2
    ...複製代碼

2. 根據 HTTP Header 選擇規則。下面的規則只會對包含了 end-user 標頭的來源請求,且值爲 jason 的請求生效:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - match:
 - headers:
 end-user:
 exact: jason
    ...複製代碼

若是規則中指定了多個標頭,則全部相應的標頭必須匹配才能應用規則。

3. 根據請求URI選擇規則。例如,若是 URI 路徑以 /api/v1 開頭,則如下規則僅適用於請求:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: productpage
spec:
 hosts:
 - productpage
 http:
 - match:
 - uri:
 prefix: /api/v1
    ...複製代碼

多重匹配條件

能夠同時設置多個匹配條件。在這種狀況下,根據嵌套,應用 AND 或 OR 語義。

若是多個條件嵌套在單個匹配子句中,則條件爲 AND。例如,如下規則僅適用於客戶端工做負載爲 reviews:v2 且請求中包含 jason 的自定義 end-user 標頭:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - match:
 - sourceLabels:
 app: reviews
 version: v2
 headers:
 end-user:
 exact: jason
    ...複製代碼

相反,若是條件出如今單獨的匹配子句中,則只應用其中一個條件(OR 語義):

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - match:
 - sourceLabels:
 app: reviews
 version: v2
 - headers:
 end-user:
 exact: jason
    ...複製代碼

若是客戶端工做負載是 reviews:v2,或者請求中包含 jason 的自定義 end-user 標頭,則適用此規則。

優先級

當對同一目標有多個規則時,會按照在 VirtualService 中的順序進行應用,換句話說,列表中的第一條規則具備最高優先級。

爲何優先級很重要:當對某個服務的路由是徹底基於權重的時候,就能夠在單一規則中完成。另外一方面,若是有多重條件(例如來自特定用戶的請求)用來進行路由,就會須要不止一條規則。這樣就出現了優先級問題,須要經過優先級來保證根據正確的順序來執行規則。

常見的路由模式是提供一或多個高優先級規則,這些優先規則使用源服務以及 Header 來進行路由判斷,而後才提供一條單獨的基於權重的規則,這些低優先級規則不設置匹配規則,僅根據權重對全部剩餘流量進行分流。

例以下面的 VirtualService 包含了兩個規則,全部對 reviews 服務發起的請求,若是 Header 包含 Foo=bar,就會被路由到 v2實例,而其餘請求則會發送給 v1

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - match:
 - headers:
 Foo:
 exact: bar
 route:
 - destination:
 host: reviews
 subset: v2
 - route:
 - destination:
 host: reviews
 subset: v1複製代碼

注意,基於 Header 的規則具備更高優先級。若是下降它的優先級,那麼這一規則就沒法生效了,這是由於那些沒有限制的權重規則會首先被執行,也就是說全部請求即便包含了符合條件的 Foo 頭,也都會被路由到 v1。流量特徵被判斷爲符合一條規則的條件的時候,就會結束規則的選擇過程,這就是在存在多條規則時,須要慎重考慮優先級問題的緣由。

目標規則

在請求被 VirtualService 路由以後,DestinationRule 配置的一系列策略就生效了。這些策略由服務屬主編寫,包含斷路器、負載均衡以及 TLS 等的配置內容。

DestinationRule 還定義了對應目標主機的可路由 subset(例若有命名的版本)。VirtualService 在向特定服務版本發送請求時會用到這些子集。

下面是 reviews 服務的 DestinationRule 配置策略以及子集:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 trafficPolicy:
 loadBalancer:
 simple: RANDOM
 subsets:
 - name: v1
 labels:
 version: v1
 - name: v2
 labels:
 version: v2
 trafficPolicy:
 loadBalancer:
 simple: ROUND_ROBIN
 - name: v3
 labels:
 version: v3複製代碼

注意在單個 DestinationRule 配置中能夠包含多條策略(好比 default 和 v2)。

斷路器

能夠用一系列的標準,例如鏈接數和請求數限制來定義簡單的斷路器。

例以下面的 DestinationRulereviews 服務的 v1 版本設置了 100 鏈接的限制:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - name: v1
 labels:
 version: v1
 trafficPolicy:
 connectionPool:
 tcp:
 maxConnections: 100複製代碼

規則評估

和路由規則相似,DestinationRule 中定義的策略也是和特定的 host 相關聯的,若是指定了 subset,那麼具體生效的 subset 的決策是由路由規則來決定的。

規則評估的第一步,是確認 VirtualService 中所請求的主機相對應的路由規則(若是有的話),這一步驟決定了將請求發往目標服務的哪個 subset(就是特定版本)。下一步,被選中的 subset 若是定義了策略,就會開始是否生效的評估。

注意:這一算法須要留心是,爲特定 subset 定義的策略,只有在該 subset 被顯式的路由時候才能生效。例以下面的配置,只爲 review 服務定義了規則(沒有對應的 VirtualService 路由規則)。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - name: v1
 labels:
 version: v1
 trafficPolicy:
 connectionPool:
 tcp:
 maxConnections: 100複製代碼

既然沒有爲 reviews 服務定義路由規則,那麼就會使用缺省的 round-robin 策略,偶爾會請求到 v1 實例,若是隻有一個 v1 實例,那麼全部請求都會發送給它。然而上面的策略是永遠不會生效的,這是由於,缺省路由是在更底層完成的任務,策略引擎沒法獲知最終目的,也沒法爲請求選擇匹配的 subset 策略。

有兩種方法來解決這個問題。能夠把路由策略提升一級,要求他對全部版本生效:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 trafficPolicy:
 connectionPool:
 tcp:
 maxConnections: 100
 subsets:
 - name: v1
 labels:
 version: v1複製代碼

還有一個更好的方法,就是爲服務定義路由規則,例如給 reviews:v1 加入一個簡單的路由規則:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - route:
 - destination:
 host: reviews
 subset: v1複製代碼

雖然 Istio 在沒有定義任何規則的狀況下,能將全部來源的流量發送給全部版本的目標服務。然而一旦須要對版本有所區別,就須要制定規則了。從一開始就給每一個服務設置缺省規則,是 Istio 世界裏推薦的最佳實踐。

Service Entry

Istio 內部會維護一個服務註冊表,能夠用 ServiceEntry 向其中加入額外的條目。一般這個對象用來啓用對 Istio 服務網格以外的服務發出請求。例以下面的 ServiceEntry 能夠用來容許外部對 *.foo.com 域名上的服務主機的調用。

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
 name: foo-ext-svc
spec:
 hosts:
 - *.foo.com
 ports:
 - number: 80
 name: http
 protocol: HTTP
 - number: 443
 name: https
 protocol: HTTPS複製代碼

ServiceEntry 中使用 hosts 字段來指定目標,字段值能夠是一個徹底限定名,也能夠是個通配符域名。其中包含的白名單,包含一或多個容許網格中服務訪問的服務。

ServiceEntry 的配置不只限於外部服務,它有兩種類型:網格內部和網格外部。網格內的條目和其餘的內部服務相似,用於顯式的將服務加入網格。能夠用來把服務做爲服務網格擴展的一部分加入不受管理的基礎設置(例如加入到基於 Kubernetes 的服務網格中的虛擬機)中。網格外的條目用於表達網格外的服務。對這種條目來講,雙向 TLS 認證被禁用,策略實現須要在客戶端執行,而不像內部服務請求那樣在服務端執行。

只要 ServiceEntry 涉及到了匹配 host 的服務,就能夠和 VirtualService 以及 DestinationRule 配合工做。例以下面的規則能夠和上面的 ServiceEntry 同時使用,在訪問 bar.foo.com 的外部服務時,設置一個 10 秒鐘的超時。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: bar-foo-ext-svc
spec:
 hosts:
 - bar.foo.com
 http:
 - route:
 - destination:
 host: bar.foo.com
 timeout: 10s複製代碼

流量的重定向和轉發、定義重試和超時以及錯誤注入策略都支持外部目標。然而因爲外部服務沒有多版本的概念,所以權重(基於版本)路由就沒法實現了。

參照 egress 任務能夠了解更多的訪問外部服務方面的知識。

Gateway

Gateway 爲 HTTP/TCP 流量配置了一個負載均衡,多數狀況下在網格邊緣進行操做,用於啓用一個服務的入口(ingress)流量。

和 Kubernetes Ingress 不一樣,Istio Gateway 只配置四層到六層的功能(例如開放端口或者 TLS 配置)。綁定一個 VirtualServiceGateway 上,用戶就可使用標準的 Istio 規則來控制進入的 HTTP 和 TCP 流量。

例以下面提供一個簡單的 Gateway 代碼,配合一個負載均衡,容許外部針對主機 bookinfo.com 的 https 流量:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
 name: bookinfo-gateway
spec:
 servers:
 - port:
 number: 443
 name: https
 protocol: HTTPS
 hosts:
 - bookinfo.com
 tls:
 mode: SIMPLE
 serverCertificate: /tmp/tls.crt
 privateKey: /tmp/tls.key複製代碼

要爲 Gateway 配置對應的路由,必須爲定義一個一樣 host 定義的 VirtualService,其中用 gateways 字段來綁定到定義好的 Gateway 上:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: bookinfo
spec:
 hosts:
 - bookinfo.com
 gateways:
 - bookinfo-gateway # <---- 綁定到 Gateway
 http:
 - match:
 - uri:
 prefix: /reviews
 route:
    ...複製代碼

Ingress 任務 中有完整的 Ingress Gateway 例子。

雖然主要用於管理入口(Ingress)流量,Gateway 還能夠用在純粹的內部服務之間或者出口(Egress)場景下使用。無論處於什麼位置,全部的網關均可以以一樣的方式進行配置和控制。Gateway 參考 中包含更多細節描述。

ServiceMesher社區信息

社區官網:www.servicemesher.com

Slack:servicemesher.slack.com 須要邀請才能加入,有志於加入ServiceMesher社區爲Service Mesh做出貢獻的同窗能夠聯繫我。

Twitter: twitter.com/servicemesh…

更多Service Mesh諮詢請掃碼關注微信公衆號ServiceMesher。

相關文章
相關標籤/搜索