GRPCRoute

Experimental Channel in v0.6.0+

The GRPCRoute resource is Alpha and part of the Experimental Channel in v0.6.0+. For more information on release channels, refer to the related documentation.

GRPCRoute is a Gateway API type for specifying routing behavior of gRPC requests from a Gateway listener to an API object, i.e. Service.

Background

While it is possible to route gRPC with HTTPRoutes or via custom, out-of-tree CRDs, in the long run, this leads to a fragmented ecosystem.

gRPC is a popular RPC framework adopted widely across the industry. The protocol is used pervasively within the Kubernetes project itself as the basis for many interfaces, including:

Given gRPC’s importance in the application-layer networking space and to the Kubernetes project in particular, the determination was made not to allow the ecosystem to fragment unnecessarily.

Encapsulated Network Protocols

In general, when it is possible to route an encapsulated protocol at a lower level, it is acceptable to introduce a route resource at the higher layer when the following criteria are met:

  • Users of the encapsulated protocol would miss out on significant conventional features from their ecosystem if forced to route at a lower layer.
  • Users of the enapsulated protocol would experience a degraded user experience if forced to route at a lower layer.
  • The encapsulated protocol has a significant user base, particularly in the Kubernetes community.

gRPC meets all of these criteria, so the decision was made to include GRPCRoutein Gateway API.

Cross Serving

Implementations that support GRPCRoute must enforce uniqueness of hostnames between GRPCRoutes and HTTPRoutes. If a route (A) of type HTTPRoute or GRPCRoute is attached to a Listener and that listener already has another Route (B) of the other type attached and the intersection of the hostnames of A and B is non-empty, then the implementation must reject Route A. That is, the implementation must raise an ‘Accepted’ condition with a status of ‘False’ in the corresponding RouteParentStatus.

In general, it is recommended that separate hostnames be used for gRPC and non-gRPC HTTP traffic. This aligns with standard practice in the gRPC community. If however, it is a necessity to serve HTTP and gRPC on the same hostname with the only differentiator being URI, the user should use HTTPRoute resources for both gRPC and HTTP. This will come at the cost of the improved UX of the GRPCRoute resource.

Spec

The specification of a GRPCRoute consists of:

  • ParentRefs- Define which Gateways this Route wants to be attached to.
  • Hostnames (optional)- Define a list of hostnames to use for matching the Host header of gRPC requests.
  • Rules- Define a list of rules to perform actions against matching gRPC requests. Each rule consists of matches, filters (optional), and backendRefs (optional) fields.

The following illustrates a GRPCRoute that sends all traffic to one Service: grpcroute-basic-example

Attaching to Gateways

Each Route includes a way to reference the parent resources it wants to attach to. In most cases, that’s going to be Gateways, but there is some flexibility here for implementations to support other types of parent resources.

The following example shows how a Route would attach to the acme-lb Gateway:

  1. apiVersion: gateway.networking.k8s.io/v1alpha2
  2. kind: GRPCRoute
  3. metadata:
  4. name: grpcroute-example
  5. spec:
  6. parentRefs:
  7. - name: acme-lb

Note that the target Gateway needs to allow GRPCRoutes from the route’s namespace to be attached for the attachment to be successful.

Hostnames

Hostnames define a list of hostnames to match against the Host header of the gRPC request. When a match occurs, the GRPCRoute is selected to perform request routing based on rules and filters (optional). A hostname is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the “host” part of the URI as defined in the RFC:

  • IPs are not allowed.
  • The : delimiter is not respected because ports are not allowed.

Incoming requests are matched against hostnames before the GRPCRoute rules are evaluated. If no hostname is specified, traffic is routed based on GRPCRoute rules and filters (optional).

The following example defines hostname “my.example.com”:

  1. apiVersion: gateway.networking.k8s.io/v1alpha2
  2. kind: GRPCRoute
  3. metadata:
  4. name: grpcroute-example
  5. spec:
  6. hostnames:
  7. - my.example.com

Rules

Rules define semantics for matching an gRPC requests based on conditions, optionally executing additional processing steps, and optionally forwarding the request to an API object.

Matches

Matches define conditions used for matching an gRPC requests. Each match is independent, i.e. this rule will be matched if any single match is satisfied.

Take the following matches configuration as an example:

  1. apiVersion: gateway.networking.k8s.io/v1alpha2
  2. kind: GRPCRoute
  3. ...
  4. matches:
  5. - method:
  6. service: com.example.User
  7. method: Login
  8. headers:
  9. values:
  10. version: "2"
  11. - method:
  12. service: com.example.v2.User
  13. method: Login

For a request to match against this rule, it must satisfy EITHER of the following conditions:

  • The com.example.User.Login method AND contains the header “version: 2”
  • The com.example.v2.User.Login method.

If no matches are specified, the default is to match every gRPC request.

Filters (optional)

Filters define processing steps that must be completed during the request or response lifecycle. Filters act as an extension point to express additional processing that may be performed in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping.

The following example adds header “my-header: foo” to gRPC requests with Host header “my.filter.com”. Note that GRPCRoute uses HTTPRoute filters for features with functionality identical to HTTPRoute, such as this.

  1. apiVersion: gateway.networking.k8s.io/v1alpha2
  2. kind: GRPCRoute
  3. metadata:
  4. name: grpc-filter-1
  5. spec:
  6. hostnames:
  7. - my.filter.com
  8. rules:
  9. - filters:
  10. - type: RequestHeaderModifier
  11. requestHeaderModifier:
  12. add:
  13. - name: my-header
  14. value: foo
  15. backendRefs:
  16. - name: my-filter-svc1
  17. weight: 1
  18. port: 50051

API conformance is defined based on the filter type. The effects of ordering multiple behaviors are currently unspecified. This may change in the future based on feedback during the alpha stage.

Conformance levels are defined by the filter type:

  • All “core” filters MUST be supported by implementations supporting GRPCRoute.
  • Implementers are encouraged to support “extended” filters.
  • “Implementation-specific” filters have no API guarantees across implementations.

Specifying a core filter multiple times has unspecified or custom conformance.

If an implementation can not support a combinations of filters, they must clearly document that limitation. In cases where incompatible or unsupported filters are specified and cause the Accepted condition to be set to status False, implementations may use the IncompatibleFilters reason to specify this configuration error.

BackendRefs (optional)

BackendRefs defines the API objects to which matching requests should be sent. If unspecified, the rule performs no forwarding. If unspecified and no filters are specified that would result in a response being sent, an UNIMPLEMENTED error code is returned.

The following example forwards gRPC requests for the method User.Login to service “my-service1” on port 50051 and gRPC requests for the method Things.DoThing with header magic: foo to service “my-service2” on port 50051:

  1. apiVersion: gateway.networking.k8s.io/v1
  2. kind: GatewayClass
  3. metadata:
  4. name: example
  5. spec:
  6. controllerName: acme.io/gateway-controller
  7. parametersRef:
  8. name: example
  9. group: acme.io
  10. kind: Parameters
  11. ---
  12. apiVersion: gateway.networking.k8s.io/v1
  13. kind: Gateway
  14. metadata:
  15. name: my-gateway
  16. spec:
  17. gatewayClassName: example
  18. listeners: # Use GatewayClass defaults for listener definition.
  19. - name: https
  20. protocol: HTTPS
  21. port: 50051
  22. tls:
  23. certificateRefs:
  24. - kind: Secret
  25. group: ""
  26. name: example-com-cert
  27. ---
  28. apiVersion: gateway.networking.k8s.io/v1alpha2
  29. kind: GRPCRoute
  30. metadata:
  31. name: grpc-app-1
  32. spec:
  33. parentRefs:
  34. - name: my-gateway
  35. hostnames:
  36. - "example.com"
  37. rules:
  38. - matches:
  39. - method:
  40. service: com.example.User
  41. method: Login
  42. backendRefs:
  43. - name: my-service1
  44. port: 50051
  45. - matches:
  46. - headers:
  47. - type: Exact
  48. name: magic
  49. value: foo
  50. method:
  51. service: com.example.Things
  52. method: DoThing
  53. backendRefs:
  54. - name: my-service2
  55. port: 50051

The following example uses the weight field to forward 90% of gRPC requests to foo.example.com to the “foo-v1” Service and the other 10% to the “foo-v2” Service:

  1. apiVersion: gateway.networking.k8s.io/v1alpha2
  2. kind: GRPCRoute
  3. metadata:
  4. name: foo-route
  5. labels:
  6. gateway: prod-web-gw
  7. spec:
  8. hostnames:
  9. - foo.example.com
  10. rules:
  11. - backendRefs:
  12. - name: foo-v1
  13. port: 50051
  14. weight: 90
  15. - name: foo-v2
  16. port: 50051
  17. weight: 10

Reference the backendRef API documentation for additional details on weight and other fields.

Status

Status defines the observed state of the GRPCRoute.

RouteStatus

RouteStatus defines the observed state that is required across all route types.

Parents

Parents define a list of the Gateways (or other parent resources) that are associated with the GRPCRoute, and the status of the GRPCRoute with respect to each of these Gateways. When a GRPCRoute adds a reference to a Gateway in parentRefs, the controller that manages the Gateway should add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route is modified.

Examples

The following example indicates GRPCRoute “grpc-example” has been accepted by Gateway “gw-example” in namespace “gw-example-ns”:

  1. apiVersion: gateway.networking.k8s.io/v1alpha2
  2. kind: GRPCRoute
  3. metadata:
  4. name: grpc-example
  5. ...
  6. status:
  7. parents:
  8. - parentRefs:
  9. name: gw-example
  10. namespace: gw-example-ns
  11. conditions:
  12. - type: Accepted
  13. status: "True"

Merging

Multiple GRPCRoutes can be attached to a single Gateway resource. Importantly, only one Route rule may match each request. For more information on how conflict resolution applies to merging, refer to the API specification.