Routing gRPC with https through Gateway & Virtualservice not working

Hi,

I have 2 GRPC services that can transcode https requests from Gateway to GRPC services (both with https enabled) behind it using GRPC transcoder EnvoyFilter, and its working.

Now I’m trying to route GRPC requests from an internal GRPC service to another internal GRPC service through Gateway with VirtualService or simply through VirtualService, but I couldn’t get both to work:

Here’s my config:

  1. Route internal gRPC requests through VirtualService:

    e.g. a GRPC request to https://service1.default.svc.cluster.local results in error:

    System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
    —> System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer

     apiVersion: networking.istio.io/v1alpha3
     kind: Gateway
     metadata:
       name: my-ingress-gateway
     spec:
       selector:
         istio: ingressgateway # use Istio default gateway implementation
       servers:
       - port:
           number: 443
           name: https
           protocol: HTTPS
         tls:
           mode: SIMPLE
           credentialName: ingressgateway-certs
         hosts:
         - "domain.com"
    
         apiVersion: networking.istio.io/v1alpha3
         kind: VirtualService
         metadata:
           name: my-router
         spec:
           hosts:
           - "domain.com"
           - "service1.default.svc.cluster.local"
           - "service2.default.svc.cluster.local"
           gateways:
           - my-ingress-gateway
           - mesh
           http:
           - match:
             - uri: # HTTP
                 prefix: /api/service1
             - uri: # GRPC
                 prefix: /service1.Service
                 route:
             - destination:
                 port:
                   number: 82
                   host: service1.default.svc.cluster.local
             corsPolicy:
               allowOrigin:
               - "*"
    
           - match:
               - uri: # HTTP
                 prefix: /api/service2
               - uri: # GRPC
                 prefix: /service2.Service
             route:
             - destination:
                 port:
                   number: 81
                 host: service2.default.svc.cluster.local
             corsPolicy:
               allowOrigin:
               - "*"
    
     ---
    
     apiVersion: networking.istio.io/v1alpha3
     kind: DestinationRule
     metadata:
       name: service1-destination
     spec:
       host: service1.default.svc.cluster.local
       trafficPolicy:
         loadBalancer:
           simple: LEAST_CONN
         tls:
           mode: ISTIO_MUTUAL
    
     ---
    
     apiVersion: networking.istio.io/v1alpha3
     kind: DestinationRule
     metadata:
       name: service2-destination
     spec:
       host: service2.default.svc.cluster.local
       trafficPolicy:
         loadBalancer:
           simple: LEAST_CONN
         tls:
           mode: ISTIO_MUTUAL
    
  2. Through Gateway + VirtualService:

    e.g. a GRPC request to https://domain.com:443 results in error:

    System.Net.Http.HttpRequestException: Name or service not known
    —> System.Net.Sockets.SocketException (0xFFFDFFFF): Name or service not known

My EnvoyFilter for both 2 approaches above:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: my-grpc-transcoder
spec:
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: SIDECAR_INBOUND
      listener:
        filterChain:
          filter:
            name: "envoy.http_connection_manager"
            subFilter:
              name: "envoy.router"
    patch:
      operation: INSERT_BEFORE
      value:
        name: envoy.grpc_json_transcoder
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.http.transcoder.v2.GrpcJsonTranscoder
          proto_descriptor: /etc/envoy/desc.pb
          services:
          - service1.Service
          - service2.Service
          print_options:
            add_whitespace: true
            always_print_primitive_fields: true

  - applyTo: CLUSTER // same is applied to service2
    match:
      context: SIDECAR_INBOUND
      cluster:
        service: service1.default.svc.cluster.local // same is applied to service2
    patch:
      operation: MERGE
      value:
        transport_socket:
          name: envoy.transport_sockets.tls
          typed_config:
            "@type": type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext
            common_tls_context:
              alpn_protocols: [ "h2" ]

Any ideas? thanks.

Hi,

you should create DR for domain.com and specify tls and proper sni.