gRPC 路由
原文:https://gateway-api.sigs.k8s.io/guides/user-guides/grpc-routing/
GRPCRoute 资源 让你可以匹配 gRPC 流量并把它转发到 Kubernetes 后端。本指南展示 GRPCRoute 如何基于 host、header、service 和 method 字段对流量进行匹配,并把它转发到不同的 Kubernetes Service。
下图描述了横跨三个不同 Service 的流量流:
- 发往
foo.example.com的、调用com.Example.Login方法的流量 → 转发到foo-svc。 - 发往
bar.example.com且带env: canaryHeader 的流量 → 对所有 service 和 method 都转发到bar-svc-canary。 - 发往
bar.example.com且不带该 Header 的流量 → 对所有 service 和 method 都转发到bar-svc。
虚线显示了为配置这套路由行为而部署的 Gateway 资源。两条 GRPCRoute 资源在同一 prod Gateway 上创建路由规则。这体现了多条 Route 可以绑定到同一个 Gateway——只要 Route 之间不冲突,就能在 Gateway 上合并。GRPCRoute 遵循同样的 Route 合并语义。详见 HTTPRoute 文档。
要接收来自 Gateway 的流量,GRPCRoute 资源必须配置 ParentRefs,指明它应该被附加到哪些父 Gateway 上。下面的示例展示了如何把 Gateway 与 GRPCRoute 组合起来,为 gRPC 流量提供服务:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
spec:
gatewayClassName: example-gateway-class
listeners:
- name: grpc
protocol: HTTPS
port: 50051
tls:
certificateRefs:
- kind: Secret
group: ""
name: example-com-cert
---
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: example-route
spec:
parentRefs:
- name: example-gateway
hostnames:
- "example.com"
rules:
- backendRefs:
- name: example-svc
port: 50051一个 GRPCRoute 可以匹配一组 hostnames。这些主机名会在 GRPCRoute 内部其他任何匹配之前优先匹配。由于 foo.example.com 和 bar.example.com 是主机名不同、路由需求不同的两个主机,所以它们各自被部署为独立的 GRPCRoute —— foo-route 和 bar-route。
下面的 foo-route 会匹配 foo.example.com 的所有流量,并应用其路由规则把流量转发到正确的后端。由于只指定了一个匹配项,所以只有对 foo.example.com 调用 com.example.User.Login 方法的请求才会被转发。任何调用其它方法的 RPC 都不会被这条 Route 匹配。
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: foo-route
spec:
parentRefs:
- name: example-gateway
hostnames:
- "foo.example.com"
rules:
- matches:
- method:
service: com.example
method: Login
backendRefs:
- name: foo-svc
port: 50051类似地,bar-route GRPCRoute 匹配 bar.example.com 的 RPC。该主机名下的所有流量都会被其路由规则评估——最具体的匹配将优先生效。也就是说:任何带 env: canary Header 的流量会被转发到 bar-svc-canary;如果 Header 缺失或值不是 canary,则会被转发到 bar-svc。
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: bar-route
spec:
parentRefs:
- name: example-gateway
hostnames:
- "bar.example.com"
rules:
- matches:
- headers:
- type: Exact
name: env
value: canary
backendRefs:
- name: bar-svc-canary
port: 50051
- backendRefs:
- name: bar-svc
port: 50051gRPC 反射(Reflection)
gRPC 反射 是使用 grpcurl 这类交互式客户端的前提——它能让你不必在本地文件系统上持有目标服务的 protobuf 副本。
要启用它,请先确保你的应用 Pod 上有 gRPC 反射服务在监听,然后把反射方法也加到 GRPCRoute 中。这种用法在开发和预发环境中很有帮助;但在生产环境中应先评估安全影响再启用。
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: foo-route
spec:
parentRefs:
- name: example-gateway
hostnames:
- "foo.example.com"
rules:
- matches:
- method:
service: com.example.User
method: Login
backendRefs:
- name: foo-svc
port: 50051
- matches:
- method:
service: grpc.reflection.v1.ServerReflection
backendRefs:
- name: foo-svc
port: 50051