概念及示例
VirtualService
描述了一個或多個用戶可尋址目標到網格內實際工作負載之間的映射 。 虛擬服務讓您配置如何在服務網格內將請求路由到服務,這基於 Istio 和平台提供的基本的連通性和服務發現能力。每個虛擬服務包含一組路由規則,Istio 按順序評估它們,Istio 將每個給定的請求匹配到虛擬服務指定的實際目標地址。您的網格可以有多個虛擬服務,也可以沒有,取決於您的使用場景。
虛擬服務在增強 Istio 流量管理的靈活性和有效性方面,發揮着至關重要的作用,通過對客戶端請求的目標地址與真實響應請求的目標工作負載進行解耦來實現。虛擬服務同時提供了豐富的方式,為發送至這些工作負載的流量指定不同的路由規則。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
gateways:
- bookinfo-gateway
- mesh
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v3
gateways字段
通過將 VirtualService
綁定到同一 Host 的 Gateway
配置(如前一節所述 ),可向網格外部暴露這些 Host。
gateways:
- bookinfo-gateway
- mesh
網格內部通信存在一個默認的mesh
保留字, mesh
用來指代網格中的所有 Sidecar。當這一字段被省略時,就會使用缺省值(mesh
),也就是針對網格中的所有 Sidecar 生效。如果提供了 gateways
字段,這一規則就只會應用到聲明的 Gateway
之中。要讓規則同時對 Gateway
和網格內服務生效,需要顯式的將 mesh
加入 gateways
列表。
Hosts字段
VirtualService
中 hosts
字段列舉虛擬服務的目標主機 ——即用戶指定的目標或是路由規則設定的目標。這是客戶端向服務發送請求時使用的一個或多個地址 。
hosts:
- bookinfo.com
虛擬服務目的地可以是 IP 地址、DNS 名稱,或者依賴於平台的一個簡稱(例如 Kubernetes 服務的短名稱),隱式或顯式地指向一個完全限定域名(FQDN)。您也可以使用通配符(“*”)前綴,讓您創建一組匹配所有服務的路由規則。虛擬服務的 hosts
字段實際上不必是 Istio 服務注冊的一部分,它只是虛擬的目標地址。這讓您可以為沒有路由到網格內部的虛擬主機建模。
路由規則
在 http
字段包含了虛擬服務的路由規則,用來描述匹配條件和路由行為,它們把 HTTP/1.1、HTTP2 和 gRPC 等流量發送到 hosts 字段指定的目標(您也可以用 tcp
和 tls
片段流量設置路由規則)。一個路由規則包含了指定的請求要流向哪個目標地址,具有 0 或多個匹配條件,取決於您的使用場景。
匹配條件
示例中的第一個路由規則有一個條件,因此以 match
字段開始。在本例中,您希望此路由應用於來自 ”jason“ 用戶的所有請求,所以使用 headers
、end-user
和 exact
字段選擇適當的請求。
- match:
- headers:
end-user:
exact: jason
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- match:
- headers:
end-user:
exact: jason
uri:
prefix: "/ratings/v2/"
ignoreUriCase: true
route:
- destination:
host: ratings.prod.svc.cluster.local
Destination
route 部分的 destination
字段指定了符合此條件的流量的實際目標地址。與虛擬服務的 hosts
不同,destination 的 host 必須是存在於 Istio 服務注冊中心的實際目標地址,否則 Envoy 不知道該將請求發送到哪里。可以是一個有代理的服務網格,或者是一個通過服務入口被添加進來的非網格服務。本示例運行在 Kubernetes 環境中,host 名為一個 Kubernetes 中運行着Service
的名稱:
route:
- destination:
host: reviews
subset: v2
請注意,在該示例和本頁其它示例中,為了簡單,我們使用 Kubernetes Service
的短名稱設置 destination 的 host。在評估此規則時,Istio 會添加一個基於虛擬服務命名空間的域后綴,這個虛擬服務包含要獲取主機的完全限定名的路由規則。在我們的示例中使用短名稱也意味着您可以復制並在任何喜歡的命名空間中嘗試它們。
只有在目標主機和虛擬服務位於相同的 Kubernetes 命名空間時才可以使用這樣的短名稱 , 建議您在生產環境中指定完全限定的主機名。
destination 片段還指定了 Kubernetes 服務的子集,將符合此規則條件的請求轉入其中。在本例中子集名稱是 v2。您可以在DestinationRule章節中看到如何定義服務子集。
Subset字段
subset
不屬於 Istio 創建的 CRD,但是它是一條重要的配置信息,有必要單獨說明下。subset
是服務端點的集合,可以用於 A/B 測試或者分版本路由等場景。另外在 subset
中可以覆蓋服務級別的即 VirtualService
中的定義的流量策略。
以下是subset
的配置信息。對於 Kubernetes 中的服務,一個 subset
相當於使用 label 的匹配條件選出來的 Service
Field | Type | Description | Required |
---|---|---|---|
name | string | 服務名和 subset 名稱可以用於路由規則中的流量拆分 |
Yes |
labels | map | 使用標簽對服務注冊表中的服務端點進行篩選 | No |
trafficPolicy | TrafficPolicy | 應用到這一 subset 的流量策略。缺省情況下 subset 會繼承 DestinationRule 級別的策略,這一字段的定義則會覆蓋缺省的繼承策略 |
No |
路由規則優先級
路由規則按從上到下的順序選擇,虛擬服務中定義的第一條規則有最高優先級。本示例中,不滿足第一個路由規則的流量均流向一個默認的目標,該目標在第二條規則中指定。因此,第二條規則沒有 match 條件,直接將流量導向 v3 子集。 我們建議提供一個默認的“無條件”或基於權重的規則作為每一個虛擬服務的最后一條規則,從而確保流經虛擬服務的流量至少能夠匹配一條路由規則。
VirtualService配置
Field | Type | Description | Required |
---|---|---|---|
hosts | string[] | 流量的目標主機。可以是帶有通配符前綴的 DNS 名稱,也可以是 IP 地址。根據所在平台情況,還可能使用短名稱來代替 FQDN。這種場景下,短名稱到 FQDN 的具體轉換過程是要靠下層平台完成的。一個主機名只能在一個 VirtualService 中定義。同一個 VirtualService 中可以用於控制多個 HTTP 和 TCP 端口的流量屬性。Kubernetes 用戶注意:當使用服務的短名稱時(例如使用 reviews ,而不是 reviews.default.svc.cluster.local ),Istio 會根據規則所在的命名空間來處理這一名稱,而非服務所在的命名空間。假設 “default” 命名空間的一條規則中包含了一個 reviews 的 host 引用,就會被視為 reviews.default.svc.cluster.local ,而不會考慮 reviews 服務所在的命名空間。為了避免可能的錯誤配置,建議使用 FQDN 來進行服務引用。 hosts 字段對 HTTP 和 TCP 服務都是有效的。網格中的服務也就是在服務注冊表中注冊的服務,必須使用他們的注冊名進行引用;只有 Gateway 定義的服務才可以使用 IP 地址。 |
Yes |
gateways | string[] | Gateway 名稱列表,Sidecar 會據此使用路由。VirtualService 對象可以用於網格中的 Sidecar,也可以用於一個或多個 Gateway 。這里公開的選擇條件可以在協議相關的路由過濾條件中進行覆蓋。保留字 mesh 用來指代網格中的所有 Sidecar。當這一字段被省略時,就會使用缺省值(mesh ),也就是針對網格中的所有 Sidecar 生效。如果提供了 gateways 字段,這一規則就只會應用到聲明的 Gateway 之中。要讓規則同時對 Gateway 和網格內服務生效,需要顯式的將 mesh 加入 gateways 列表。 |
No |
http | HTTPRoute[] | HTTP 流量規則的有序列表。這個列表對名稱前綴為 http- 、http2- 、grpc- 的服務端口,或者協議為 HTTP 、HTTP2 、GRPC 以及終結的 TLS,另外還有使用 HTTP 、HTTP2 以及 GRPC 協議的 ServiceEntry 都是有效的。進入流量會使用匹配到的第一條規則。 |
No |
tls | TLSRoute[] | 一個有序列表,對應的是透傳 TLS 和 HTTPS 流量。路由過程通常利用 ClientHello 消息中的 SNI 來完成。TLS 路由通常應用在 https- 、tls- 前綴的平台服務端口,或者經 Gateway 透傳的 HTTPS、TLS 協議端口,以及使用 HTTPS 或者 TLS 協議的 ServiceEntry 端口上。注意:沒有關聯 VirtualService 的 https- 或者 tls- 端口流量會被視為透傳 TCP 流量。 |
No |
tcp | TCPRoute[] | 一個針對透傳 TCP 流量的有序路由列表。TCP 路由對所有 HTTP 和 TLS 之外的端口生效。進入流量會使用匹配到的第一條規則。 | No |
exportTo | string[] | 當前vritual service要導出的 namespace 列表。 應用於 vritual service 的解析發生在 namespace 層次結構的上下文中。 vritual service 的導出允許將其包含在其他 namespace 中的服務的解析層次結構中。 此功能為服務所有者和網格管理員提供了一種機制,用於控制跨 namespace 邊界的 vritual service 的可見性 如果未指定任何 namespace,則默認情況下將 vritual service rule 導出到所有 namespace 值 . 被保留,用於定義導出到 vritual service 被聲明所在的相同 namespace 。類似的值* 保留,用於定義導出到所有 namespacesNOTE:在當前版本中,exportTo值被限制為 . 或* (即, 當前namespace或所有namespace) |
HTTPRoute配置
Field | Type | Description | Required |
---|---|---|---|
name | string | 為route分配給路由的名稱 | No |
match | HTTPMatchRequest[] | 匹配要激活的規則要滿足的條件。單個匹配塊內的所有條件都具有AND語義,而匹配塊列表具有OR語義。如果任何一個匹配塊成功,則匹配該規則。 | No |
route | HTTPRouteDestination[] | http規則可以重定向或轉發(默認)流量 | No |
redirect | HTTPRedirect | http規則可以重定向或轉發(默認)流量. 如果在規則中指定了流量通過選項,則將忽略路由/重定向。重定向原語可用於將HTTP 301重定向發送到其他URI或Authority。 | No |
rewrite | HTTPRewrite | 重寫 HTTP URIs and Authority header. 重寫不能與重定向原語一起使用 | No |
timeout | Duration | Timeout for HTTP requests. | No |
retries | HTTPRetry | Retry policy for HTTP requests. | No |
fault | HTTPFaultInjection | 故障注入策略,適用於客戶端的HTTP通信。請注意,如果在客戶端啟用了故障注入策略,則不會啟用超時或重試。 | No |
mirror | Destination | 除了將請求轉發到預期目標之外,還可以將HTTP流量鏡像到另一個目標。 | No |
mirrorPercent | UInt32Value | mirror 字段是設置流量的百分比。如果不存在該字段,則將鏡像所有流量(100%)。最大值為100。 |
No |
corsPolicy | CorsPolicy | 有關跨源資源共享的更多詳細信息,請參考 CORS | No |
headers | Headers | Header 規則 | No |
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- bookinfo.com
http:
- match:
- uri:
prefix: /reviews
route:
- destination:
host: reviews
- match:
- uri:
prefix: /ratings
route:
- destination:
host: ratings
...
TCPRoute配置
Field | Type | Description | Required |
---|---|---|---|
match | L4MatchAttributes[] | 匹配要激活的規則要滿足的條件。單個匹配塊內的所有條件都具有AND語義,而匹配塊列表具有OR語義。如果任何一個匹配塊成功,則匹配該規則。 | No |
route | RouteDestination[] | 連接應轉發到的目的地 | No |
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo-Mongo
spec:
hosts:
- mongo.prod.svc.cluster.local
tcp:
- match:
- port: 27017
route:
- destination:
host: mongo.backup.svc.cluster.local
port:
number: 5555
TLSRoute配置
Type | Type | Description | Required |
---|---|---|---|
match | TLSMatchAttributes[] | 匹配要激活的規則要滿足的條件。單個匹配塊內的所有條件都具有AND語義,而匹配塊列表具有OR語義。如果任何一個匹配塊成功,則匹配該規則。 | Yes |
route | RouteDestination[] | 連接應轉發到的目的地 | No |
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo-sni
spec:
hosts:
- "*.bookinfo.com"
gateways:
- mygateway
tls:
- match:
- port: 443
sniHosts:
- login.bookinfo.com
route:
- destination:
host: login.prod.svc.cluster.local
- match:
- port: 443
sniHosts:
- reviews.bookinfo.com
route:
- destination:
host: reviews.prod.svc.cluster.local
具體細節的參數明細可查閱:https://preliminary.istio.io/zh/docs/reference/config/networking/virtual-service/#VirtualService
參考文獻
https://preliminary.istio.io/zh/docs/concepts/traffic-management/#virtual-services
https://preliminary.istio.io/zh//blog/2018/v1alpha3-routing/
https://preliminary.istio.io/zh/docs/reference/config/networking/virtual-service/#VirtualService
https://jimmysong.io/istio-handbook/concepts/traffic-management-basic.html