跳至内容

HTTP 流量拆分

HTTPRoute 资源 允许您指定权重以在不同的后端之间分配流量。这在发布期间拆分流量、金丝雀测试更改或紧急情况时非常有用。HTTPRoutespec.rules.backendRefs 接受路由规则将向其发送流量的后端列表。这些后端之间的相对权重定义了它们之间的流量拆分。以下 YAML 代码片段展示了如何将两个服务列为单个路由规则的后端。此路由规则将流量 90% 分配到 foo-v1,10% 分配到 foo-v2

Traffic splitting

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: simple-split
spec:
  rules:
  - backendRefs:
    - name: foo-v1
      port: 8080
      weight: 90
    - name: foo-v2
      port: 8080
      weight: 10

weight 表示流量的按比例拆分(而不是百分比),因此单个路由规则内所有权重的总和是所有后端的分母。weight 是一个可选参数,如果未指定,则默认为 1。如果仅为路由规则指定了一个后端,它隐式地接收 100% 的流量,无论指定了哪个权重(如果有)。

指南

本指南展示了两个版本的服务的部署。流量拆分用于管理从 v1 到 v2 的流量逐渐拆分。

此示例假设已部署以下网关

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: prod-web
spec:
  gatewayClassName: example
  listeners:
  - protocol: HTTP
    port: 80
    name: prod-web-gw
    allowedRoutes:
      namespaces:
        from: Same

金丝雀流量发布

首先,可能只有一个版本的 Service 为 foo.example.com 提供生产用户流量。以下 HTTPRoute 未为 foo-v1foo-v2 指定任何 weight,因此它们将隐式地接收由各自路由规则匹配的 100% 的流量。金丝雀路由规则用于(匹配标头 traffic=test)在将任何生产用户流量拆分到 foo-v2 之前发送合成测试流量。路由优先级 确保所有具有匹配主机和标头的流量(最具体的匹配)都将发送到 foo-v2

Traffic splitting

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: foo-route
  labels:
    gateway: prod-web-gw
spec:
  hostnames:
  - foo.example.com
  rules:
  - backendRefs:
    - name: foo-v1
      port: 8080
  - matches:
    - headers:
      - name: traffic
        value: test
    backendRefs:
    - name: foo-v2
      port: 8080

蓝绿流量发布

在内部测试验证了来自 foo-v2 的成功响应后,最好将一小部分流量转移到新服务中,以便进行逐渐和更真实的测试。以下 HTTPRoute 添加了 foo-v2 作为后端以及权重。权重总计为 100,因此 foo-v1 接收 90/100=90% 的流量,foo-v2 接收 10/100=10% 的流量。

Traffic splitting

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: foo-route
  labels:
    gateway: prod-web-gw
spec:
  hostnames:
  - foo.example.com
  rules:
  - backendRefs:
    - name: foo-v1
      port: 8080
      weight: 90
    - name: foo-v2
      port: 8080
      weight: 10

完成发布

最后,如果所有信号都为正,则需要将流量完全转移到 foo-v2 并完成发布。foo-v1 的权重设置为 0,以便配置为接受零流量。

Traffic splitting

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: foo-route
  labels:
    gateway: prod-web-gw
spec:
  hostnames:
  - foo.example.com
  rules:
  - backendRefs:
    - name: foo-v1
      port: 8080
      weight: 0
    - name: foo-v2
      port: 8080
      weight: 1

此时,100% 的流量正在路由到 foo-v2,发布已完成。如果由于任何原因,foo-v2 出现错误,可以更新权重以快速将流量转移回 foo-v1。一旦发布被认为是最终的,v1 就可以完全退役。