Use Kong API Gateway on Koyeb Serverless Platform

June 03, 2021

Édouard Bonlieu

Édouard Bonlieu
@edouardb_

Introduction

Kong Gateway is a fast, scalable, and distributed API Gateway offering powerful primitives to ease microservices and distributed architecture management. Combining both Kong Gateway with the Koyeb serverless platform, you benefit from all the built-in blocks to deploy modern applications at scale:

  • Koyeb: to easily deploy your applications globally and providing native TLS encryption, global edge network, service mesh, and discovery, horizontal scaling, and more.

  • Kong Gateway: acting as distributed microservice abstraction layer offering rate-limiting, auth features, proxy caching, and more.

Kong Gateway

In this guide, we will deploy a Koyeb App with the following Services:

  • Kong Gateway: to proxy requests and forward them to the target microservices.
  • A simple HTTP echo service

We will then configure Kong rate-limiting to restrict the number of requests our services can receive, implement basic auth to one of our simple HTTP services, and see how to secure the Kong admin API.

Requirements

To successfully follow and complete this guide, you need:

  • A Koyeb account to deploy the microservices and Kong API Gateway
  • A PostgreSQL database Koyeb can access
  • Docker installed on your machine to prepare the Kong Gateway database

Steps

To successfully follow this guide and deploy Kong Gateway, you need to follow these steps:

  1. Deploy Kong Gateway
  2. Deploy a simple HTTP echo service
  3. Configure Kong Gateway

Deploy Kong Gateway

Prepare your database

The first step is to prepare your database to run Kong Gateway. This database is used by Kong to store its configuration such as routes, services, etc. In your terminal, run the following command to run the Kong database migration:

$ docker run --rm \ -e "KONG_DATABASE=kong" \ -e "KONG_PG_HOST=<PG_HOST>" \ -e "KONG_PG_PORT=<PG_PORT" \ -e "KONG_PG_USER=<PG_USER>" \ -e "KONG_PG_PASSWORD=<PG_PASSWORD>" \ -e "KONG_PG_SSL=on" kong:latest kong migrations bootstrap

Deploy Kong on Koyeb

With the Kong database migration performed, we can now deploy Kong Gateway, we use the official Kong Docker image kong.

On the Koyeb control panel, click the Create App button. You land on the App creation page where you need to configure your application.

  1. Fill the Docker image field with kong.

  2. In the Ports section, change the export port from 80 to 8000, which is the port the kong Docker image uses to receive incoming HTTP traffic, and forwards it to upstream Services. This setting is required to let Koyeb know which port Kong is listening to and properly route incoming HTTP requests. If you want the Kong Gateway to be available on a specific path, you can change the default one (/) to the path of your choice.

  3. Add another port in the Ports section, to expose the Kong Gateway admin API. Set the port to 8001, and set the path to /admin

  4. In the Environment variables section, configure the environment variables required to properly run Kong Gateway.

    • KONG_DATABASE: The environment variable containing the type of database, here postgres
    • KONG_PG_DATABASE: The environment variable containing the database name, here kong
    • KONG_PG_HOST: The environment variable containing the PostgreSQL port
    • KONG_PG_PORT: The environment variable containing the PostgreSQL host
    • KONG_PG_USER: The environment variable containing the PostgreSQL user, in my case: kong
    • KONG_PG_PASSWORD: The environment variable containing the PostgreSQL password. To store this value which contains sensitive information, we strongly recommend configuring the environment variable using Koyeb secrets instead of storing it as a plaintext value. Secrets are encrypted at rest. They are ideal to store add sensitive data like authentication tokens, OAuth tokens, etc.
    • KONG_PG_SSL: The environment variable use to connect the PostgreSQL connection using SSL, in my case: on
    • KONG_ADMIN_LISTEN: The environment variable containing the host and port the admin need to listen, 0.0.0.0:8001
    • KONG_PROXY_ACCESS_LOG: /dev/stdout
    • KONG_ADMIN_ACCESS_LOG: /dev/stdout
    • KONG_PROXY_ERROR_LOG: /dev/stderr
    • KONG_ADMIN_ERROR_LOG: /dev/stderr
  5. Give your App a name, i.e kong-gateway, and click Create App.

Within a few seconds, your Kong Gateway service will be up and running. You will be able to access it via the Koyeb App URL displayed in the Koyeb control panel: <appname>-<orgname>.koyeb.app

Deploy a simple HTTP echo service

To implement a complete demo and showcase how Kong Gateway works, we will add a simple HTTP echo services in our Koyeb App.

This service will not be exposed directly to the Internet. Instead, we will take advantage of the Koyeb service mesh and discovery built-in features which provide an isolated, secure private network to allow Koyeb Services to communicate inside a Koyeb App.

In your App, click the Create Service button, and deploy the service as below:

  1. Fill the Docker image field with mendhak/http-https-echo.
  2. In the Ports section, keep the export port to 80 which is the port the mendhak/http-https-echo Docker image app is listening on. This setting is required to let Koyeb know which port your application is listening to and properly route incoming HTTP requests. Uncheck the checkbox Expose publicly to make the application only reachable via the Koyeb App mesh.
  3. Give the Service a name, i.e http-echo, and click Create Service.

Configure Kong Gateway

Create new Kong services and register new routes

The next step is to configure the Kong Gateway to:

  • Create two new services pointing to our simple HTTP echo service

In your terminal, run the following commands:

