2

I'd like to expose a virtual service in a gateway in such a way that it will respond to both grpc and REST request at the same port/host. The discriminator between the two call mode is the Content-Type: application/json is for REST, everything else will be for grpc. The upstream service exposes only a grcp endpoint, so on the REST path I'd like to use the grpc transcoding filter. This is the setup: enter image description here

this is my virtual service:

kind: VirtualService
metadata:
  labels:
    app.kubernetes.io/name: hello
    app.kubernetes.io/version: "1.0"
  name: hello
spec:
  gateways:
    - istio-system/mesh-gateway
  hosts:
    - 'hello.mesh.control-cluster-raffa.demo.red-chesterfield.com'
  http:
    - name: transcoded
      match:
        - name: rest-content-type
          headers:
            "Content-Type":
              exact: "application/json"
      route:
        - destination:
            host: hello
            port:
              number: 9000
    - name: primary
      route:
        - destination:
            host: hello
            port:
              number: 9000

I am not sure how to write the envoy filter so that it applies to only one branch of the VirtualService, but it would look somethign like this I think:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: grpc-json-transcoder
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
    - applyTo: NETWORK_FILTER # http connection manager is a filter in Envoy
      match:
        context: GATEWAY
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
      patch:
        operation: INSERT_AFTER
        value:
          name: envoy.filters.http.grpc_json_transcoder
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder
            proto_descriptor: "/var/config/proto/proto.pb"
            services: ["hello.HelloGrpc"]
            print_options:
              add_whitespace: true
              always_print_primitive_fields: true
              always_print_enums_as_ints: false
              preserve_proto_field_names: false

Here are some questions:

  • this filter should be applied to the ingress-gateway. In my case the gateway is not in the same namespace as the virtual service, where does the filter goes? I assume in the envoy filter namespace.
  • this gateway is share with many other services, how can I make sure that the filter does not interfere with other virtual services?
  • how can I make sure that the filter applies only to the http route named "transcoded" in the virtual service?
  • this filter requires reading a file, I assume this file will need to be mounted in the ingress gateway, correct?
Jon Bates
  • 3,055
  • 2
  • 30
  • 48

0 Answers0