3. 多版本路由原理:基于权重、Header、QueryParam 的路由分发机制
在 Gateway API 中,多版本路由的核心是将流量按照预定义的规则分发到不同的后端服务(Service)版本。这种分发机制主要依赖 HTTPRoute 资源中的 matches 和 backendRefs 字段。通过组合不同的匹配条件与权重分配,可以实现灰度发布、A/B 测试、蓝绿部署等高级流量管理策略。
3.1 核心概念:匹配器(Matcher)与后端引用(BackendRef)
一个 HTTPRoute 规则由两部分组成:
- 匹配器(Matches):定义流量进入规则的条件,支持路径(Path)、Header、QueryParam、方法(Method)等。
- 后端引用(BackendRefs):定义匹配成功后流量转发的目标 Service 及权重。
| 匹配类型 | 匹配字段 | 典型用途 | 示例 |
|---|---|---|---|
| 路径(Path) | path |
按 URL 路径分流,如 /v2 指向新版本 |
path.type: PathPrefix, path.value: "/api/v2" |
| Header | headers |
按 HTTP 请求头分流,如 X-Canary: true |
headers[0].name: "X-Version", headers[0].value: "beta" |
| QueryParam | queryParams |
按 URL 查询参数分流,如 ?test=1 |
queryParams[0].name: "test", queryParams[0].value: "1" |
| 方法(Method) | method |
按 HTTP 方法分流,如只让 GET 请求访问新版本 | method: "GET" |
关键原则: 当同一个 HTTPRoute 规则中存在多个匹配条件时,它们之间是 AND 关系(必须全部满足)。不同规则之间是 OR 关系(按顺序匹配,命中即停止)。
3.2 基于权重的路由分发
权重路由是最常用的灰度发布手段。它允许将流量按百分比切分到多个后端版本,无需修改客户端代码。
工作原理: 在 backendRefs 中为每个后端 Service 设置 weight 字段。Gateway 控制器会根据权重比例随机分发匹配到的请求。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: canary-route
spec:
parentRefs:
- name: my-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: my-app-v1
port: 80
weight: 90
- name: my-app-v2
port: 80
weight: 10
权重计算规则:
- 每个后端的实际流量比例 = 该后端权重 / 所有后端权重之和。
- 权重为 0 表示不接收流量(可用于优雅下线)。
- 权重总和不必为 100,Gateway 会自动归一化。
实战建议: 在集群升级演练中,建议初始权重设置为 v1:100 / v2:0,确认新版本 Pod 就绪后,逐步调整权重(如 90:10 → 50:50 → 0:100),实现平滑切换。
3.3 基于 Header 的路由分发
Header 路由允许根据请求头中的特定键值对进行流量分发。这种方式非常适合 A/B 测试,例如让内部测试人员或特定用户群体访问新版本。
匹配规则:
type: Exact:精确匹配 Header 值。type: RegularExpression:正则表达式匹配 Header 值。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-based-route
spec:
parentRefs:
- name: my-gateway
rules:
- matches:
- headers:
- name: "X-Canary"
value: "true"
backendRefs:
- name: my-app-v2
port: 80
weight: 100
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: my-app-v1
port: 80
weight: 100
注意: Header 匹配是大小写敏感的。建议在客户端和服务端统一使用小写 Header 名称。Gateway API 规范要求实现必须支持大小写不敏感的匹配,但不同实现的行为可能略有差异。
3.4 基于 QueryParam 的路由分发
QueryParam 路由通过 URL 中的查询参数(如 ?version=v2)来分流。这种方式对客户端侵入性小,适合临时调试或功能验证。
匹配规则:
type: Exact:精确匹配参数值。type: RegularExpression:正则表达式匹配参数值。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: query-based-route
spec:
parentRefs:
- name: my-gateway
rules:
- matches:
- queryParams:
- name: "version"
value: "v2"
backendRefs:
- name: my-app-v2
port: 80
weight: 100
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: my-app-v1
port: 80
weight: 100
3.5 多条件组合路由
在实际演练中,经常需要组合多种匹配条件来实现精细化的流量控制。例如:只让携带特定 Header 且访问特定路径的请求进入新版本。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: combined-route
spec:
parentRefs:
- name: my-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api/v2
headers:
- name: "X-Env"
value: "staging"
queryParams:
- name: "debug"
value: "true"
backendRefs:
- name: my-app-v2
port: 80
weight: 100
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: my-app-v1
port: 80
weight: 100
3.6 路由优先级与匹配顺序
当多个规则同时匹配时,Gateway API 遵循以下优先级原则:
- 精确匹配优先于前缀匹配:
Exact类型的路径匹配优先级高于PathPrefix。 - 规则顺序:在同一个 HTTPRoute 中,规则按定义顺序从上到下匹配,命中即停止。
- 条件数量:匹配条件更多的规则优先级更高(更具体)。
| 优先级 | 匹配类型 | 示例 |
|---|---|---|
| 最高 | 精确路径 + Header + QueryParam | /api/v2 + X-Version: beta + ?test=1 |
| 高 | 精确路径 + Header | /api/v2 + X-Version: beta |
| 中 | 精确路径 | /api/v2 |
| 低 | 前缀路径 | /api |
演练要点: 在集群升级后的多版本路由切换中,建议先使用 Header 或 QueryParam 路由进行小范围验证,确认新版本稳定后再逐步增加权重,最后切换到基于路径的默认路由。这种渐进式策略可以最大程度降低升级风险。