gRPC routing

Experimental Channel

The GRPCRoute resource described below is currently only included in the “Experimental” channel of Gateway API. For more information on release channels, refer to the related documentation.

The GRPCRoute resource allows you to match on gRPC traffic and direct it to Kubernetes backends. This guide shows how the GRPCRoute matches traffic on host, header, and service, and method fields and forwards it to different Kubernetes Services.

The following diagram describes a required traffic flow across three different Services:

  • Traffic to foo.example.com for the com.Example.Login method is forwarded to foo-svc
  • Traffic to bar.example.com with an env: canary header is forwarded to bar-svc-canary for all services and methods
  • Traffic to bar.example.com without the header is forwarded to bar-svc for all services and methods

gRPC Routing

The dotted lines show the Gateway resources deployed to configure this routing behavior. There are two GRPCRoute resources that create routing rules on the same prod Gateway. This illustrates how more than one Route can bind to a Gateway which allows Routes to merge on a Gateway as long as they don’t conflict. GRPCRoute follows the same Route merging semantics. For more information on that, refer to the documentation.

In order to receive traffic from a Gateway, a GRPCRoute resource must be configured with ParentRefs which reference the parent gateway(s) that it should be attached to. The following example shows how the combination of Gateway and GRPCRoute would be configured to serve gRPC traffic:

  1. apiVersion: gateway.networking.k8s.io/v1
  2. kind: Gateway
  3. metadata:
  4. name: example-gateway
  5. spec:
  6. gatewayClassName: example-gateway-class
  7. listeners:
  8. - name: grpc
  9. protocol: HTTPS
  10. port: 50051
  11. tls:
  12. certificateRefs:
  13. - kind: Secret
  14. group: ""
  15. name: example-com-cert
  16. ---
  17. apiVersion: gateway.networking.k8s.io/v1alpha2
  18. kind: GRPCRoute
  19. metadata:
  20. name: example-route
  21. spec:
  22. parentRefs:
  23. - name: example-gateway
  24. hostnames:
  25. - "example.com"
  26. rules:
  27. - backendRefs:
  28. - name: example-svc
  29. port: 50051

A GRPCRoute can match against a single set of hostnames. These hostnames are matched before any other matching within the GRPCRoute takes place. Since foo.example.com and bar.example.com are separate hosts with different routing requirements, each is deployed as its own GRPCRoute - foo-route and bar-route.

The following foo-route will match any traffic for foo.example.com and apply its routing rules to forward the traffic to the correct backend. Since there is only one match specified, only requests for the com.example.User.Login method to foo.example.com will be forwarded. RPCs of any other method` will not be matched by this Route.

  1. apiVersion: gateway.networking.k8s.io/v1alpha2
  2. kind: GRPCRoute
  3. metadata:
  4. name: foo-route
  5. spec:
  6. parentRefs:
  7. - name: example-gateway
  8. hostnames:
  9. - "foo.example.com"
  10. rules:
  11. - matches:
  12. - method:
  13. service: com.example
  14. method: Login
  15. backendRefs:
  16. - name: foo-svc
  17. port: 50051

Similarly, the bar-route GRPCRoute matches RPCs for bar.example.com. All traffic for this hostname will be evaluated against the routing rules. The most specific match will take precedence which means that any traffic with the env: canary header will be forwarded to bar-svc-canary and if the header is missing or does not have the value canary then it will be forwarded to bar-svc.

  1. apiVersion: gateway.networking.k8s.io/v1alpha2
  2. kind: GRPCRoute
  3. metadata:
  4. name: bar-route
  5. spec:
  6. parentRefs:
  7. - name: example-gateway
  8. hostnames:
  9. - "bar.example.com"
  10. rules:
  11. - matches:
  12. - headers:
  13. - type: Exact
  14. name: env
  15. value: canary
  16. backendRefs:
  17. - name: bar-svc-canary
  18. port: 50051
  19. - backendRefs:
  20. - name: bar-svc
  21. port: 50051

gRPC Reflection is required to use interactive clients such as grpcurl without having a local copy of the target service’s protocol buffers present on your local filesysem. To enable this, first ensure that you have a gRPC reflection server listening on your application pods, then add the reflection method to your GRPCRoute. This is likely to be useful in development and staging environments, but this should be enabled in production environments only after the security implications have been considered.

  1. apiVersion: gateway.networking.k8s.io/v1alpha2
  2. kind: GRPCRoute
  3. metadata:
  4. name: foo-route
  5. spec:
  6. parentRefs:
  7. - name: example-gateway
  8. hostnames:
  9. - "foo.example.com"
  10. rules:
  11. - matches:
  12. - method:
  13. service: com.example.User
  14. method: Login
  15. backendRefs:
  16. - name: foo-svc
  17. port: 50051
  18. - matches:
  19. - method:
  20. service: grpc.reflection.v1.ServerReflection
  21. backendRefs:
  22. - name: foo-svc
  23. port: 50051