Skip to content

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: canary Header 的流量 → 对所有 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 流量提供服务:

yaml
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 匹配。

yaml
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。

yaml
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: 50051

gRPC 反射(Reflection) ​

gRPC 反射 是使用 grpcurl 这类交互式客户端的前提——它能让你不必在本地文件系统上持有目标服务的 protobuf 副本。

要启用它,请先确保你的应用 Pod 上有 gRPC 反射服务在监听,然后把反射方法也加到 GRPCRoute 中。这种用法在开发和预发环境中很有帮助;但在生产环境中应先评估安全影响再启用。

yaml
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

基于 MIT 协议发布