Exploring API Gateways: Kong Setup
The beauty of software architecture is the myriad of strategies
One technology that I feel will help me create better architectures is an API Gateway.
I had avoided microservices architectures, but I watched Continuous Delivery's video, and independently deployable services made my eyes light up.
The beauty of software architecture is the myriad of strategies. Imagine a design that you could de-couple your organization at the development level. I am going for it.
One technology that I believe will help me design better architecture (not only microservices) is an API Gateway. It will help me tie the underlying containers up and identify shared functionalities. I will cover it in later posts. For now, I will present my starting point.
After some researches, I decided to use Kong as my learning tool, mostly because of custom Golang plugins, and I can run it locally.
Overview

The Kong API Gateway will be deployed inside a Kubernetes cluster and configured using the declarative approach. I will sync the local configuration file with a Pod containing a decK container that will communicate with the Kong Admin API.
Kubernetes
I opted for Kubernetes just for the personal challenge. Using Docker Compose is probably easier and faster.
I chose Kind to create the cluster because it is faster, and I can keep everything in a single Docker Network, even the Postgres database.
Ports 8000 and 8443 will be exposed to interact with the Kong Proxy and test our microservices architecture.
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: kong-in-kubernetes
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 32080
hostPort: 8000
- containerPort: 32443
hostPort: 8443
Finally: kind create cluster --config kind.yaml
Postgres database for Kong
It seems fair to use Kong with Postgres, but I did not want to deploy a database inside Kubernetes (regretting my choices), too much work and complexity.
An easier way is to deploy a Postgres database inside kind's network and reference it using an ExternalName
Service.
Docker Compose:
services:
database:
image: postgres
ports:
- 5432:5432
networks:
- kind
environment:
POSTGRES_DB: kong
POSTGRES_USER: kong
POSTGRES_PASSWORD: kongnetworks:
kind:
external: true
name: kind
Postgres ExternalName Service:
apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
type: ExternalName
externalName: database
Running everything:
docker-compose up -dkubectl apply -f postgres/svc.yaml
Kong
With all set, we can focus on the API Gateway. The easiest way to deploy Kong in Kubernetes is using the Helm Chart, and I will break down some essential values in the Chart.
Environment Variables
env:
database: postgres
pg_host: database
pg_user: kong
pg_password: kong
pg_database: kong
declarative_config: /opt/kong/kong.yaml
Every variable in the env
section will be transformed to uppercase and prefixed by KONG_
. Our goal is to instruct Kong to use the Postgres database, the reason why env.pg_host
is set to database
, the Postgres' service name in kind's network.
Kong Admin API
We will configure Kong with decK that needs to communicate with the Kong Admin API. But we do not want to expose this API outside Kubernetes. That is why we will use a ClusterIP Service:
admin:
enabled: true
type: ClusterIP
http:
enabled: true
Exposing Kong Proxy
By the end of the day, we need to test our API Gateway, and it needs to be exposed out of the Docker Network. In Kind
's configuration, the kind's container bound the container's ports 32080
and 32443
to 8000 and 8443, respectively. These will be the NodePorts
:
proxy:
enabled: true
type: NodePort http:
nodePort: 32080
tls:
nodePort: 32443
Deploying Kong
Everything in order, we can run:
helm repo add kong https://charts.konghq.com
helm repo update
helm install -n kong --create-namespace api-gateway kong/kong --set ingressController.installCRDs=false --values kong/values.yaml
Declarative Configuration
Before iterating over Kong's features, our last step is to configure the API Gateway. I prefer declarative approaches, but this requires syncing a local file. Sadly, I complicated my life with Kubernetes, but I came up with a solution.
Using kubectl cp and decK, I created a script that:
- Spawns a Pod with decK
- Copies a local kong.yaml file to decK's container
- Runs the sync command in decK
- Deletes the Pod
#!/bin/bashkubectl run -n kong --wait --restart=Never deck --image=kong/deck --command -- sleep 3600
kubectl wait -n kong --for=condition=ready pods/deck
kubectl cp ./kong/kong.yaml kong/deck:/tmp/kong.yaml
kubectl exec -n kong deck -- deck sync --kong-addr=http://api-gateway-kong-admin:8001 -s /tmp/kong.yaml
kubectl delete -n kong pods/deck
decK communicates with Kong API using the service created by the admin
section in the Chart values file.
Now we are ready to go.
Next Steps
This is a how-to article but a starting point: Kubernetes cluster with Kong API Gateway ready to iterate over microservices designs.
You can check the complete environment in my GitHub Repository:
https://github.com/vargasmesh/Kong-in-Kubernetes.
Now, I will set sail for this microworld and see what we can learn from it.