This tutorial walks through installing, configuring, and testing various features of the Kong API Gateway. API gateways are pivotal to largely scaled application architectures that support microservices patterns to support features such as authentication/authorization, rate limiting, IP restrictions, etc.

Prerequisites

This tutorial assumes you have the Docker engine installed and running as the examples will use Docker to launch various containers for use of the Kong API Gateway and supporting services.

To ensure all containers can communicate easily, let’s create a Docker network on which all containers will be launched:

$ docker network create kong

Launching a PostgreSQL Database

Kong uses a database to store the state and configuration information you manipulate for the instance. It is possible to launch a Kong gateway without a database backend, but it complicates the creation of services (you’ll need to manipulate configuration files and inject them, which is clunky). So let’s launch a PostgreSQL database instance that we can use for the Kong API gateway:

$ docker run -d --name kong-database \
                --network=kong \
                -p 5432:5432 \
                -e "POSTGRES_USER=kong" \
                -e "POSTGRES_DB=kong" \
                -e "POSTGRES_PASSWORD=kong" \
                postgres:9.6

Next, we’ll want to run the database migrations to prepare the database for the Kong API Gateway instance:

$ docker run --rm \
             --link kong-database:kong-database \
             --network=kong \
             -e "KONG_DATABASE=postgres" \
             -e "KONG_PG_HOST=kong-database" \
             -e "KONG_PG_USER=kong" \
             -e "KONG_PG_PASSWORD=kong" \
             -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
             kong/kong-gateway kong migrations bootstrap

Once the migrations complete, you should see a completion message similar to Database is up-to-date, indicating you’re now ready to launch the Kong API Gateway instance.

Launching a Kong API Gateway

Now, let’s launch the Kong API Gateway instance using the PostgreSQL instance we launched:

$ docker run -d --name kong \
                --network=kong \
                --link kong-database:kong-database \
                -e "KONG_DATABASE=postgres" \
                -e "KONG_PG_HOST=kong-database" \
                -e "KONG_PG_PASSWORD=kong" \
                -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
                -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
                -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
                -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
                -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
                -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
                -p 8000:8000 \
                -p 8443:8443 \
                -p 8001:8001 \
                -p 8444:8444 \
                kong/kong-gateway

If the container launches successfully, you can validate the Kong API Gateway is running by issuing a curl command to the API endpoint like so: curl http://localhost:8001/. If you receive a large JSON response with valid data, you can be confident your API gateway instance is running as expected.

Launching the Konga Admin UI

To ease the administration and testing of Kong features, we’ll install the Konga administrative User Interface for configuring Kong.

Launch the Konga docker container:

$ docker run -d --name konga \
                --network=kong \
                -p 1337:1337 \
                pantsel/konga

Once the Konga Docker container is launched, you can visit the web interface in a browser by visiting http://localhost:1337. From here, you’ll be asked to create an administrative user - go ahead and enter details that allow you to create the admin account. Once you click create, you’ll need to log into the interface using the same account credentials. If all goes well, you’ll land on a Dashboard page that asks about connecting to your Kong instance.

Enter the details for your Kong instance - create a name for the connection (e.g. “Kong”) and enter the URL of the admin API which, if you followed the above directions verbatim, should be http://kong:8001 (using the hostname kong will be recognizable by the Konga interface by the nature of naming your Docker container that was launched within the kong network itself). Click the “Create Connection” button and if all goes well, you’ll land on the Dashboard with some basic metrics information about your Kong instance.

Launch an Echo Server for Service

Let’s use a basic echo server container for configuring and testing our API gateway. Launch an echo server using the following command:

$ docker run -d --name echo-server \
                --network=kong \
                -p 3000:80 \
                ealen/echo-server

Issue a curl request to validate the container is working as expected: curl http://localhost:3000/param?query=hello-world. If all goes well, you should receive a JSON payload which contains (among other data) the following bit: ...,"query":{"query":"hello-world"},.

Note that we’re querying the echo server on port 3000 yet binding that port to port 80. Port 80 will be used to access the echo server by the Kong API Gateway on the kong network which all Docker containers are connected to.

Configure the Echo Service

Now let’s configure a Service and Route through the Konga interface. Log into Konga, and navigate to the Services menu item in the left navbar. Click the Add New Service button, and enter the following details:

  • Name: EchoTest
  • Protocol: http
  • Host: echo-server
  • Port: 80
  • Path: /

Click the Submit Changes button, which should bring you to the list of Services. Then, click on the service name EchoTest to bring up the options for the Service, and select the Routes option for the Service. Click the Add Route button, and enter the following details:

  • Name: TestRoute
  • Paths: /testPath (make sure to press “Enter” after entering this value)
  • Protocols: http (make sure to press “Enter” after entering this value)

