proxy,

How to setup Envoy proxy

Sep 25, 2021 · 4 mins read · Post a comment

Envoy is a minimalistic L7 proxy designed to be used along with the cloud native microservice applications. It’s an open-source container based project which can run on a minimum system resources with high performance. In this tutorial, I’m going to give you a brief example of how you can create an envoy proxy using the latest Docker image.

Prerequisites

  • Linux bash environment
  • Docker

Envoy Resources

Before we can start with the configuration let’s create a directory envoy and file envoy.yaml as well.

mkdir envoy
cd envoy
touch envoy.yaml

There are two types of recourses, static and dynamic. In this example, I’m going to show you how to configure envoy static API rather than dynamic. So let’s open the envoy.yaml file and fill the first line with:

static_resources:

Envoy Listeners

The listeners section is more of a network config where you need to specify the IP address you want to listen to and the port. I will set 0.0.0.0 for the IP configuration and 15000 as a port.

listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 15000 }

Envoy Filter Chains and Filters

Filter chains can have multiple filters. Filters are defining the virtual hosts which are used in Nginx and Apache world as well, or more precisely filters are handling the requests and proxying them to the desired destination. In this example, I’m going to proxy all the traffic to devcoops.com:

filter_chains:
- filters:
  - name: envoy.http_connection_manager
    config:
      stat_prefix: ingress_http
      route_config:
        name: local_route
        virtual_hosts:
        - name: local_service
          domains: ["*"]
          routes:
          - match: { prefix: "/" }
            route: { host_rewrite_literal: devcoops.com, cluster: service_devcoops }
      http_filters:
      - name: envoy.router
  • route_config: Responsible to route the traffic if the virtual hosts hit a match. In this example, it will pass all the HTTP requests because the domain option is *.
  • cluster: Define a cluster name where the request will be taken and handled from that cluster, which we are going to specify it in the next section.

Rest of the config sections are self-explanatory and built-in, default envoy filters.

Envoy Clusters

As I mentioned previously if the route matches some filters, it will pass the request to the cluster where it will proxy the traffic to the desired destination. The default envoy behavior is to use the round robin algorithm if there are multiple hosts specified.

clusters:
  - name: service_google
    connect_timeout: 0.25s
    type: LOGICAL_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [{ socket_address: { address: devcoops.com, port_value: 443 }}]
    tls_context: { sni: devcoops.com }

Completed Envoy Configuration

The finished envoy.yaml should look like:

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 15000 }

    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route: { host_rewrite_literal: devcoops.com, cluster: service_devcoops }
          http_filters:
          - name: envoy.router

  clusters:
  - name: service_devcoops
    connect_timeout: 0.25s
    type: LOGICAL_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [{ socket_address: { address: devcoops.com, port_value: 443 }}]
    tls_context: { sni: devcoops.com }

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 8080 }

Run the Envoy Docker image

Once the configuration is prepared, save the file, and you can run the following command to start the proxy:

cd ..
docker run --name=envoy_proxy -d \
  -p 80:15000 \
  -v $(pwd)/envoy/envoy.yaml:/etc/envoy/envoy.yaml \
  envoyproxy/envoy:v1.18.4

Once the container is up and running open your web browser and type: http://localhost and you should be redirected to devcoops.com. You can check it through the console as well.

curl -Ik http:localhost

Output:

HTTP/1.1 200 OK
content-length: 20595
server: envoy
content-type: text/html; charset=utf-8
last-modified: Fri, 24 Sep 2021 18:05:05 GMT
access-control-allow-origin: *
etag: "614e1351-5073"
expires: Sat, 25 Sep 2021 22:52:06 GMT
cache-control: max-age=600
set-cookie: path=/; domain=.devcoops.com;
x-proxy-cache: MISS
x-github-request-id: 5F34:35B2:1D01C4E:1DC3E60:614FA5BE
accept-ranges: bytes
date: Sat, 25 Sep 2021 23:27:21 GMT
via: 1.1 varnish
age: 0
x-served-by: cache-vie6341-VIE
x-cache: MISS
x-cache-hits: 0
x-timer: S1632612441.978172,VS0,VE97
vary: Accept-Encoding
x-fastly-request-id: d968a1b0b0fff9d5f7ffc4fb93840badc6b44ae6
x-envoy-upstream-service-time: 206

Conclusion

Setting up an Envoy proxy will increase your performance and spare memory and CPU resources. You can use it as a part of your Docker Compose microservice configuration file. I’m going to shed some light on that in some of our next topics. Feel free to leave a comment below and if you find this tutorial useful, follow our official channel on Telegram.