GRPCRoute¶
自 v1.1.0 以来为标准通道
GRPCRoute
资源是 GA,并且自 v1.1.0
以来一直是标准通道的一部分。有关发布通道的更多信息,请参阅我们的 版本控制指南.
GRPCRoute 是网关 API 类型,用于指定从网关侦听器到 API 对象(即服务)的 gRPC 请求的路由行为。
背景¶
虽然可以使用 HTTPRoutes
或通过自定义的、树外 CRD 来路由 gRPC,但从长远来看,这会导致生态系统碎片化。
gRPC 是一个 在整个行业广泛采用的流行 RPC 框架。该协议在 Kubernetes 项目本身中被广泛使用,作为许多接口的基础,包括
鉴于 gRPC 在应用程序层网络空间以及 Kubernetes 项目中的重要性,决定不允许多余的生态系统碎片化。
封装的网络协议¶
通常,当可以在较低级别路由封装协议时,当满足以下标准时,在较高级别引入路由资源是可以接受的
- 如果强制在较低级别进行路由,封装协议的用户将错过其生态系统中的重要传统功能。
- 如果强制在较低级别进行路由,封装协议的用户将体验到用户体验下降。
- 封装协议拥有大量的用户群,特别是在 Kubernetes 社区中。
gRPC 满足所有这些标准,因此决定在网关 API 中包含 GRPCRoute
。
交叉服务¶
支持 GRPCRoute 的实现必须在 GRPCRoute
和 HTTPRoute
之间强制实施主机名的唯一性。如果类型为 HTTPRoute
或 GRPCRoute
的路由 (A) 附加到侦听器,并且该侦听器已经附加了另一种类型 (B) 的另一个路由,并且 A 和 B 的主机名的交集非空,则实现必须拒绝路由 A。也就是说,实现必须在相应的 RouteParentStatus 中引发状态为“False”的“已接受”条件。
通常,建议为 gRPC 和非 gRPC HTTP 流量使用单独的主机名。这与 gRPC 社区的标准做法一致。但是,如果必须在同一主机名上提供 HTTP 和 gRPC,唯一的区别是 URI,则用户应使用 HTTPRoute
资源来提供 gRPC 和 HTTP。这将以 GRPCRoute
资源的改进用户体验为代价。
规范¶
GRPCRoute 的规范包括
- ParentRefs- 定义此路由想要附加到的网关。
- Hostnames(可选)- 定义用于匹配 gRPC 请求的 Host 标头的主机名列表。
- Rules- 定义用于对匹配的 gRPC 请求执行操作的规则列表。每个规则都包含 匹配项、过滤器(可选)和 backendRefs(可选)字段。
以下示例说明将所有流量发送到一个服务的 GRPCRoute:
附加到网关¶
每个路由都包含一种方式来引用它想要附加到的父资源。在大多数情况下,将是网关,但这里有一些灵活性可以让实现支持其他类型的父资源。
以下示例显示了路由如何附加到 acme-lb
网关
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpcroute-example
spec:
parentRefs:
- name: acme-lb
请注意,目标网关需要允许来自路由命名空间的 GRPCRoutes 附加,才能使附加成功。
主机名¶
主机名定义用于匹配 gRPC 请求的 Host 标头的主机名列表。当匹配发生时,将选择 GRPCRoute 根据规则和过滤器(可选)执行请求路由。主机名是网络主机的完全限定域名,如 RFC 3986 中所定义。请注意以下与 RFC 中定义的 URI 的“主机”部分的偏差
- 不允许使用 IP 地址。
- 不尊重 : 分隔符,因为不允许使用端口。
在评估 GRPCRoute 规则之前,将传入请求与主机名进行匹配。如果未指定主机名,则根据 GRPCRoute 规则和过滤器(可选)对流量进行路由。
以下示例定义了主机名“my.example.com”
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpcroute-example
spec:
hostnames:
- my.example.com
规则¶
规则定义用于根据条件匹配 gRPC 请求的语义,可选地执行其他处理步骤,并可选地将请求转发到 API 对象。
匹配项¶
匹配项定义用于匹配 gRPC 请求的条件。每个匹配项都是独立的,即如果满足任何单个匹配项,则将匹配此规则。
以以下匹配项配置为例
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
...
matches:
- method:
service: com.example.User
method: Login
headers:
values:
version: "2"
- method:
service: com.example.v2.User
method: Login
对于要匹配此规则的请求,它必须满足以下任一条件
com.example.User.Login
方法 **并且** 包含标头“version: 2”com.example.v2.User.Login
方法。
如果没有指定匹配项,则默认情况下匹配每个 gRPC 请求。
过滤器(可选)¶
过滤器定义必须在请求或响应生命周期中完成的处理步骤。过滤器充当扩展点,以表达可以在网关实现中执行的其他处理。一些示例包括请求或响应修改、实施身份验证策略、速率限制和流量整形。
以下示例将标头“my-header: foo”添加到 Host 标头为“my.filter.com”的 gRPC 请求。请注意,GRPCRoute 使用 HTTPRoute 过滤器来实现与 HTTPRoute 功能相同的特性,例如本示例。
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpc-filter-1
spec:
hostnames:
- my.filter.com
rules:
- filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: my-header
value: foo
backendRefs:
- name: my-filter-svc1
weight: 1
port: 50051
API 一致性是根据过滤器类型定义的。当前未指定多个行为顺序的影响。这可能会根据 Alpha 阶段的反馈在将来发生变化。
一致性级别由过滤器类型定义
- 所有支持 GRPCRoute 的实现 **必须** 支持所有“核心”过滤器。
- 鼓励实现者支持“扩展”过滤器。
- “实现特定”过滤器在不同实现之间没有 API 保证。
多次指定核心过滤器具有未定义或自定义的符合性。
如果实现无法支持某些过滤器的组合,则必须明确记录该限制。在指定不兼容或不支持的过滤器并导致Accepted
条件设置为状态False
的情况下,实现可以使用IncompatibleFilters
原因来指定此配置错误。
BackendRefs(可选)¶
BackendRefs 定义了应将匹配请求发送到的 API 对象。如果未指定,则规则不执行转发。如果未指定且未指定会导致发送响应的过滤器,则返回UNIMPLEMENTED
错误代码。
以下示例将User.Login
方法的 gRPC 请求转发到端口50051
上的“my-service1”服务,并将带有magic: foo
头的Things.DoThing
方法的 gRPC 请求转发到端口50051
上的“my-service2”服务。
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: example
spec:
controllerName: acme.io/gateway-controller
parametersRef:
name: example
group: acme.io
kind: Parameters
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
spec:
gatewayClassName: example
listeners: # Use GatewayClass defaults for listener definition.
- name: https
protocol: HTTPS
port: 50051
tls:
certificateRefs:
- kind: Secret
group: ""
name: example-com-cert
---
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpc-app-1
spec:
parentRefs:
- name: my-gateway
hostnames:
- "example.com"
rules:
- matches:
- method:
service: com.example.User
method: Login
backendRefs:
- name: my-service1
port: 50051
- matches:
- headers:
- type: Exact
name: magic
value: foo
method:
service: com.example.Things
method: DoThing
backendRefs:
- name: my-service2
port: 50051
以下示例使用weight
字段将 90% 的 gRPC 请求从foo.example.com
转发到“foo-v1”服务,并将另外 10% 的请求转发到“foo-v2”服务。
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
name: foo-route
labels:
gateway: prod-web-gw
spec:
hostnames:
- foo.example.com
rules:
- backendRefs:
- name: foo-v1
port: 50051
weight: 90
- name: foo-v2
port: 50051
weight: 10
有关weight
和其他字段的更多详细信息,请参考backendRef API 文档。
状态¶
Status 定义了 GRPCRoute 的观察状态。
RouteStatus¶
RouteStatus 定义了所有路由类型都需要观察到的状态。
父级¶
Parent 定义了与 GRPCRoute 关联的网关(或其他父资源)列表,以及 GRPCRoute 相对于每个网关的状态。当 GRPCRoute 在 parentRefs 中添加对网关的引用时,管理网关的控制器应在控制器第一次看到路由时将条目添加到此列表中,并在修改路由时根据需要更新条目。
示例¶
以下示例表明 GRPCRoute“grpc-example”已被“gw-example-ns”命名空间中的网关“gw-example”接受。
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: grpc-example
...
status:
parents:
- parentRefs:
name: gw-example
namespace: gw-example-ns
conditions:
- type: Accepted
status: "True"
合并¶
多个 GRPCRoute 可以附加到单个网关资源。重要的是,每个请求只能匹配一条路由规则。有关冲突解决如何应用于合并的更多信息,请参考API 规范。