Now click the Submit Changes button. You now have a Service and Route defined which you can use your API gateway to route requests to your back-end echo server service. Let’s test it by issuing the following curl request:

$ curl http://localhost:8000/testPath/param?query=hello-world

Note above that the curl request is targeting localhost, but on port 8000 which is where the Kong API gateway is listening. If successful, the above curl request should return a JSON response that has the following in its payload, indicating a succesful configuration of your API gateway routing to the back-end echo server: ...,"query":{"query":"hello-world"},...

Plugin Testing

The power of Kong is not just in the gateway pass-through/routing but in the plugins which perform various functions. This section explores several of the open-source (non-enterprise) plugins that can be used with the Kong API Gateway.

API Key Authentication

To test some basic functionality of the API gateway, let’s configure the API Key global plugin. In the Konga web interface, navigate to the Plugins page in the left navbar. Click the Add Global Plugins button, and select Add Plugin under the “Key Auth” plugin in the Authentication plugin sub-menu. This specific plugin allows the management of consumers within the Kong API Gateway itself, which is a reasonable first test for authentication. When the modal pops open, simply navigate to the bottom and click Add Plugin without changing any values.

Now that the plugin is installed, let’s try to re-issue a curl request to the echo server:

$ curl http://localhost:8000/testPath/param?query=hello-world

You should get a response that looks like the following:

{
  "message":"No API key found in request"
}

This indicates that we need an API key to authenticate to access the endpoint. Navigate to the Consumers page via the left navbar in the Konga interface, and click the Create Consumer button. For username, specify test-consumer, and leave the rest of the fields default/click the Submit Consumer button. By default (as seen in the Routes view for the consumer created) the consumer is permitted to access the TestRoute route for our echo server.

Next, for the consumer, click on the Credentials navigation, followed by the API Keys sub-navigation. Then, click the Create API Key button and click Submit (leave fields blank/default). You should then see an API key generated - copy this value.

Let’s re-issue the same curl command but this time, pass the API key (replace <APIKEY> with the API Key value you copied from the Konga interface):

$ curl --header "apikey: <APIKEY>" \
       http://localhost:8000/testPath/param?query=hello-world

If successful, you should be authenticated and receive the echo response as expected. Congratulations, you’ve now configured authentication at your Gateway layer for your back-end echo service!

It’s worth noting there is a rich set of authentication plugins available for authentication and at large scale, it’s likely better to offload the user and auth management to a proper identity provider which Kong can use vs. managing users within Kong itself.

Rate Limiting

In order to help prevent DDoS attacks, the rate limiting plugin can be used. First, install the plugin under the Plugins menu in the left navbar, and under the Traffic Control sub-menu by clicking the Add Plugin button under Rate Limiting. In the form that opens, leave all values blank except the second value - specify 1 in the second field and then click the Submit Changes button. This should configure a maximum request rate of 1 request per second globally (for all consumers). This plugin allows a per-consumer rate limit, but to keep the testing easy, we’ll specify a 1 per second rate limit for all consumers/request sources.

Let’s test this - issue multiple curl requests in a for loop (again replacing <APIKEY> with your consumer API key):

$ for x in {1..10}; do curl --header "apikey: <APIKEY>" \
       http://localhost:8000/testPath/param?query=hello-world; \
done

What you should observe is that your first request returns a result from the echo server, but several of the subsequent requests (depending on how fast your device issues the requests) should return a JSON response of { "message":"API rate limit exceeded" }. This indicates that our rate limiting plugin is working as expected!

Request Transformer

Often it’s useful to have requests transformed prior to forwarding to the back-end service. Let’s add the Request Transformer plugin via the Global Plugins menu under the Transformations sub-menu. When you click Add Plugin, modify the append -> querystring field to read as query:added, then press “Enter” (this is important! if you don’t press the enter key, the querystring won’t add the actual value). This should add a query string to the end of the requested URL. Let’s try this - issue a curl command like so, again replacing the <APIKEY> parameter with your actual API key. Note that we have removed the query parameter in the querystring, expecting our API Gateway to add it to our request with a specific/different value than previous tests:

$ curl --header "apikey: <APIKEY>" \
       http://localhost:8000/testPath/param

When submitting the request, you should get back the typical JSON payload, except this time you should see the JSON contents of ...,{"query":{"query":"added"},, indicating the API Gateway has successfully injected the querystring in the request!

Conclusion

The Kong API Gateway can be a very powerful component of your overall architecture. With the multitude of plugins available for content manipulation, authentication, and security controls, Kong is sure to offer an enhanced edge to your complex ecosystem of microservice functionality, offloading many of the likely custom functionality built into your software.

Credit

The above tutorial was pieced together with some information from the following sites/resources, among others that were likely missed in this list: