gRPC Transcoding with Istio
Share: 

gRPC Transcoding with Istio


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.

Using 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 proto.

We’d love you to try the tool yourself. You can download the source here. See README.md for further details.

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.

Follow Sai Sitharaman on Twitter @ssaigs

Back to blog