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 上。下面的示例展示了如何把 GatewayGRPCRoute 组合起来,为 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.combar.example.com 是主机名不同、路由需求不同的两个主机,所以它们各自被部署为独立的 GRPCRoute —— foo-routebar-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 协议发布