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

  1. Install kgateway in a cluster.
  2. Install grpcurl for 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 a pong message.
  • yages.Echo.Reverse: Takes input content and returns the content in reverse order, such as hello world becomes dlrow olleh.

Steps to set up the sample gRPC service:

  1. 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
  2. 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
    EOF

    Example output:

    referencegrant.gateway.networking.k8s.io/allow-grpc-route-to-echo created

Set up the Gateway for gRPC routes

  1. Check the status of the Gateway.

    kubectl get gateway grpc-gateway -n kgateway-system -o yaml

    Example 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

  1. Create the GRPCRoute resource. Include the grpc.reflection.v1alpha.ServerReflection method to enable dynamic API exploration. For detailed information about GRPCRoute fields and configuration options, see the Gateway API GRPCRoute documentation

  2. Verify that the GRPCRoute is applied successfully.

    kubectl get grpcroute grpc-echo-route -n kgateway-system -o yaml

    Example 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: 

Verify the gRPC route

Verify that the gRPC route to the echo service is working.

  1. Get the external address of the gateway and save it in an environment variable.

  2. Explore the API dynamically.

    Expected 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 );
    }
  3. Send a gRPC request to test the route.

    Expected 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