📑 目录
- [1. 什么是 Virtual Service?](#1. 什么是 Virtual Service?)
- [2. Virtual Service 配置结构详解](#2. Virtual Service 配置结构详解)
- [3. 核心功能与配置示例](#3. 核心功能与配置示例)
- [3.1 基于权重的流量切分(金丝雀发布)](#3.1 基于权重的流量切分(金丝雀发布))
- [3.2 基于请求内容的路由(A/B测试)](#3.2 基于请求内容的路由(A/B测试))
- [3.3 故障注入](#3.3 故障注入)
- [3.4 超时与重试](#3.4 超时与重试)
- [3.5 流量镜像(影子流量)](#3.5 流量镜像(影子流量))
- [4. 与 Destination Rule 的关系](#4. 与 Destination Rule 的关系)
- [5. 部署与验证](#5. 部署与验证)
- [6. 最佳实践与注意事项](#6. 最佳实践与注意事项)
1. 什么是 Virtual Service?
Virtual Service(虚拟服务)是 Istio 流量管理模型中的核心资源之一。它定义了如何将客户端请求路由到服务网格内的服务实例。你可以将 Virtual Service 理解为传统负载均衡器配置的声明式升级版,它允许你基于 HTTP、gRPC、TCP 等协议的各种属性(如 URI、Header、权重)来精细地控制流量。
核心作用:
- 请求路由:定义匹配规则,将流量导向特定的服务子集(如不同版本)。
- 流量切分:按权重将流量分发到多个服务版本(如金丝雀发布)。
- 故障注入:模拟服务故障,用于测试系统的弹性。
- 超时与重试:为服务调用配置超时和重试策略,提高可靠性。
- 跨服务版本路由:实现 A/B 测试、蓝绿部署等高级发布策略。
Virtual Service 通常与 Destination Rule 协同工作。Destination Rule 定义了到达目标服务后的策略(如负载均衡算法、连接池设置),而 Virtual Service 则定义了"哪些流量"以及"如何"到达这些目标。
2. Virtual Service 配置结构详解
一个典型的 Virtual Service 资源配置文件(YAML)包含以下主要部分:
yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews-vs # Virtual Service 的名称
namespace: default # 所属命名空间
spec:
hosts: # 指定该 Virtual Service 应用的目标服务,当有请求访问 `reviews` 这个域名时,归我管。
- reviews
http: # 定义 HTTP 流量规则(也支持 tcp, tls)
- match: # 匹配条件,可选。不写 match 则匹配所有流量
- headers: # 按请求头匹配
end-user:
exact: jason
route: # 路由目的地
- destination:
host: reviews # 目标服务名,需在网格内可解析
subset: v2 # 对应 Destination Rule 中定义的子集
- route: # 另一个路由规则(默认路由)
- destination:
host: reviews
subset: v1
weight: 80 # 流量权重 80%
- destination:
host: reviews
subset: v3
weight: 20 # 流量权重 20%
配置字段逐行说明
-
apiVersion: networking.istio.io/v1beta1- 说明 :指定使用的 Istio API 版本。
v1beta1是当前稳定且功能丰富的版本。
- 说明 :指定使用的 Istio API 版本。
-
kind: VirtualService- 说明:声明此资源类型为 Virtual Service。
-
metadataname: reviews-vs- 说明:Virtual Service 资源的唯一标识名。
namespace: default- 说明:资源部署的命名空间,必须与目标服务在同一命名空间或能被其访问。
-
spechosts: - reviews- 说明 :一个字符串列表,指定此 Virtual Service 规则所应用的一个或多个服务。这里的
reviews是 Kubernetes Service 的名称。也可以是带命名空间的完全限定域名(FQDN),如reviews.default.svc.cluster.local。客户端向这些hosts发起的请求将受本规则约束。
- 说明 :一个字符串列表,指定此 Virtual Service 规则所应用的一个或多个服务。这里的
http:- 说明:用于配置 HTTP/1.1, HTTP/2, 以及 gRPC 流量的路由规则。这是一个数组,可以定义多条规则,Istio 会按顺序评估。
- match:- 说明 :定义流量匹配条件。
match块是数组,每个元素定义一组"与"条件。一个http块下可以有多个match块,按定义顺序匹配,第一个匹配的规则生效。 - headers:- 说明:匹配 HTTP 请求头。
end-user:- 说明:要匹配的请求头名称。
exact: jason- 说明 :匹配模式为"精确匹配",值必须完全等于
jason。其他模式还有prefix(前缀)、regex(正则)等。
- 说明 :匹配模式为"精确匹配",值必须完全等于
- 说明 :定义流量匹配条件。
route:- 说明 :定义匹配到的流量将被路由到哪里。
destination是必填项。 - destination:- 说明:路由目标定义。
host: reviews- 说明 :目标服务,与
spec.hosts中的条目对应,但也可以是网格外的服务(通过 Service Entry 定义)。
- 说明 :目标服务,与
subset: v2- 说明 :指向 Destination Rule 中定义的子集名称(如
v2)。子集通常代表服务的某个特定版本(通过标签选择器标识)。如果不需要区分版本,可以省略此字段。
- 说明 :指向 Destination Rule 中定义的子集名称(如
- 说明 :定义匹配到的流量将被路由到哪里。
- route:(第二个路由规则,无match)- 说明 :这是一个"默认"或"兜底"路由规则,因为它没有
match条件,会捕获所有未被前面规则匹配的流量。 - destination: ... weight: 80- 说明 :定义了一个权重目的地。
weight字段指定了流向该目的地的流量百分比(80%)。
- 说明 :定义了一个权重目的地。
- destination: ... weight: 20- 说明:第二个权重目的地,接收 20% 的流量。所有权重之和应为 100。
- 说明 :这是一个"默认"或"兜底"路由规则,因为它没有
3. 核心功能与配置示例
3.1 基于权重的流量切分(金丝雀发布)
这是最常见的场景,将流量按比例分给不同版本的服务。
yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: productpage
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
weight: 90 # 90% 流量流向稳定版 v1
- destination:
host: productpage
subset: v2
weight: 10 # 10% 流量流向新版本 v2 进行测试
说明 :此配置将所有访问 productpage 服务的流量,90% 路由到 v1 子集,10% 路由到 v2 子集。配合 Destination Rule 定义 v1 和 v2 对应的 Pod 标签。
3.2 基于请求内容的路由(A/B测试)
根据请求的路径、头信息等将流量导向不同版本。
yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match: # 规则1:匹配特定用户
- headers:
cookie:
regex: "^(.*?;)?(user=test-user)(;.*)?$"
route:
- destination:
host: reviews
subset: v2 # 测试用户看到 v2 版本
- match: # 规则2:匹配特定 API 路径
- uri:
prefix: /api/v2/
route:
- destination:
host: reviews
subset: v2
- route: # 规则3:默认路由给所有其他用户
- destination:
host: reviews
subset: v1
说明 :此配置实现了复杂的路由逻辑。携带特定 cookie 的用户或访问 /api/v2/ 路径的请求会被路由到 v2 版本,其他所有请求则路由到 v1 版本。
3.3 故障注入
主动注入延迟或中断,测试应用的容错能力。
yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- fault: # 故障注入配置
delay:
percentage: # 注入比例
value: 10.0
fixedDelay: 5s # 固定延迟 5 秒
route:
- destination:
host: ratings
subset: v1
说明 :此配置向 ratings 服务的 v1 版本注入故障,对 10% 的请求添加 5 秒的固定延迟。fault 块还可以配置 abort 来模拟 HTTP 错误。
3.4 超时与重试
配置服务的调用超时和重试策略,提升系统韧性。
yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: checkout
spec:
hosts:
- checkout
http:
- route:
- destination:
host: checkout
timeout: 3s # 请求超时时间设为 3 秒
retries: # 重试策略
attempts: 3 # 最多重试 3 次
perTryTimeout: 2s # 每次重试的超时时间
retryOn: connect-failure,refused-stream,5xx # 在哪些条件下重试
说明 :此配置为 checkout 服务设置了 3 秒的总超时。如果请求失败(如连接失败、5xx 错误),会最多重试 3 次,每次重试超时为 2 秒。
3.5 流量镜像(影子流量)
将实时流量的副本发送到另一个服务,用于测试或监控,不影响主流程。
yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- httpbin
http:
- route:
- destination:
host: httpbin
subset: v1
weight: 100
mirror: # 流量镜像目标
host: httpbin
subset: v2
mirrorPercentage: # 镜像流量百分比(新版本字段)
value: 50.0
说明 :此配置将所有流量路由到 httpbin 的 v1 版本,但同时将其中 50% 的流量镜像(复制一份)发送到 v2 版本。镜像请求的响应会被忽略。
4. 与 Destination Rule 的关系
Virtual Service 负责"路由决策",而 Destination Rule 负责"到达后策略"。两者必须配合使用才能实现完整的流量管理。
典型工作流程:
-
Destination Rule :定义服务的子集和策略。
yamlapiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: reviews-dr spec: host: reviews subsets: - name: v1 # 子集名称,被 Virtual Service 引用 labels: version: v1 # 匹配 Pod 的标签 - name: v2 labels: version: v2 trafficPolicy: # 负载均衡、连接池等策略 loadBalancer: simple: ROUND_ROBIN -
Virtual Service :引用这些子集,并制定路由规则。
yamlapiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: reviews-vs spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 # 引用 Destination Rule 中定义的子集 weight: 50 - destination: host: reviews subset: v2 weight: 50
5. 部署与验证
-
部署配置:
bashkubectl apply -f destination-rule.yaml kubectl apply -f virtual-service.yaml -
验证配置:
bash# 查看 Virtual Service kubectl get virtualservice kubectl describe virtualservice <vs-name> # 查看生效的规则 istioctl proxy-config routes <pod-name> -n <namespace> -
测试流量 :使用
curl或浏览器访问服务,并通过修改请求头、权重等观察路由是否符合预期。
6. 最佳实践与注意事项
- 明确
hosts字段 :确保spec.hosts中的服务名在网格内可正确解析。 - 规则顺序 :
http.match规则按顺序评估,应将最具体的规则放在前面。 - 默认路由 :总是提供一个没有
match条件的默认路由作为兜底,避免流量被意外丢弃。 - 与 Gateway 集成:Virtual Service 可以绑定到 Gateway,用于管理入口流量。
- 性能影响:过于复杂的匹配规则(如大量正则表达式)可能会对性能产生轻微影响。
- 优先级 :同一个 host 被多个 Virtual Service 定义时,会按创建时间顺序合并,后创建的规则优先级更高(
kubectl的apply顺序)。
通过灵活组合 Virtual Service 的各种功能,你可以轻松实现灰度发布、故障演练、多版本并行测试等复杂的微服务流量治理场景。