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