Is it possible to route multiple GRPC services with Kong Ingress Controller?

I have read following guidelines for GRPC service routing:

But I can’t find any documentation on how to route multiple GRPC services. Is it possible to do so?

RPCs are called via the format “[host]/[service]/[method]” so you can enable service routing by setting the ingress “path” prefix for each of your gRPC services to the fully-qualified service name (e.g. path: “/hello.HelloService/” in the case of the second linked example).

I changed my ingress to the following:

  paths:
  - backend:
      serviceName: grpcbin
      servicePort: 9001
    path: /hello.HelloService/

But I am unable to call it with grpcurl. I tried calling the service with the following command:

  1. grpcurl -v -d ‘{“greeting”: “Kong Hello world!”}’ -insecure $url:443 hello.HelloService.SayHello

Error invoking method "hello.HelloService.SayHello": failed to query for service descriptor "hello.HelloService": rpc error: code = Internal desc = transport: received the unexpected content-type "application/json; charset=utf-8"

  1. grpcurl -v -d ‘{“greeting”: “Kong Hello world!”}’ -insecure $url/hello.HelloService:443 hello.HelloService.SayHello

Failed to dial target host ".../hello.HelloService:443": dial tcp: lookup .../hello.HelloService: no such host

  1. grpcurl -v -d ‘{“greeting”: “Kong Hello world!”}’ -insecure $url/hello.HelloService:443 SayHello

Failed to dial target host ".../hello.HelloService:443": dial tcp: lookup .../hello.HelloService: no such host

I also tried removing the ‘/’ at the end of the path (i.e. path: /hello.HelloService) but the result is still the same

@freesnow The first command should be correct. I think the issue is that grpcurl is trying to call the grpc reflection API but there is no mapping. Can you try also adding another path mapping to your ingress:

 - backend:
      serviceName: grpcbin
      servicePort: 9001
   path: /grpc.reflection.v1alpha.ServerReflection/

Thanks. I am able to call the GRPC service after adding the path mapping above.

Does that mean I need to disable reflection for all the applications I deploy to the cluster if I need to route multiple GRPC services? Or is there another way to route multiple GRPC services with reflection enabled?

Also, after I disabled reflection for the application, I received another error when trying to call the service:
failed to query for service descriptor "...": server does not support the reflection API

If your use case specifically requires the reflection API for clients e.g. grpcurl then you could alternatively provide the client with the proto files via the -import-path option so it knows how to convert JSON -> protobuf. However, I think the more typical use cases involves using the generated gRPC client stubs to communicate directly via protobuf.

Thanks so much for the help! I am able to set up multiple GRPC services and use grpcurl to call them.

Hi Freesnow,
Can you please share the solution with me ?
Or the ingress file with the two different paths (for two differents grpc services)

Thanks!

Here’s the ingress (the second service is demo.grpc.api.v1.Demo):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    configuration.konghq.com/protocols: grpc,grpcs
  name: "grpc-ingress"
  namespace: default
spec:
  rules:
    - http:
        paths:
          - path: /demo.grpc.api.v1.Demo/
            backend:
              serviceName: grpc-demo-http
              servicePort: 9090
          - path: /
            backend:
              serviceName: /hello.HelloService/
              servicePort: 9001

To call the two services with grpcurl:

  • grpcurl -insecure -proto helloDemo.proto $url:443 demo.grpc.api.v1.Demo/SayHello
  • grpcurl -insecure -d ‘{“greeting”: “Kong Hello world!”}’ -proto hello.proto $url:443 hello.HelloService.SayHello
1 Like