curl -i -X POST \ --url https://<appname>-<orgname>.koyeb.app/admin/services \ --data 'name=hello-service1' \ --data 'url=http://http-echo/service1' curl -i -X POST \ --url https://<appname>-<orgname>.koyeb.app/admin/services \ --data 'name=hello-service2' \ --data 'url=http://http-echo/service2'

These commands create two Kong services with the name hello-service1 and hello-service2. Each one of these services is configured with an upstream server URL pointing to two different paths of our HTTP echo service.

  • Register two routes, one for each service we created to route incoming requests to each one of this service via a specific path

In your terminal, run the following commands:

curl -i -X POST \ --url https://<appname>-<orgname>.koyeb.app/admin/services/hello-service1/routes \ --data 'hosts[]=<appname>-<orgname>.koyeb.app' \ --data 'paths[]=/service1' \ --data 'methods[]=GET' curl -i -X POST \ --url https://<appname>-<orgname>.koyeb.app/admin/services/hello-service2/routes \ --data 'hosts[]=<appname>-<orgname>.koyeb.app' \ --data 'paths[]=/service2' \ --data 'methods[]=GET'

These commands create two Kong routes, one for each service we previously created. That way, from our Koyeb App url, we will be able to access https://<appname>-<orgname>.koyeb.app/service2 and https://<appname>-<orgname>.koyeb.app/service1.

Add rate limiting

Kong Gateway provide a rate limiting plugin to protect your services and restrict the number of requests your upstream services receive from your API consumers. To add rate limiting and protect your services, in a terminal run the following command:

curl -i -X POST https://<appname>-<orgname>.koyeb.app/admin/plugins \ --data name=rate-limiting \ --data config.minute=5 \ --data config.policy=local

The rule above restricts the number of requests a service can receive to five requests per minute. You can validate the rate-limiting rule works as expected running six times the query below from the terminal:

curl -i -X GET https://<appname>-<orgname>.koyeb.app/service1

When you hit the rate-limiting limit you will see the following:

{ "message": "API rate limit exceeded" }

Enable basic auth on a service

Kong provides a large choice of authentication plugins which can be helpful to secure one or all of your services. In this guide, we will enable basic authentication on our hello-service1 Kong service.

In the terminal, run the following command to enable basic auth:

curl -X POST https://<appname>-<orgname>.koyeb.app/admin/services/hello-service1/plugins \ --data "name=basic-auth" \ --data "config.hide_credentials=true"

And create a consumer (in Kong represents a consumer or a user of a Service) by executing the following request:

curl -d "username=demo&custom_id=<REPLACE_ME_WITH_AN_ID>" https://<appname>-<orgname>.koyeb.app/admin/consumers

Last, create a new credential you will use to access the service:

curl -X POST https://<appname>-<orgname>.koyeb.app/admin/consumers/demo/basic-auth \ --data "username=koyeb" \ --data "password=demo"

Now if you go to https://<appname>-<orgname>.koyeb.app/service1, the basic auth form appears and asks for a username and password to access the service.

Secure the Kong Gateway admin API

As we have previously seen, Kong allows you to secure your services using different methods. We will now use Kong to secure the admin API. In the previous step, we add using the basic auth method, to secure the admin, we will use API key authentication.

  1. Create a new service to access the admin
curl -i -X POST \ --url https://<appname>-<orgname>.koyeb.app/admin/services \ --data 'name=admin-api' \ --data 'url=http://localhost:8001'
  1. Register a new Route to access theadmin-api service:
curl -X POST https://<appname>-<orgname>.koyeb.app/admin/services/admin-api/routes \ --data 'hosts[]=<appname>-<orgname>.koyeb.app' \ --data 'paths[]=/admin' \
  1. Create an admin consumer:
curl -d "username=admin&custom_id=<REPLACE_ME_WITH_AN_ID>" https://<appname>-<orgname>.koyeb.app/admin/consumers
  1. Enable API key auth on the admin api:
curl -i -X POST \ --url https://<appname>-<orgname>.koyeb.app/admin/services/admin-api/plugins/ \ --data 'name=key-auth' \ --data 'config.hide_credentials=true'
  1. Create the API key
curl -i -X POST https://<appname>-<orgname>.koyeb.app/admin/consumers/admin/key-auth \ --data key=<YOUR_API_KEY>
  1. Validate authentication
curl -i https://<appname>-<orgname>.koyeb.app/admin-api \ -H 'apikey: <YOUR_API_KEY>'

If everything works as expected, you can now update your Koyeb Kong service and disable the exposition of port 8001 to the Internet by unchecking Expose publicly. That way the Kong admin API will be only accessible via the secure endpoint https://<appname>-<orgname>.koyeb.app/admin-api.

Conclusion

In this guide, we did a quick tour of how to configure and use Kong Gateway. We explored the Kong plugin system and enable rate-limiting and auth on our services. We also showcased how to secure and restrict access to the Kong admin API.

We took advantage of the Koyeb mesh and service discovery built-in features offering a simple, secure, and powerful private network to host your microservices and access them from the Internet using Kong Gateway.

To go deeper and learn more about how Kong Gateway works, we recommend you to check out the Kong official documentation

If you have any questions, suggestions, or feedback about this tutorial or would like to see a specific topic covered, do not hesitate to join us on Slack.

Welcome to Koyeb

Koyeb is a developer-friendly serverless platform to deploy any apps globally.

Start for free
Start for free, pay as you grow

Deploy 2 services for free and enjoy our predictable pricing as you grow

Deploy your first app in no time

Get up and running in 5 minutes