gRPC services
Route traffic to gRPC services using the GRPCRoute resource for protocol-aware routing.
About
GRPCRoute provides protocol-aware routing for gRPC traffic within the Kubernetes Gateway API. Unlike HTTPRoute, which requires matching on HTTP paths and methods, GRPCRoute allows you to define routing rules using gRPC-native concepts like service and method names.
Consider the difference:
- HTTPRoute Match:
path:/com.example.User/Login,method: POST - GRPCRoute Match:
service: yages.Echo,method: Ping
The GRPCRoute approach is more readable, less error-prone, and aligns with the Gateway API’s role-oriented philosophy.
Before you begin
- Install kgateway in a cluster.
- Install
grpcurlfor testing on your computer.
Deploy a sample gRPC service
Deploy a sample gRPC service for testing purposes. The sample service has two APIs:
yages.Echo.Ping: Takes no input (empty message) and returns apongmessage.yages.Echo.Reverse: Takes input content and returns the content in reverse order, such ashello worldbecomesdlrow olleh.
Steps to set up the sample gRPC service:
-
Deploy the gRPC echo server and client.
kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: grpc-echo spec: selector: matchLabels: app: grpc-echo replicas: 1 template: metadata: labels: app: grpc-echo spec: containers: - name: grpc-echo image: ghcr.io/projectcontour/yages:v0.1.0 ports: - containerPort: 9000 protocol: TCP env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: GRPC_ECHO_SERVER value: "true" - name: SERVICE_NAME value: grpc-echo --- apiVersion: v1 kind: Service metadata: name: grpc-echo-svc spec: type: ClusterIP ports: - port: 3000 protocol: TCP targetPort: 9000 appProtocol: kubernetes.io/h2c selector: app: grpc-echo --- apiVersion: v1 kind: Pod metadata: name: grpcurl-client spec: containers: - name: grpcurl image: docker.io/fullstorydev/grpcurl:v1.8.7-alpine command: - sleep - "infinity" EOF -
Create a ReferenceGrant to allow GRPCRoutes to reference the gRPC echo service.
kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: allow-grpc-route-to-echo namespace: default spec: from: - group: gateway.networking.k8s.io kind: GRPCRoute namespace: kgateway-system to: - group: "" kind: Service EOFExample output:
referencegrant.gateway.networking.k8s.io/allow-grpc-route-to-echo created
Set up the Gateway for gRPC routes
Create an HTTP listener so that the gateway can route gRPC traffic. For more information, see the HTTP listener guide. Note that GRPCRoutes can be attached to HTTPS listeners for TLS termination only in version 2.3 and later.
-
Create a Gateway resource with an HTTP listener.
kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: grpc-gateway namespace: kgateway-system labels: app: grpc-echo spec: gatewayClassName: kgateway listeners: - protocol: HTTP port: 8080 name: http hostname: "grpc.example.com" allowedRoutes: namespaces: from: All EOFReview the following table to understand this configuration.
Setting Description spec.gatewayClassNameThe name of the Kubernetes GatewayClass. When you set up kgateway, a default GatewayClass is set up for you. spec.listenersConfiguration for the HTTP listener for this Gateway. hostnameThe hostname for routing. This values must match the hostname in your GRPCRoute.
-
Check the status of the Gateway.
kubectl get gateway grpc-gateway -n kgateway-system -o yamlExample output:
status: addresses: - type: IPAddress value: ${INGRESS_GW_ADDRESS} conditions: - lastTransitionTime: "2024-11-20T16:01:25Z" message: "" observedGeneration: 2 reason: Accepted status: "True" type: Accepted - lastTransitionTime: "2024-11-20T16:01:25Z" message: "" observedGeneration: 2 reason: Programmed status: "True" type: Programmed
Create a GRPCRoute
-
Create the GRPCRoute resource. Include the
grpc.reflection.v1alpha.ServerReflectionmethod to enable dynamic API exploration. For detailed information about GRPCRoute fields and configuration options, see the Gateway API GRPCRoute documentationkubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: GRPCRoute metadata: name: grpc-echo-route namespace: kgateway-system labels: app: grpc-echo spec: parentRefs: - name: grpc-gateway namespace: kgateway-system sectionName: http hostnames: - "grpc.example.com" rules: - matches: - method: service: "grpc.reflection.v1alpha.ServerReflection" backendRefs: - name: grpc-echo-svc namespace: default port: 3000 - backendRefs: - name: grpc-echo-svc namespace: default port: 3000 EOF -
Verify that the GRPCRoute is applied successfully.
kubectl get grpcroute grpc-echo-route -n kgateway-system -o yamlExample output:
status: parents: - conditions: - lastTransitionTime: "2024-11-21T16:22:52Z" message: "" observedGeneration: 1 reason: Accepted status: "True" type: Accepted - lastTransitionTime: "2024-11-21T16:22:52Z" message: "" observedGeneration: 1 reason: ResolvedRefs status: "True" type: ResolvedRefs controllerName: kgateway.dev/kgateway parentRef: group: gateway.networking.k8s.io kind: Gateway name: grpc-gateway namespace: kgateway-system sectionName: http
Verify the gRPC route
Verify that the gRPC route to the echo service is working.
-
Get the external address of the gateway and save it in an environment variable.
export GATEWAY_IP=$(kubectl get gateway grpc-gateway -n kgateway-system -o jsonpath='{.status.addresses[0].value}') echo $GATEWAY_IPkubectl port-forward svc/grpc-gateway -n kgateway-system 8080:8080 -
Explore the API dynamically.
grpcurl -plaintext -authority grpc.example.com $GATEWAY_IP:8080 list grpcurl -plaintext -authority grpc.example.com $GATEWAY_IP:8080 describe yages.Echogrpcurl -plaintext -authority grpc.example.com localhost:8080 list grpcurl -plaintext -authority grpc.example.com localhost:8080 describe yages.EchoExpected response:
grpc.health.v1.Health grpc.reflection.v1alpha.ServerReflection yages.Echo yages.Echo is a service: service Echo { rpc Ping ( .yages.Empty ) returns ( .yages.Content ); rpc Reverse ( .yages.Content ) returns ( .yages.Content ); } -
Send a gRPC request to test the route.
grpcurl -plaintext \ -authority grpc.example.com \ $GATEWAY_IP:8080 \ yages.Echo/Pinggrpcurl -plaintext \ -authority grpc.example.com \ localhost:8080 \ yages.Echo/PingExpected response:
{ "text": "pong" }
Next steps
Explore the traffic management, resiliency, and security policies that you can apply to make your gRPC services more robust and secure.
Cleanup
You can remove the resources that you created in this guide.kubectl delete -A gateways,grpcroutes,pod,svc,secrets -l app=grpc-echo
kubectl delete referencegrant allow-grpc-route-to-echo -n default