Status: I'm currently using this in production, but it needs a tiny bit more cleanup before I push the containers to dockerhub and write docs.
This project exists to glue together Kubernetes and Envoy, allowing Envoy to read Kubernetes services and endpoints as clusters (via CDS) and endpoints (via EDS).
In simple cases, the default DNS provided by headless services is probably good enough for your Envoy configuration, and in complex cases, you should probably use a full service mesh like Istio. This exists for the medium-sized case, where you are manually writing Envoy configurations, but want to grab your clusters from an API instead of typing the details into your configuration. Beyond saving you typing, using a native xDS service discovery API server allows us to provide Envoy with locality information in support of locality-aware load balancing. This can save you money on inter-AZ network traffic, and save your users time with lower network latency between your proxy and the backend.
I have not tested this with ExternalService
type services. It "should" work. Depending on how
external the external service is, you might want to skip EDS and declare the cluster a LOGICAL_DNS
type. If the external service uses TLS, you may want to configure Envoy with a literal SNI to
present to the upstream server; otherwise it might serve you the wrong certificate or otherwise act
confused (my experience with proxying to AWS services is that they will do the right things, but log
a ton of errors while doing that, which may distract you from real issues). You will also need to
configure how Envoy verifies the upstream's certificate; by default, it will trust anything!
Things are going to work very strangely if you use different port
and targetPort
numbers in your
service definition. It will never work for headless services, and will not work in EDS mode.
Things are going to work very strangely if you use non-headless services. In CDS-only mode, your connections will go through kube-proxy as you'd expect, but remember that Envoy typically only uses one connection per upstream, so there will be no load balancing unless you explicitly configure your cluster to create one connection per request. In any mode involving EDS, we bypass kube-proxy by programming Envoy with the Pod endpoints directly. To avoid confusing yourself, I recommend not using any plain services by setting clusterIP to None for all of them.
It is possible, with the right set of overrides on default:kubernetes:443
, to end up with a route
to your Kubernetes API server authenticated automatically with the service account that runs Envoy.
You'd have to do a lot of work to make it happen, but all the tools are available. Don't bridge that
to the Internet or you will be mining a lot of cryptocoins in short order.