Istio 服务网格流量管理
yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: reviews spec: hosts:
- reviews http:
- match:
- uri: prefix: "/" route:
- destination: host: reviews subset: v1 weight: 80
- destination: host: reviews subset: v2 weight: 20
在这个例子中,需要配合 DestinationRule 来定义 `v1` 和 `v2` 子集。
### DestinationRule(目标规则)
DestinationRule 定义了流量到达某个服务后,针对不同版本的子集(subset)的策略,比如负载均衡算法、连接池大小、熔断阈值、TLS 模式等。
**关键字段:**
- `host`:目标服务,通常与 VirtualService 中的 host 相同。
- `subsets`:基于标签(labels)定义的版本分组。每一个 subset 对应一组具有相同标签的 Pod。
- `trafficPolicy`:全局或针对特定子集的流量策略(负载均衡、连接池、异常检测等)。
**示例:定义 reviews 服务的两个子集,并指定负载均衡策略**
```yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: RANDOM
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 10
http2MaxRequests: 100
maxRequestsPerConnection: 2
outlierDetection:
consecutiveErrors: 5
interval: 30s
baseEjectionTime: 60s
当 VirtualService 中引用了 subset: v1 时,请求会被转发到携带 version: v1 标签的 Pod 上。
Gateway(网关)
Gateway 用于管理进出服务网格的边界流量,通常对应 Ingress 流量(从外部访问网格内部),但也可用于 Egress。
它运行在网格边缘的 Envoy 代理上,用于配置暴露的端口、协议和 TLS 设置。真正的流量路由规则仍然写在 VirtualService 中,并通过 gateways 字段绑定。
Gateway + VirtualService 结合实现外部入口:
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: my-gateway
spec:
selector:
istio: ingressgateway # 使用默认 Ingress Gateway 的 Pod 标签
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "example.com"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: my-app-external
spec:
hosts:
- "example.com"
gateways:
- my-gateway
http:
- route:
- destination:
host: my-service.default.svc.cluster.local
port:
number: 8080
ServiceEntry(服务入口)
Istio 通过内部服务注册表感知网格内部服务,如果需要访问网格外部服务(如外部 API、数据库),可以使用 ServiceEntry 将外部服务注册进来,以便对出流量进行治理。
这在使用 External API 并需要为其配置超时、重试规则时非常有用,也是很多初学者容易忽略的地方。
高级流量管理场景
基于请求内容的路由(内容路由)
你可以根据 HTTP Header、URI、Query Params 等匹配规则将请求路由到不同版本。最常见的场景是 A/B 测试或基于用户类型的分流。
http:
- match:
- headers:
end-user:
exact: "internal"
route:
- destination:
host: reviews
subset: v3
- route:
- destination:
host: reviews
subset: v1
上述规则表示:如果请求头 end-user 的值为 internal,则将流量发送到 v3 版本,否则全部默认进入 v1。
流量镜像(Traffic Mirroring)
流量镜像(又称流量影子)能够把实时请求复制一份发送到另一个服务版本,但不影响主请求的响应。常用于将生产流量导入测试版本来验证新功能。
在 VirtualService 中使用 mirror 字段:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 100
mirror:
host: reviews
subset: v2
这里所有请求 100% 发往 v1,同时会镜像一份到 v2(v2 的响应会被丢弃)。
故障注入(Fault Injection)
Istio 可以主动注入延迟(delay)或中断(abort)来测试服务的弹性。无需修改代码,只在 VirtualService 中配置即可。
注入 5 秒延迟给 10% 的请求:
http:
- fault:
delay:
percentage:
value: 10
fixedDelay: 5s
route:
- destination:
host: reviews
subset: v1
注入 HTTP 503 错误:
- fault:
abort:
percentage:
value: 20
httpStatus: 503
超时、重试与熔断
请求超时(Timeout)
在 VirtualService 的路由规则中指定 HTTP 请求的超时时间(默认 15 秒)。超时发生后,Envoy 会返回 504 Gateway Timeout,可以用来防止下游服务慢响应耗尽资源。
http:
- timeout: 2s
route:
- destination:
host: reviews
subset: v1
重试(Retries)
当目标服务返回特定错误时,Envoy 可以自动发起重试。配置重试次数、重试条件以及每次重试的超时时间。
http:
- retries:
attempts: 3
perTryTimeout: 1s
retryOn: "connect-failure,refused-stream,503"
route:
- destination:
host: reviews
subset: v1
retryOn 可以使用 Istio 支持的策略条件组合。
熔断(Circuit Breaking)
熔断在 DestinationRule 中配置,通过连接池和异常检测参数来限制并发连接或请求数,并在一段时间内将不健康的主机剔除。
上面 DestinationRule 示例中的 connectionPool 和 outlierDetection 就是典型的熔断配置。异常检测(outlier detection)会根据连续错误数触发暂时移出主机池,类似于 Hystrix 的断路器模式。
常用异常检测参数:
consecutive5xxErrors:连续 5xx 错误次数interval:扫描间隔baseEjectionTime:最小驱逐时间maxEjectionPercent:最大可驱逐主机百分比
实际场景演示:金丝雀发布
假设我们有一个 productpage 服务的新版本 v2 需要逐步上线,流程如下:
- 为
productpage创建 DestinationRule,定义v1和v2两个 subset。 - 首先通过 VirtualService 将所有流量指向 v1。
- 修改 VirtualService,将 5% 流量转移到 v2,观察指标。
- 逐步增加权重直至 100%,完成发布。
- 如果发现问题,立即将权重恢复至 v1,完成回滚。
对应的 VirtualService 逐步修改:
# 仅 v1
http:
- route:
- destination:
host: productpage
subset: v1
weight: 100
# 5% 灰度
http:
- route:
- destination:
host: productpage
subset: v1
weight: 95
- destination:
host: productpage
subset: v2
weight: 5