EnRoute Standalone Gateway
What this article covers.
This article covers how EnRoute can be run standalone without a kubernetes cluster. It is an API gateway built on top of cloud-native Envoy proxy. The configuration model is consistent with the EnRoute Kubernetes Ingress Gateway. The EnRoute Standalone Gateway is packaged as a docker image.
Understanding EnRoute Gateway through a simple example
EnRoute provides simple APIs to configure Envoy Proxy. An EnRoute docker image packages Envoy along with EnRoute service that provides these APIs.
In the next few steps, we show how easy it is to configure Envoy using APIs provided by EnRoute Standalone Gateway.
In this example, we’ll start a simple python service and use EnRoute gateway APIs to configure Envoy. Once configured, Envoy will route traffic to this backend python service.
- Send traffic using curl [1]
- Envoy routes traffic on default route to backend python server [2]
- Server sends a response [3]
- Envoy returns a response back [4]
Create service
We use python to create a listening server that will respond to requests used in this example.
Start example server on port 50051
python -m SimpleHTTPServer 50051
Setup EnRoute Gateway
Start EnRoute Gateway
The gateway is packaged as a docker image that can be run using the following command -
sudo docker run --net=host saarasio/enroute-gw:latest
This starts the gateway with in the host privileged mode. The following ports are of interest -
- 1323 - REST API port. Used to create state on the controller
- 9001 - Envoy admin endpoint port.
- 8080 - Listener port for http setup
- 8443 - Listener port for https setup
The EnRoute gateway is now ready with it’s API server. We use simple curl REST API calls to setup the above example.
EnRoute Config model
EnRoute follows a very simple config model. We tell EnRoute about the upstream service by creating an upstream
(that points to the python service we started on port 50051). To route traffic to this upstream
, we create a service
, a route
for this service
and attach the upstream
to this route
We attach the service
to a route
which is attached to an upstream
.
EnRoute can program multiple Envoy proxies and each one is abstracted by a proxy
resource. A service
created in the previous step can be attached to one or many proxy
We create a proxy
called gw
and attach the service
object with it. An instance of Envoy proxy can connect using the name gw
and receive the config associated with the proxy
object.
Create Proxy, Service, Route, Upstream
We use the EnRoute API to perform the following tasks -
Create Upstream
The upstream
object points to the python server listening on port 50051
we created earlier
curl -s -X POST "http://localhost:1323/upstream" \
-d 'Upstream_name=server1' \
-d 'Upstream_ip=127.0.0.1' \
-d 'Upstream_port=50051' \
-d 'Upstream_hc_path=/' \
-d 'Upstream_weight=100'
{
"data": {
"insert_saaras_db_upstream": {
"affected_rows": 1
}
}
}
Create Service
The service
object holds information like fqdn, filters associated with service and other attributes.
curl -s -X POST "http://localhost:1323/service" -d 'Service_Name=demo' -d 'fqdn=*'
{
"data": {
"insert_saaras_db_service": {
"affected_rows": 1
}
}
}
Create Route on this Service
Every service
has one or many route
associated with it. We create the default /
route.
Note the path below where a route is created for service/demo
curl -s -X POST "http://localhost:1323/service/demo/route" \
-d 'Route_Name=gs_route' \
-d 'Route_prefix=/'
{
"data": {
"insert_saaras_db_route": {
"affected_rows": 2
}
}
}
Attach route to upstream
The route
created in previous step needs an upstream
to send traffic to. Here we associate the route
with the upstream
created earlier.
Note how the route on service demo indicated by service/demo/route/gs_route
is associated with upstream/server1
curl -s -X POST "http://localhost:1323/service/demo/route/gs_route/upstream/server1"
{
"data": {
"insert_saaras_db_route_upstream": {
"affected_rows": 4
}
}
}
Create Proxy
The Envoy proxy running in EnRoute package attaches to the EnRoute control-plane using the name gw
. We create a proxy
object with the same name that will feed config to this Envoy.
curl -s -X POST "http://localhost:1323/proxy" -d 'Name=gw'
{
"name": "gw"
}
Attach Service with proxy gw
The service
-> route
-> upstream
traffic path we created in the earlier step can now be used to program Envoy proxy listening for config with the name gw
. We can program it by attaching the service
to the proxy
called gw
Note the path used to perform the association that uses proxy/gw
and service/demo
perform the association.
curl -s -X POST "http://localhost:1323/proxy/gw/service/demo"
{
"data": {
"insert_saaras_db_proxy_service": {
"affected_rows": 3
}
}
}
Dump service
curl -s localhost:1323/service/dump/demo
{
"data": {
"saaras_db_service": [
{
"service_id": 1,
"service_name": "demo",
"fqdn": "*",
"create_ts": "2021-01-24T19:36:58.618025+00:00",
"routes": [
{
"route_id": 1,
"route_name": "gs_route",
"route_upstreams": [
{
"upstream": {
"upstream_id": 1,
"upstream_name": "server1",
"upstream_ip": "127.0.0.1",
"upstream_port": 50051
}
}
],
"route_filters": [],
"route_prefix": "/"
}
],
"service_secrets": [],
"service_filters": []
}
]
}
}
Set Envoy logging level to trace
curl -X POST http://localhost:9001/logging?level=trace
Send traffic
Send a request to the listener
curl -k -vvv http://localhost:8080
Check envoy stats
curl -k -vvv http://localhost:9001/stats