Sunday, July 12, 2020

Envoy Control Plane Hello World

Hi,

In this post I would like to explain how to configure Envoy proxy to work with a control plane. I spent some time reading documentation about Envoy and I didn't find nothing for having something up and running for beginners like me. I hope to fill this gap.

To describe Envoy very quickly it is a proxy like Nginx or HAProxy but with the difference that its configuration can be dynamic and piloted through API. I was very curious to set up an example where I can modify the upstream IP address by API.

For more information please refers to Envoy documentation (https://www.envoyproxy.io/docs/envoy/latest/) or this blog article https://blog.envoyproxy.io/service-mesh-data-plane-vs-control-plane-2774e720f7fc which give a bigger picture of control plane and service mesh.

So let's go back to this tutorial. What we will achieve is:



We will use java-control-plane only for EDS functionality. All the rest will be configured statically by a yaml file. What it is interesting is that Envoy can be used in a lot of configuration from fully dynamic by using EDS, CDS, LDS, etc or fully static. We'll take an hybrid approach. Once you understand how it works for EDS it is easy to adapt for the others.

Important concepts with Envoy are listeners (LDS), clusters (CDS) and endpoints (EDS). In our example the listener is configured to be on port 10000. A cluster is a list of endpoints that provide a service (in our example the cluster name is some_service). Endpoints are pairs of IP address/port number associated to a cluster.

Envoy will connect to a control plane to retrieve endpoint configuration (in our example the endpoint 127.0.0.1:8000 is given by the control plane).

First of all you need the Envoy binary. What I did is build it locally by following https://github.com/envoyproxy/envoy/tree/master/ci#building-and-running-tests-as-a-developer. If you go this way I suggest to do it with a release version and not master branch where some unit tests may fail (I did it with v1.14.3 without issue). Another option is to use the docker image.

You will also need the java-control-plane: https://github.com/envoyproxy/java-control-plane (it is easier to use than go-control-plane):

git clone https://github.com/envoyproxy/java-control-plane 

Pre-requisite: 

1) Modify java-control-plane to use it as an EDS

The modification consists in adding an endpoint to some_service cluster in the snapshot. some_service cluster is commented as it is defined by static resource (see content of bootstrap-xds.yaml bellow). Just to help understand, each time you want to change the topology of your mesh you create a new snapshot. The default version of TestMain.java contains two snapshot creation but for this tutorial only the first one is necessary so the second one is commented.

Modify TestMain.java as follow:

 2) Add bootstrap-xds.yaml  to Envoy directory:


Takeaways from this configuration:
- Envoy is listening on port 10000
- Requests to 10000 are sent to the cluster some_service
- The endpoints of cluster some_service are provided by EDS
- EDS server is running on port 12345

Now that all configuration is done, let's start the services

1) Start the upstream

Start an http server listening on port 8000 with python

python3 -m http.server 

2) Start Envoy with bootstrap-xds.yaml configuration

./envoy -c bootstrap-xds.yaml --drain-time-s 1 -l debug 
NB: you can access Envoy stats at http://127.0.0.1:19000



3) Start the control plane

Run TestMain.java from java-control-plane project

4) Verify it works

Make a request to http://127.0.0.1:10000/ and it should be redirected to http://127.0.0.1:8000/

I hope this tutorial can help getting started with Envoy with a very practical example that you can build on.

No comments:

Post a Comment