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.