虚拟服务
影响流量路由的配置。以下是一些在流量路由的上下文中定义的有用术语。
服务
应用程序行为的单位,绑定到服务注册表中的唯一名称。服务由在 Pod、容器、VM 等上运行的工作负载实例实现的多个网络端点组成。
服务版本(又称子集)
- 在持续部署场景中,对于给定服务,可能存在运行应用程序二进制文件的不同变体的不同实例子集。这些变体不一定是不同的 API 版本。它们可能是对同一服务的迭代更改,部署在不同的环境中(生产、登台、开发等)。发生这种情况的常见场景包括 A/B 测试、金丝雀发布等。特定版本的選擇可以根据各种标准(标头、URL 等)或根据分配给每个版本的权重来决定。每个服务都有一个包含其所有实例的默认版本。
源
- 调用服务的下游客户端。
主机
- 客户端尝试连接到服务时使用的地址。
访问模型
- 应用程序仅访问目标服务(主机),而不知道各个服务版本(子集)。版本的选择由代理/边车决定,使应用程序代码能够与依赖服务的演变分离。
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
虚拟服务
影响流量路由的配置。
目标
Destination 指示在处理路由规则后将请求/连接发送到的可寻址网络服务。destination.host 应该明确地引用服务注册表中的服务。Istio 的服务注册表由平台的服务注册表(例如 Kubernetes 服务、Consul 服务)中找到的所有服务以及通过 ServiceEntry 资源声明的服务组成。
Kubernetes 用户注意:使用短名称(例如“reviews”而不是“reviews.default.svc.cluster.local”)时,Istio 将根据规则的命名空间而不是服务来解释短名称。在“default”命名空间中包含主机“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 的内部服务注册表。然后可以定义 VirtualService 来控制绑定到这些外部服务的流量。例如,以下规则定义了 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。
委托
描述代理 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
标头
当 Envoy 将请求转发到目标服务或从目标服务转发响应时,可以操作消息头。可以为特定路由目标或所有目标指定头操作规则。以下虚拟服务为路由到任何 reviews 服务目标的请求添加了一个值为 true 的 test 头。它还删除了 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)。以下路由规则将到达名为 mygateway 的网关 443 端口的未终止 TLS 流量转发到网格中的内部服务,具体取决于 SNI 值。
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 端口的流量转发到另一个 Mongo 服务器的 5555 端口。
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 不能为空。注意:
- 如果根虚拟服务通过正则表达式匹配了任何属性(路径、头等),委托虚拟服务不应该在同一属性上进行任何其他匹配。
- 如果委托虚拟服务通过正则表达式匹配了任何属性(路径、头等),根虚拟服务不应该在同一属性上进行任何其他匹配。
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 请求的特定部分。Rewrite 原语只能与 HTTPRouteDestination 一起使用。以下示例演示了如何在进行实际 API 调用之前重写对 ratings 服务的 api 调用(/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 秒。如果发生连接失败、拒绝流或上游服务器响应服务不可用 (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。例如,以下规则将跨域请求限制为使用 HTTP POST/GET 从 example.com 域发起的请求,并将 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 请求,和/或延迟请求的代理。故障规则必须具有延迟或中止或两者兼而有之。
注意:延迟和中止故障是独立的,即使同时指定了它们。
HTTPMirrorPolicy
HTTPMirrorPolicy 可用于指定除了原始目的地之外的镜像 HTTP 流量的目的地。镜像流量是尽力而为的,其中 sidecar/gateway 不会等待镜像目的地响应,然后才返回来自原始目的地的响应。将为镜像目的地生成统计信息。
PortSelector
PortSelector 指定要用于匹配或选择最终路由的端口号。
Percent
Percent 指定 0.0 到 100.0 范围内的百分比。
Headers.HeaderOperations
HeaderOperations 描述要应用的标头操作
HTTPFaultInjection.Delay
延迟规范用于将延迟注入请求转发路径。以下示例将在来自具有标签 env: prod 的所有 pod 的“reviews”服务的“v1”版本的每 1000 个请求中引入一个 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
中止规范用于使用预先指定的错误代码过早中止请求。以下示例将在每 1000 个对“ratings”服务“v1”的请求中返回 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
Name | 描述 |
---|---|
FROM_PROTOCOL_DEFAULT | |
FROM_REQUEST_PORT |
CorsPolicy.UnmatchedPreflights
Name | 描述 |
---|---|
UNSPECIFIED | 默认为 FORWARD |
FORWARD | 不匹配配置的允许来源的预检请求将被转发到上游。 |
IGNORE | 不匹配配置的允许来源的预检请求将不会被转发到上游。 |