Skip to content

API Gateway (Kong)

Use Kong as an API gateway to route, rate-limit, and authenticate requests to backend services.

Time: ~20 minutes Difficulty: Intermediate

Resources: This demo needs ~1GB RAM. Clean up other demos first: task clean:all

  • Deploying Kong as a Kubernetes-native API gateway
  • Routing traffic to multiple backend services through a single entry point
  • Applying rate limiting to protect services from overload
  • Enabling API key authentication to control access
  • Using Kong custom resources (KongPlugin, KongIngress)
+--------+
| Client |
+----+---+
|
+------+------+
| Kong Gateway|
| (proxy:80) |
+------+------+
|
+--------+--------+
| |
+-----+-----+ +-----+-----+
| echo-1 | | echo-2 |
| (service) | | (service) |
+-----------+ +-----------+

Kong sits in front of the backend services, handling routing, rate limiting, and authentication. Clients never talk to backend services directly.

Terminal window
kubectl apply -f demos/api-gateway/manifests/namespace.yaml

Kong’s Helm chart installs the gateway and registers its CRDs (KongPlugin, KongConsumer, etc.). The plugin manifests in this demo depend on those CRDs, so Helm must be installed first.

Terminal window
helm repo add kong https://charts.konghq.com
helm repo update
helm install kong kong/ingress -n api-gateway-demo \
--set gateway.proxy.type=NodePort \
--set gateway.resources.requests.memory=256Mi \
--set gateway.resources.requests.cpu=100m \
--set gateway.resources.limits.memory=512Mi \
--set gateway.resources.limits.cpu=500m

Wait for Kong pods to be ready:

Terminal window
kubectl get pods -n api-gateway-demo -w
Terminal window
kubectl apply -f demos/api-gateway/manifests/backends.yaml

Step 4: Create Ingress routes through Kong

Section titled “Step 4: Create Ingress routes through Kong”
Terminal window
kubectl apply -f - <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-routes
namespace: api-gateway-demo
annotations:
konghq.com/strip-path: "true"
spec:
ingressClassName: kong
rules:
- http:
paths:
- path: /echo-1
pathType: Prefix
backend:
service:
name: echo-1
port:
number: 80
- path: /echo-2
pathType: Prefix
backend:
service:
name: echo-2
port:
number: 80
EOF
Terminal window
# Get the Kong proxy URL
export KONG_PROXY=$(minikube service kong-gateway-proxy -n api-gateway-demo --url | head -1)
curl -s $KONG_PROXY/echo-1 | python3 -m json.tool
curl -s $KONG_PROXY/echo-2 | python3 -m json.tool

You should see different JSON responses from each echo service.

Terminal window
kubectl apply -f demos/api-gateway/manifests/rate-limit-plugin.yaml

Annotate the Ingress to use the rate limiting plugin:

Terminal window
kubectl annotate ingress echo-routes -n api-gateway-demo \
konghq.com/plugins=rate-limit --overwrite
Terminal window
# Send 6 requests quickly (limit is 5 per minute)
for i in $(seq 1 6); do
echo "Request $i:"
curl -s -o /dev/null -w "HTTP %{http_code}\n" $KONG_PROXY/echo-1
done

The first 5 requests return HTTP 200. The 6th returns HTTP 429 (Too Many Requests).

Terminal window
kubectl apply -f demos/api-gateway/manifests/api-key-plugin.yaml

Update the Ingress annotation to include both plugins:

Terminal window
kubectl annotate ingress echo-routes -n api-gateway-demo \
konghq.com/plugins=rate-limit,api-key-auth --overwrite
Terminal window
curl -s $KONG_PROXY/echo-1
# Returns 401 Unauthorized
Terminal window
kubectl apply -f - <<'EOF'
apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
name: demo-user
namespace: api-gateway-demo
annotations:
kubernetes.io/ingress.class: kong
username: demo-user
credentials:
- demo-user-key
---
apiVersion: v1
kind: Secret
metadata:
name: demo-user-key
namespace: api-gateway-demo
labels:
konghq.com/credential: key-auth
type: Opaque
stringData:
key: my-secret-api-key
EOF
Terminal window
curl -s -H "apikey: my-secret-api-key" $KONG_PROXY/echo-1 | python3 -m json.tool
# Returns 200 with JSON response
Terminal window
# Check all pods
kubectl get pods -n api-gateway-demo
# Check services
kubectl get svc -n api-gateway-demo
# Check Kong plugins
kubectl get kongplugins -n api-gateway-demo
# Check Kong consumers
kubectl get kongconsumers -n api-gateway-demo
# Check ingress routes
kubectl get ingress -n api-gateway-demo
manifests/
namespace.yaml # api-gateway-demo namespace
backends.yaml # Two echo servers (echo-1, echo-2) with nginx configs
rate-limit-plugin.yaml # KongPlugin CR: 5 requests per minute, local policy
api-key-plugin.yaml # KongPlugin CR: key-auth requiring API keys

Backends are nginx pods configured to return JSON identifying which service handled the request. Kong is installed via Helm and acts as a reverse proxy in front of both backends. The rate-limit plugin uses a KongPlugin custom resource to enforce 5 requests per minute per client. The api-key plugin requires all requests to include a valid apikey header. Kong checks credentials against KongConsumer resources and their associated Secrets.

Note: The KongPlugin and KongConsumer CRDs are registered by the Kong Helm chart. If you apply the plugin manifests before installing Kong, kubectl will reject them with “no matches for kind KongPlugin.” Always install Kong first.

  1. Change the rate limit to 10 requests per minute:

    Terminal window
    kubectl edit kongplugin rate-limit -n api-gateway-demo
    # Change config.minute from 5 to 10
  2. Add a third echo backend and route:

    Terminal window
    # Deploy a new echo service and add a /echo-3 path to the Ingress
  3. Remove the API key plugin and verify open access:

    Terminal window
    kubectl annotate ingress echo-routes -n api-gateway-demo \
    konghq.com/plugins=rate-limit --overwrite
    curl -s $KONG_PROXY/echo-1
  4. Check Kong’s admin API for active routes:

    Terminal window
    kubectl port-forward svc/kong-gateway-admin -n api-gateway-demo 8444:8444
    curl -s https://localhost:8444/routes --insecure | python3 -m json.tool
  5. Observe rate limit headers in responses:

    Terminal window
    curl -s -i $KONG_PROXY/echo-1 -H "apikey: my-secret-api-key" | grep -i ratelimit
Terminal window
helm uninstall kong -n api-gateway-demo
kubectl delete namespace api-gateway-demo

See docs/deep-dive.md for a detailed explanation of API gateway patterns, Kong’s plugin architecture, the difference between local and cluster rate limiting policies, and how to set up mutual TLS between Kong and backend services.

Move on to Event-Driven Kafka to learn how services communicate asynchronously through message brokers.