虛擬服務
影響流量路由的設定。以下是一些在流量路由上下文中定義有用的術語。
服務 (Service)
:應用程式行為的單元,在服務註冊表中與唯一的名稱綁定。服務由多個網路端點 (endpoints)組成,這些端點由在 Pod、容器、VM 等上執行的工作負載實例實現。
服務版本(又稱子集)(Service versions (a.k.a. subsets))
:在持續部署的場景中,對於給定的服務,可以有不同的實例子集,它們執行應用程式二進制檔案的不同變體。這些變體不一定是不同的 API 版本。它們可能是對同一服務的迭代變更,部署在不同的環境中(生產、預備、開發等)。發生這種情況的常見場景包括 A/B 測試、金絲雀發布等。特定版本的選擇可以基於各種標準(標頭、URL 等)和/或分配給每個版本的權重來決定。每個服務都有一個預設版本,由其所有實例組成。
來源 (Source)
:呼叫服務的下游用戶端。
主機 (Host)
:用戶端嘗試連線到服務時使用的位址。
存取模型 (Access model)
:應用程式僅尋址目標服務(主機),而不知道個別服務版本(子集)。版本的實際選擇由代理/邊車決定,使應用程式碼能夠將自身與相依服務的演變分離。
VirtualService
定義在尋址主機時要應用的一組流量路由規則。每個路由規則都定義了特定協定的流量匹配條件。如果流量匹配,則會將其傳送到註冊表中定義的指定目的地服務(或其子集/版本)。
流量的來源也可以在路由規則中匹配。這允許為特定的用戶端內容自訂路由。
以下 Kubernetes 範例預設將所有 HTTP 流量路由到具有標籤 “version: v1” 的 reviews 服務的 Pod。此外,路徑以 /wpcatalog/ 或 /consumercatalog/ 開頭的 HTTP 請求將被重寫為 /newcatalog,並傳送到具有標籤 “version: v2” 的 Pod。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-route
spec:
hosts:
- reviews.prod.svc.cluster.local
http:
- name: "reviews-v2-routes"
match:
- uri:
prefix: "/wpcatalog"
- uri:
prefix: "/consumercatalog"
rewrite:
uri: "/newcatalog"
route:
- destination:
host: reviews.prod.svc.cluster.local
subset: v2
- name: "reviews-v1-route"
route:
- destination:
host: reviews.prod.svc.cluster.local
subset: v1
路由目的地的子集/版本由對指定服務子集的參考來識別,該子集必須在相應的 DestinationRule
中宣告。
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews-destination
spec:
host: reviews.prod.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
VirtualService
影響流量路由的設定。
Destination
目的地表示處理路由規則後,請求/連線將傳送到的網路可尋址服務。destination.host 應明確指向服務註冊表中的服務。Istio 的服務註冊表由平台服務註冊表(例如,Kubernetes 服務、Consul 服務)中找到的所有服務,以及透過ServiceEntry資源宣告的服務組成。
Kubernetes 使用者注意事項:當使用簡短名稱(例如「reviews」而不是「reviews.default.svc.cluster.local」)時,Istio 將根據規則的命名空間而不是服務來解讀簡短名稱。在「預設」命名空間中包含主機「reviews」的規則將被解讀為「reviews.default.svc.cluster.local」,而與與 reviews 服務關聯的實際命名空間無關。為了避免潛在的錯誤配置,建議始終使用完整網域名稱而不是簡短名稱。
以下 Kubernetes 範例預設將所有流量路由到具有標籤「version: v1」(即子集 v1)的 reviews 服務的 Pod,並將某些流量路由到子集 v2(在 Kubernetes 環境中)。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-route
namespace: foo
spec:
hosts:
- reviews # interpreted as reviews.foo.svc.cluster.local
http:
- match:
- uri:
prefix: "/wpcatalog"
- uri:
prefix: "/consumercatalog"
rewrite:
uri: "/newcatalog"
route:
- destination:
host: reviews # interpreted as reviews.foo.svc.cluster.local
subset: v2
- route:
- destination:
host: reviews # interpreted as reviews.foo.svc.cluster.local
subset: v1
以及相關聯的 DestinationRule
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews-destination
namespace: foo
spec:
host: reviews # interpreted as reviews.foo.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
以下 VirtualService 為 Kubernetes 中對 productpage.prod.svc.cluster.local 服務的所有呼叫設定 5 秒的逾時。請注意,此規則中未定義子集。Istio 將從服務註冊表中擷取 productpage.prod.svc.cluster.local 服務的所有實例,並填入邊車的負載平衡池。此外,請注意,此規則設定在 istio-system 命名空間中,但使用 productpage 服務的完整網域名稱 productpage.prod.svc.cluster.local。因此,規則的命名空間不會影響解析 productpage 服務的名稱。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: my-productpage-rule
namespace: istio-system
spec:
hosts:
- productpage.prod.svc.cluster.local # ignores rule namespace
http:
- timeout: 5s
route:
- destination:
host: productpage.prod.svc.cluster.local
若要控制傳送到網格外部服務的流量的路由,必須先使用 ServiceEntry 資源將外部服務新增至 Istio 的內部服務註冊表。然後可以定義 VirtualServices 來控制傳送到這些外部服務的流量。例如,以下規則定義了 wikipedia.org 的服務,並為 HTTP 請求設定了 5 秒的逾時。
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: external-svc-wikipedia
spec:
hosts:
- wikipedia.org
location: MESH_EXTERNAL
ports:
- number: 80
name: example-http
protocol: HTTP
resolution: DNS
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: my-wiki-rule
spec:
hosts:
- wikipedia.org
http:
- timeout: 5s
route:
- destination:
host: wikipedia.org
HTTPRoute
描述 HTTP/1.1、HTTP2 和 gRPC 流量的匹配條件和路由動作。如需使用範例,請參閱 VirtualService。
Delegate
描述委派 VirtualService。以下路由規則將流量轉發到名為 productpage
的委派 VirtualService 的 /productpage
,並將流量轉發到名為 reviews
的委派 VirtualService 的 /reviews
。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "bookinfo.com"
gateways:
- mygateway
http:
- match:
- uri:
prefix: "/productpage"
delegate:
name: productpage
namespace: nsA
- match:
- uri:
prefix: "/reviews"
delegate:
name: reviews
namespace: nsB
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: productpage
namespace: nsA
spec:
http:
- match:
- uri:
prefix: "/productpage/v1/"
route:
- destination:
host: productpage-v1.nsA.svc.cluster.local
- route:
- destination:
host: productpage.nsA.svc.cluster.local
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews
namespace: nsB
spec:
http:
- route:
- destination:
host: reviews.nsB.svc.cluster.local
Headers
當 Envoy 將請求轉發到目的地服務或從目的地服務傳回回應時,可以操作訊息標頭。可以為特定路由目的地或所有目的地指定標頭操作規則。以下 VirtualService 將 test
標頭以及值 true
新增至路由到任何 reviews
服務目的地的請求。它也會移除 foo
回應標頭,但僅限於來自 reviews
服務的 v1
子集(版本)的回應。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-route
spec:
hosts:
- reviews.prod.svc.cluster.local
http:
- headers:
request:
set:
test: "true"
route:
- destination:
host: reviews.prod.svc.cluster.local
subset: v2
weight: 25
- destination:
host: reviews.prod.svc.cluster.local
subset: v1
headers:
response:
remove:
- foo
weight: 75
TLSRoute
描述用於路由未終止 TLS 流量 (TLS/HTTPS) 的比對條件和動作。以下路由規則會根據 SNI 值,將到達名為「mygateway」的閘道之連接埠 443 的未終止 TLS 流量轉發到網格中的內部服務。
apiVersion: networking.istio.io/v1
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
TCPRoute
描述用於路由 TCP 流量的比對條件和動作。以下路由規則會將到達 mongo.prod.svc.cluster.local 之連接埠 27017 的流量轉發到連接埠 5555 上的另一個 Mongo 伺服器。
apiVersion: networking.istio.io/v1
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
HTTPMatchRequest
HttpMatchRequest 指定為了將規則套用到 HTTP 請求而需要符合的一組條件。例如,以下規則將規則限制為僅比對 URL 路徑開頭為 /ratings/v2/ 且請求包含值為 jason
的自訂 end-user
標頭的請求。
apiVersion: networking.istio.io/v1
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
HTTPMatchRequest 不可以是空的。注意:
- 如果根 VirtualService 已使用 regex 比對任何屬性(路徑、標頭等),委派 VirtualService 不應在相同屬性上進行任何其他比對。
- 如果委派 VirtualService 已使用 regex 比對任何屬性(路徑、標頭等),根 VirtualService 不應在相同屬性上進行任何其他比對。
HTTPRouteDestination
每個路由規則都與一個或多個服務版本相關聯(請參閱文件開頭的詞彙表)。與版本相關聯的權重決定了它接收的流量比例。例如,以下規則會將「reviews」服務的 25% 流量路由到帶有「v2」標籤的執行個體,其餘流量(即 75%)則路由到「v1」。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-route
spec:
hosts:
- reviews.prod.svc.cluster.local
http:
- route:
- destination:
host: reviews.prod.svc.cluster.local
subset: v2
weight: 25
- destination:
host: reviews.prod.svc.cluster.local
subset: v1
weight: 75
以及相關聯的 DestinationRule
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews-destination
spec:
host: reviews.prod.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
流量也可以在兩個完全不同的服務之間分割,而無需定義新的子集。例如,以下規則會將 25% 的流量從 reviews.com 轉發到 dev.reviews.com
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-route-two-domains
spec:
hosts:
- reviews.com
http:
- route:
- destination:
host: dev.reviews.com
weight: 25
- destination:
host: reviews.com
weight: 75
RouteDestination
L4 路由規則加權目的地。
L4MatchAttributes
L4 連線比對屬性。請注意,L4 連線比對支援尚未完成。
TLSMatchAttributes
TLS 連線比對屬性。
HTTPRedirect
HTTPRedirect 可用於向呼叫者傳送 301 重新導向回應,其中回應中的 Authority/Host 和 URI 可以與指定的值交換。例如,以下規則會將 ratings 服務上對 /v1/getProductRatings API 的請求重新導向到 bookratings 服務提供的 /v1/bookRatings。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- match:
- uri:
exact: /v1/getProductRatings
redirect:
uri: /v1/bookRatings
authority: newratings.default.svc.cluster.local
...
HTTPDirectResponse
HTTPDirectResponse 可用於向用戶端傳送固定的回應。例如,以下規則會對 /v1/getProductRatings API 的請求傳回固定的 503 狀態和主體。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- match:
- uri:
exact: /v1/getProductRatings
directResponse:
status: 503
body:
string: "unknown error"
...
也可以指定二進位回應主體。這對於非基於文字的協定(例如 gRPC)最為有用。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- match:
- uri:
exact: /v1/getProductRatings
directResponse:
status: 503
body:
bytes: "dW5rbm93biBlcnJvcg==" # "unknown error" in base64
...
在 HTTPRoute 以及 direct_response 中新增標頭是很好的實務,例如指定傳回的 Content-Type。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- match:
- uri:
exact: /v1/getProductRatings
directResponse:
status: 503
body:
string: "{\"error\": \"unknown error\"}"
headers:
response:
set:
content-type: "text/plain"
...
HTTPBody
HTTPRewrite
HTTPRewrite 可用於在將請求轉發到目的地之前,重寫 HTTP 請求的特定部分。重寫基本類型只能與 HTTPRouteDestination 一起使用。以下範例示範如何在進行實際 API 呼叫之前,重寫 api 呼叫 (/ratings) 到 ratings 服務的 URL 前綴。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- match:
- uri:
prefix: /ratings
rewrite:
uri: /v1/bookRatings
route:
- destination:
host: ratings.prod.svc.cluster.local
subset: v1
RegexRewrite
StringMatch
描述如何在 HTTP 標頭中匹配給定的字串。exact
和 prefix
匹配區分大小寫。regex
匹配支援不區分大小寫的匹配。
HTTPRetry
描述 HTTP 請求失敗時要使用的重試原則。例如,以下規則設定呼叫 ratings:v1 服務時允許的最大重試次數為 3 次,每次重試嘗試的逾時時間為 2 秒。如果發生連線失敗、拒絕串流或上游伺服器回應 Service Unavailable(503) 錯誤,則會嘗試重試。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- route:
- destination:
host: ratings.prod.svc.cluster.local
subset: v1
retries:
attempts: 3
perTryTimeout: 2s
retryOn: gateway-error,connect-failure,refused-stream
CorsPolicy
描述給定服務的跨來源資源共享 (CORS) 原則。請參閱 CORS 以了解更多有關跨來源資源共享的詳細資訊。例如,以下規則將跨來源請求限制為來自 example.com 網域的請求(使用 HTTP POST/GET),並將 Access-Control-Allow-Credentials
標頭設定為 false。此外,它只會公開 X-Foo-bar
標頭,並設定 1 天的到期期限。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- route:
- destination:
host: ratings.prod.svc.cluster.local
subset: v1
corsPolicy:
allowOrigins:
- exact: https://example.com
allowMethods:
- POST
- GET
allowCredentials: false
allowHeaders:
- X-Foo-Bar
maxAge: "24h"
HTTPFaultInjection
HTTPFaultInjection 可用於指定一或多個要在將 HTTP 請求轉發到路由中指定的目的地時注入的錯誤。錯誤規格是 VirtualService 規則的一部分。錯誤包括從下游服務中止 Http 請求和/或延遲請求的 Proxy 處理。錯誤規則必須具有延遲或中止或兩者。
注意: 延遲和中止錯誤彼此獨立,即使同時指定兩者。
HTTPMirrorPolicy
HTTPMirrorPolicy 可用於指定除了原始目的地之外,還要鏡像 HTTP 流量的目的地。鏡像流量是盡力而為,側車/閘道不會等待鏡像目的地回應,才會傳回來自原始目的地的回應。將為鏡像目的地產生統計資料。
PortSelector
PortSelector 指定要用於匹配或選取最終路由的 Port 號碼。
Percent
Percent 指定 [0.0, 100.0] 範圍內的百分比。
Headers.HeaderOperations
HeaderOperations 描述要應用的標頭操作
HTTPFaultInjection.Delay
延遲規格用於將延遲注入請求轉發路徑。以下範例會在所有具有標籤 env: prod 的 Pod 中,每 1000 個請求中對「reviews」服務的「v1」版本引入 5 秒的延遲
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-route
spec:
hosts:
- reviews.prod.svc.cluster.local
http:
- match:
- sourceLabels:
env: prod
route:
- destination:
host: reviews.prod.svc.cluster.local
subset: v1
fault:
delay:
percentage:
value: 0.1
fixedDelay: 5s
fixedDelay 欄位用於表示延遲的秒數。選用的 percentage 欄位可以用於僅延遲特定百分比的請求。如果未指定,則不會延遲任何請求。
HTTPFaultInjection.Abort
中止規格用於以預先指定的錯誤碼過早中止請求。以下範例會針對「ratings」服務「v1」的每 1000 個請求中的 1 個傳回 HTTP 400 錯誤碼。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- route:
- destination:
host: ratings.prod.svc.cluster.local
subset: v1
fault:
abort:
percentage:
value: 0.1
httpStatus: 400
httpStatus 欄位用於指示要傳回給呼叫端的 HTTP 狀態碼。選擇性的 percentage 欄位可用於僅中止特定百分比的請求。如果未指定,則不會中止任何請求。
google.protobuf.UInt32Value
uint32
的包裝訊息。
UInt32Value
的 JSON 表示法是 JSON 數字。
HTTPRedirect.RedirectPortSelection
名稱 | 描述 |
---|---|
FROM_PROTOCOL_DEFAULT | |
FROM_REQUEST_PORT |
CorsPolicy.UnmatchedPreflights
名稱 | 描述 |
---|---|
UNSPECIFIED | 預設為 FORWARD |
FORWARD | 不符合設定的允許來源的預檢請求將會轉發到上游。 |
IGNORE | 不符合設定的允許來源的預檢請求將不會轉發到上游。 |