How to route multiple gRPC services based on path in Istio(Kubernetes)

6/18/2020

I have managed to run one grpc service in a root path. But I tried to add more grpc service by adding custom path route in virtual service which doesn't work. Any help would be highly appreciated.

This is the gateway:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"

I have this virtual service routing to only one grpc service and is working fine

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-virtual-svc
spec:
  hosts:
    - "*"
  gateways:
    - my-gateway
  http:
  - name: "my-grpc-1"
    match:
    - uri:
        prefix: "/"
    route:
    - destination:
        port:
          number: 9090
        host: my-grpc-1-svc

But I wanted to try something like below but it is not working

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-virtual-svc
spec:
  hosts:
    - "*"
  gateways:
    - my-gateway
  http:
  - name: "my-grpc-1"
    match:
    - uri:
        prefix: "/my-grpc-1"
    route:
    - destination:
        port:
          number: 9090
        host: my-grpc-1-svc
  - name: "my-grpc-2"
    match:
    - uri:
        prefix: "/my-grpc-2"
    route:
    - destination:
        port:
          number: 9090
        host: my-grpc-2-svc
-- Prata
grpc
istio
kubernetes

3 Answers

6/19/2020

That´s probably does not work because your app listen on / and with your first virtual service, which works, istio send requests to /, which is not happening with your second virtual service.

The answer here would be to add rewrite to your second virtual service.

HTTPRewrite can be used to rewrite specific parts of a HTTP request before forwarding the request to the destination. Rewrite primitive can be used only with HTTPRouteDestination. The following example demonstrates how to rewrite the URL prefix for api call (/ratings) to ratings service before making the actual API call.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings-route
spec:
  hosts:
  - ratings.prod.svc.cluster.local
  http:
  - match:
    - uri:
        prefix: /ratings
    rewrite:
      uri: /v1/bookRatings
    route:
    - destination:
        host: ratings.prod.svc.cluster.local
        subset: v1

so it would look like this

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-virtual-svc
spec:
  hosts:
    - "*"
  gateways:
    - my-gateway
  http:
  - name: "my-grpc-1"
    match:
    - uri:
        prefix: "/my-grpc-1"
    rewrite:
      uri: "/"
    route:
    - destination:
        port:
          number: 9090
        host: my-grpc-1-svc
  - name: "my-grpc-2"
    match:
    - uri:
        prefix: "/my-grpc-2"
    rewrite:
      uri: "/"
    route:
    - destination:
        port:
          number: 9090
        host: my-grpc-2-svc

Related documentation about it is here.


I think you could try to do it with FQN of the gRPC services as mentioned in this github issue comment

Another idea would be to use nginx like mentioned here.

-- Jakub
Source: StackOverflow

1/8/2022

Convenient way for routing grpc is Ingress. But it needs to add some settings for ngnix:

If you prefer to forward encrypted traffic to your POD and terminate TLS at the gRPC server itself, add the ingress annotation \ nginx.ingress.kubernetes.io/backend-protocol: "GRPCS".

or else

Note that gRPC services must be specified as backend services. nginx.ingress.kubernetes.io/grpc-backend: "true"

NGINX Ingress Controller: This example demonstrates how to route traffic to a gRPC service through the nginx controller.

-- John Nix
Source: StackOverflow

3/31/2021

Here are some tips when working with grpc and istio (tested with istio 1.9.2).

1.Set protocol in service:

kind: Service
metadata:
  name: my-grpc-service
spec:
  ports:
  - number: 9009
    appProtocol: grpc

2.set protocol in gateway:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-gateway
spec:
  servers:
    - port:
        number: 80
        name: grpc
        protocol: GRPC
      hosts:
        - "*"

3.grpc generated uri path prefix will be the same as package value in .proto file:

syntax = "proto3";    
package somepath;

use it as match.uri.prefix:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-virtual-svc
spec:
  http:
  - name: "my-grpc-1"
    match:
    - uri:
        prefix: "/somepath"
-- Matt
Source: StackOverflow