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
What You Will Learn
Section titled “What You Will Learn”- 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)
Architecture
Section titled “Architecture” +--------+ | 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.
Deploy
Section titled “Deploy”Step 1: Create the namespace
Section titled “Step 1: Create the namespace”kubectl apply -f demos/api-gateway/manifests/namespace.yamlStep 2: Install Kong via Helm
Section titled “Step 2: Install Kong via Helm”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.
helm repo add kong https://charts.konghq.comhelm 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=500mWait for Kong pods to be ready:
kubectl get pods -n api-gateway-demo -wStep 3: Deploy the backend services
Section titled “Step 3: Deploy the backend services”kubectl apply -f demos/api-gateway/manifests/backends.yamlStep 4: Create Ingress routes through Kong
Section titled “Step 4: Create Ingress routes through Kong”kubectl apply -f - <<'EOF'apiVersion: networking.k8s.io/v1kind: Ingressmetadata: 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: 80EOFStep 5: Verify routing works
Section titled “Step 5: Verify routing works”# Get the Kong proxy URLexport KONG_PROXY=$(minikube service kong-gateway-proxy -n api-gateway-demo --url | head -1)
curl -s $KONG_PROXY/echo-1 | python3 -m json.toolcurl -s $KONG_PROXY/echo-2 | python3 -m json.toolYou should see different JSON responses from each echo service.
Step 6: Apply rate limiting
Section titled “Step 6: Apply rate limiting”kubectl apply -f demos/api-gateway/manifests/rate-limit-plugin.yamlAnnotate the Ingress to use the rate limiting plugin:
kubectl annotate ingress echo-routes -n api-gateway-demo \ konghq.com/plugins=rate-limit --overwriteStep 7: Test rate limiting
Section titled “Step 7: Test rate limiting”# 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-1doneThe first 5 requests return HTTP 200. The 6th returns HTTP 429 (Too Many Requests).
Step 8: Apply API key authentication
Section titled “Step 8: Apply API key authentication”kubectl apply -f demos/api-gateway/manifests/api-key-plugin.yamlUpdate the Ingress annotation to include both plugins:
kubectl annotate ingress echo-routes -n api-gateway-demo \ konghq.com/plugins=rate-limit,api-key-auth --overwriteStep 9: Test without API key
Section titled “Step 9: Test without API key”curl -s $KONG_PROXY/echo-1# Returns 401 UnauthorizedStep 10: Create a consumer and API key
Section titled “Step 10: Create a consumer and API key”kubectl apply -f - <<'EOF'apiVersion: configuration.konghq.com/v1kind: KongConsumermetadata: name: demo-user namespace: api-gateway-demo annotations: kubernetes.io/ingress.class: kongusername: demo-usercredentials: - demo-user-key---apiVersion: v1kind: Secretmetadata: name: demo-user-key namespace: api-gateway-demo labels: konghq.com/credential: key-authtype: OpaquestringData: key: my-secret-api-keyEOFStep 11: Test with API key
Section titled “Step 11: Test with API key”curl -s -H "apikey: my-secret-api-key" $KONG_PROXY/echo-1 | python3 -m json.tool# Returns 200 with JSON responseVerify
Section titled “Verify”# Check all podskubectl get pods -n api-gateway-demo
# Check serviceskubectl get svc -n api-gateway-demo
# Check Kong pluginskubectl get kongplugins -n api-gateway-demo
# Check Kong consumerskubectl get kongconsumers -n api-gateway-demo
# Check ingress routeskubectl get ingress -n api-gateway-demoWhat is Happening
Section titled “What is Happening”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 keysBackends 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.
Experiment
Section titled “Experiment”-
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 -
Add a third echo backend and route:
Terminal window # Deploy a new echo service and add a /echo-3 path to the Ingress -
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 --overwritecurl -s $KONG_PROXY/echo-1 -
Check Kong’s admin API for active routes:
Terminal window kubectl port-forward svc/kong-gateway-admin -n api-gateway-demo 8444:8444curl -s https://localhost:8444/routes --insecure | python3 -m json.tool -
Observe rate limit headers in responses:
Terminal window curl -s -i $KONG_PROXY/echo-1 -H "apikey: my-secret-api-key" | grep -i ratelimit
Cleanup
Section titled “Cleanup”helm uninstall kong -n api-gateway-demokubectl delete namespace api-gateway-demoFurther Reading
Section titled “Further Reading”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.
Next Step
Section titled “Next Step”Move on to Event-Driven Kafka to learn how services communicate asynchronously through message brokers.