服务网格 12:Gateway API 如何描述网格内路由
HTTPRoute 没有 Gateway,也能作用于 Service 吗
前提是实现支持 Gateway API 的网格路由能力(GAMMA),不是“集群安装了 HTTPRoute CRD”就自动生效。第 06 篇的五层证据仍适用:提交 HTTPRoute、检查控制器接受与关联状态、查代理当前 route/cluster、观察真实请求经过哪条代理路径、核对库存服务的版本和请求 ID。控制面不处于普通 orders → inventory 请求的转发链上。
与入口流量附着到 Gateway 不同,网格中的 HTTPRoute 通过 parentRefs 指向 Kubernetes Service,例如 inventory 的端口 8080。parentRefs 回答“哪条 Service 流量可受此规则影响”,backendRefs 回答“命中后转发到哪个目标”;前者不是后端 Pod 列表,后者也不表示调用者身份。通过目标应用日志的同一请求 ID 才能核对后端版本,不能只看对象 Accepted=True。
放在哪个命名空间,改变了谁受影响
Gateway API 网格概览将与目标 Service 同命名空间的 Route 称为生产者 Route:它由 Service 提供方定义,对访问该 Service 的客户端生效。位于其他命名空间的 Route 是消费者 Route,只作用于该 Route 所在命名空间的客户端。图中 service-mesh-lab 内的规则拟约束所有对库存服务的调用;mesh-clients 内的规则只针对该命名空间发往库存服务的调用。先确认具体实现支持这两类 Route,别把“跨命名空间能创建 Route”误读成“所有来源都经过它”。
1 | |
例如将 header x-canary: yes 的请求路由到 inventory-v2:先确保 v2 Service、端口和后端实例存在,再提交指向 inventory Service 的 Route;同时保留没有该 header 的 v1 基线。同一 Service 同一命名空间内的多条 Route 会依 Route 合并与优先级规则处理,不能假定“后一条 YAML 自动覆盖前一条”。ReferenceGrant 涉及跨命名空间后端引用时还需单独审查;不要把消费方 Route 的跨命名空间 parentRefs 与跨命名空间 backendRefs 混为一谈。
分开运行生产者与消费者规则
本工程固定 Gateway API 1.3.0 CRD 与 Istio 1.27.0 候选实现。sidecar 安装入口已包含 CRD;功能是否被实现接受仍以 Route 状态与数据面请求判断。从 examples/service-mesh/ 执行 SM_CONTEXT=kind-service-mesh-sidecar bash scripts/cluster-case.sh 12,前提是第 06、10 篇的 VirtualService 已清理。
生产者清单在 deploy/kubernetes/inventory-httproute.yaml,Route 位于 service-mesh-lab,与 parent Service 同 namespace;parentRefs 的 group 是空字符串、kind 是 Service、name 是 inventory、port 是 8080。带 x-canary: yes 的请求转给 inventory-v2:8080,其余转给 inventory-v1:8080。脚本采集 status.parents、orders 代理资源、canary/default 响应和 v2 handler ID。
消费者阶段先确认 mesh-clients namespace 不存在,避免覆盖已有工作负载;再使用 mainline/12/consumer.yaml,其中包含带注入标签的 mesh-clients namespace、一个调用者 Deployment、指向跨 namespace inventory 的 HTTPRoute,以及允许该 Route 引用 inventory-v2 后端的 ReferenceGrant。此规则将 mesh-clients 的调用导向 v2;service-mesh-lab 的调用不应仅因这条消费者规则被强制导向 v2。普通 Service 原本就可能选中 v2,因此不能用外部来源偶然一次 v2 响应证明作用域越界。
1 | |
生产者和消费者先分阶段运行。官方网格概览仍将两类规则的相互关系标为持续完善的部分,不应假定“消费者一定覆盖生产者”。跨 namespace parentRefs 的附着语义与 backendRefs 的引用许可也不同,ReferenceGrant 在这里授予的是后端 Service 引用。
负例把消费者 parent 名改成不存在的 missing-inventory,保存带 observedGeneration 的 conditions 和代理路由,再重复请求。不能要求业务必失败:失去 Route 后普通 Service 仍可能可达;要判定的是该 Route 不再按原附着对象生效。恢复重新 apply consumer.yaml,等待状态与 v2 请求同时恢复。结束删除本次清单,保留原 namespace 外其他资源。当前生产者/消费者实际集群验证均 NOT_RUN。
[PATTERN] 角色化配置把服务提供者的默认行为与调用方范围分开;API 对象所在 namespace 是语义的一部分。
| 原则 | 检验点 |
|---|---|
| 附着与目标分离 | parentRefs 与 backendRefs 分别核对 |
| 权限最小化 | ReferenceGrant 仅允许指定后端名称 |
| 失效规则不等于失效服务 | 错 parent 检查状态,不猜固定 HTTP 码 |
练习与参考解答
- HTTPRoute 状态显示
Accepted=True,但 v2 没有任何请求,能认定负载均衡有错吗?参考解答:不能。先检查来源是否在作用范围、请求 header 是否匹配、backendRefs服务/端口与 endpoints 是否有效,再看代理当前路由和同一请求 ID 的库存日志。Accepted 不能证明请求实际经过该规则。 - 保留规则内容不变,把生产者 Route 移到
mesh-clients命名空间;哪些请求应重新核验?参考解答:此时它是消费者 Route,重点对比该来源和其他来源(如service-mesh-lab)访问同一 Service 的结果;如仍有生产者 Route,应检查两者优先级与合并行为。控制器对这一组合是否支持要看选定版本,不可先填预期状态码。
官方参考与系列导航
- Gateway API Service Mesh overview:Service 附着、生产者/消费者作用域及合并边界。
- Gateway API GAMMA 与 实现列表:功能阶段与实现支持需对应部署版本核对。
- Gateway API HTTPRoute:parentRefs、backendRefs、状态与匹配字段;真实控制器兼容性仍待验证。
系列导航:00 无网格基线 → 11 连接与负载均衡 → 12 Gateway API 网格路由(本文)→ 13 超时预算。

