Kubernetes Gateway API on AKS Exposed via Azure Application Gateway
Source: Dev.to
Introduction
We needed to expose the Kubernetes Gateway API from a multi‑tenant AKS cluster through Azure Application Gateway. The integration initially failed: health probes were unhealthy, backends appeared unhealthy, and traffic did not flow. This article documents a working solution and provides a reference architecture for teams facing the same challenges. The complete solution is available on GitHub.
Proof of Concept Overview
The POC demonstrates how to set up the Kubernetes Gateway API on AKS and expose it via Azure Application Gateway in a multi‑tenant environment. Two sample applications (app1 and app2) are deployed in the cluster, each exposed through its own HTTPRoute while sharing a common Istio Gateway resource.
Sample Applications
| Component | Description |
|---|---|
sample-app-1 | Nginx pod returning “Hello from App 1” on path /app1 |
sample-app-2 | Nginx pod returning “Hello from App 2” on path /app2 |
health-responder | Dedicated pod for Application Gateway health probes on /healthz |
| Istio Gateway | Shared Gateway resource implementing the K8s Gateway API |
| HTTPRoutes | Per‑path routing rules in application namespaces |
Each application has its own HTTPRoute in its namespace, illustrating a self‑service routing model where application teams manage routes while using a common gateway infrastructure.
Note: The POC keeps the scenario simple to focus on Azure integration challenges.
app1andapp2simulate applications running in two separate tenants. A future post will cover multi‑tenancy on Kubernetes with Capsule and the Gateway API.
Architecture Components
| Component | Purpose |
|---|---|
| Azure Application Gateway | Public entry point with WAF and TLS termination |
| Internal Load Balancer | Connects the Application Gateway to the AKS cluster |
| Istio Gateway | Implementation of the Kubernetes Gateway API |
| HTTPRoutes | Per‑namespace routing rules for tenants |
| Istio Ambient Mesh | mTLS between services without sidecars |
Implementation Challenges and Fixes
Issue 1: Health Probes Failing
Problem – Azure Application Gateway health probes returned 404 because Istio’s Envoy proxy did not have a matching HTTPRoute for the probe path.
Solution – Create an explicit HTTPRoute that matches the health‑probe path and forwards it to the health-responder pod.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: health-route
namespace: gateway-health
spec:
parentRefs:
- name: shared-gateway
namespace: istio-ingress
rules:
- matches:
- path:
type: PathPrefix
value: /healthz
backendRefs:
- name: health-responder
port: 8080
Issue 2: ExternalTrafficPolicy for Azure DSR
Problem – The Azure Internal Load Balancer operates in Direct Server Return (DSR) mode. With the default externalTrafficPolicy: Cluster, kube‑proxy performs SNAT when forwarding traffic across nodes, breaking the asymmetric routing required for DSR and causing connection timeouts.
Solution – Patch the Gateway service to use externalTrafficPolicy: Local, ensuring that traffic is only routed to pods on the node that received the request and preserving the DSR flow.
kubectl patch svc -n \
-p '{"spec":{"externalTrafficPolicy":"Local"}}'