gRPC Transcoding with Istio
There are a lot of advantages to using gRPC instead of HTTP/JSON when building new APIs, like HTTP/2, streaming, cross-language support, server push, etc. The hardest part tends to be legacy services that expect HTTP/JSON. This is why gRPC-JSON transcoding is so attractive: we can implement gRPC servers but expose them to legacy services with a HTTP/JSON interface. Typically, we would use the gRPC Gateway or a product like Google Cloud Endpoints to handle gRPC-JSON transcoding for us, but Envoy implements transcoding too!
Envoy implements gRPC transcoding as a filter. At Tetrate, we use Istio as the control plane for our Envoy sidecars, and Istio allows for custom Envoy configuration via its
EnvoyFilter CRD. To take advantage of this, we created a small tool,
gen-transcoder, which scans gRPC proto descriptors to automatically generate accurate Envoy filter configs. It also supports features like filtering the services or packages in the descriptor that are exposed as HTTP/JSON by Envoy.
gen-transcoder is built to be friendly with CI/CD workflows too. At Tetrate, we use it to automate the delivery of gRPC-JSON transcoder configs as part of our normal service deployment.
gen-transcoder is a simple 2-step process:
Step 1: Generate proto descriptors during proto compilation
$ protoc \ -I path/to/google/protobufs \ -I path/to/your/protos \ --descriptor_set_out=path/to/output/dir/YOUR_SERVICE_NAME.proto-descriptor \ --include_imports \ --go_out=plugins=grpc:. \ path/to/your/protos/service.proto
Step 2: Use
gen-transcoder to generate Istio Envoy proxy configuration
$ gen-transcoder \ --port 9080 \ --service foo \ --packages proto.package.name \ --services='Service.*' \ --descriptor=path/to/output/dir/YOUR_SERVICE_NAME.proto-descriptor
As part of this, we have included a few sample proto services, compiled into a single proto descriptor that you can use in the following way.
$ gen-transcoder \ --port 9080 \ --service echo \ --packages proto \ --services 'Echo.*' \ --descriptor \ proto/onebig.proto-descriptor
This emits an
EnvoyFilter specifically for service
proto.EchoService in package
As a warning, Istio’s
EnvoyFilter must be used with care, though! If a bad filter config is pushed Envoy will reject configuration updates and stop serving – an outage we at Tetrate experienced before writing this tool.