Gateway API Inference Extension (GAIE)
Gateway API Inference Extension (GAIE)
Gateway API Inference Extension (GAIE)
Integrate Dynamo with the Gateway API Inference Extension, also known as Inference Gateway, for intelligent KV-aware request routing at the gateway layer.
EPP’s default kv-routing approach is not token-aware because the prompt is not tokenized. But the Dynamo plugin uses a token-aware KV algorithm. It employs the dynamo router which implements kv routing by running your model’s tokenizer inline. The EPP plugin configuration is embedded in the recipe-based GAIE deploy YAMLs under recipes/llama-3-70b/vllm/agg/gaie/ and recipes/llama-3-70b/vllm/disagg-single-node/gaie/, following the GAIE/EPP configuration layout used by this repository.
Dynamo Integration with the Inference Gateway supports Aggregated and Disaggregated Serving. A request only exercises disaggregated routing when the EPP config defines a prefill profile and prefill workers are available. The recipe examples provide separate aggregated and disaggregated configs under recipes/llama-3-70b/vllm/agg/gaie/ and recipes/llama-3-70b/vllm/disagg-single-node/gaie/. Unless DYN_ENFORCE_DISAGG=true, deployments without a prefill profile or prefill workers fall back to aggregated serving.
GAIE integration supports Data Parallelism.
If you want to use LoRA deploy Dynamo without the Inference Gateway.
These setups use agentgateway as the Inference Gateway implementation.
See Quickstart Guide to install Dynamo Kubernetes Platform.
If you are installing from the source tree rather than a release chart, follow Advanced: Build from Source and run helm dep build ./platform/ before helm install so the vendored subcharts match the local chart contents.
First, deploy an inference gateway service. In this example, we’ll install agentgateway with the inference extension enabled.
This script installs the Gateway API CRDs, the GAIE CRDs, agentgateway into agentgateway-system, and a Gateway named inference-gateway into ${NAMESPACE}.
Do not forget docker registry secret if needed.
Do not forget to include the HuggingFace token.
You can either use the provided Dynamo FrontEnd image for the EPP image or you need to build your own Dynamo EPP custom image following the steps below.
We provide an example for the Qwen vLLM below.
You have to deploy the Dynamo Graph and the HTTPRoute.
The example http-route.yaml resolves the Gateway in the same namespace as
the HTTPRoute, so the simplest path is to apply the route in the same
namespace where you installed the Gateway (i.e. ${NAMESPACE}). If your
Gateway lives in a different namespace, add parentRefs[].namespace to point
at it explicitly:
Examples for other models can be found in the recipes folder.
We provide examples for llama-3-70b vLLM under the recipes/llama-3-70b/vllm/agg/gaie/ for aggregated and recipes/llama-3-70b/vllm/disagg-single-node/gaie/ for disaggregated serving.
Note for the aggregated serving you need to disable DYN_ENFORCE_DISAGG in epp config.
Use the proper folder in commands below.
--router-mode direct so that it respects the EPP’s routing decisions passed via request headers.frontendSidecar field on a worker service to have the operator automatically inject a fully configured frontend sidecar container with all required Dynamo env vars, probes, and ports:--router-mode direct flag ensures the routing respects this selection.Startup Probe Timeout: The EPP has a default startup probe timeout of 30 minutes (10s × 180 failures).
If your model takes longer to load, increase the failureThreshold in the EPP’s startupProbe. For example,
to allow 60 minutes for startup:
Gateway Namespace
The example http-route.yaml resolves the Gateway in the same namespace as
the route. If you install the Gateway in one namespace and apply the route in
another, add parentRefs[].namespace: <gateway-namespace> to http-route.yaml.
Common Vars for Routing Configuration:
Enabling KV-Aware Routing (most precise)
KV-aware routing uses live KV cache block events from workers so the EPP can route requests to the worker with the best prefix cache overlap. To enable it (default):
--enable-prefix-caching and --kv-events-config '{"enable_kv_cache_events":true}'.--kv-events-config with the appropriate endpoint.--publish-events-and-metrics.DYN_USE_KV_EVENTS at its default (true). The EPP subscribes to worker KV events via event plane (NATS/ZMQ) and uses them for prefix-overlap scoring.--block-size on all workers must match DYN_KV_CACHE_BLOCK_SIZE on the EPP (default: 128). Mismatched block sizes cause incorrect block hash computation.Disabling KV-Aware Routing
To disable the EPP from listening for KV events (e.g., when prefix caching is off on workers, or for simpler load-balanced routing):
DYN_USE_KV_EVENTS=false. The router falls back to approximate mode (routing decisions are tracked locally with TTL decay instead of live KV events from workers).--no-enable-prefix-caching to disable prefix caching entirely. Without prefix caching, no KV events are generated regardless of other flags.DYN_ROUTER_KV_OVERLAP_SCORE_CREDIT=0 on the EPP to skip prefix-overlap scoring altogether, making the router select workers based on load only.DYN_BUSY_THRESHOLD to configure the upper bound on how “full” a worker can be (often derived from kv_active_blocks or other load metrics) before the router skips it. If the selected worker exceeds this value, routing falls back to the next best candidate. By default the value is negative meaning this is not enabled.DYN_ENFORCE_DISAGG=true (default: false) to control per-request behavior when prefill workers are unavailable:
true (recommended for disaggregated serving): Requests fail with an error if prefill workers are not available. Use this when disaggregated serving is required and aggregated fallback is not acceptable.false (default): Requests gracefully fall back to aggregated mode (skip prefill, route directly to decode) when prefill workers are not available. When prefill workers appear later, subsequent requests automatically use disaggregated routing.DYN_ROUTER_KV_OVERLAP_SCORE_CREDIT to control the device-local prefix-overlap credit multiplier, from 0.0 to 1.0. Higher values bias toward reusing workers with similar cached prefixes. (default: 1)DYN_ROUTER_PREFILL_LOAD_SCALE to scale adjusted prompt-side prefill load before decode blocks are added. (default: 1)DYN_ROUTER_TEMPERATURE (default: 0.0) to soften or sharpen normalized worker sampling. Low temperature makes the router pick the top candidate deterministically; higher temperature lets lower-scoring workers through more often (exploration).DYN_ROUTER_REPLICA_SYNC — Enable replica synchronization (default: false)DYN_ROUTER_TRACK_ACTIVE_BLOCKS — Track active blocks (default: true)DYN_ROUTER_TRACK_OUTPUT_BLOCKS — Track output blocks during generation (default: false)Service Mesh Integration (Istio)
When running under a service mesh such as Istio, the mesh sidecar proxy may conflict with the EPP’s own TLS serving, causing connection failures (double-TLS). To avoid this, the mesh must be told how to connect to the EPP service via an Istio DestinationRule.
The Dynamo operator can generate this DestinationRule automatically. Enable it by setting the dynamo.serviceMesh parameters when installing or upgrading the Dynamo platform Helm chart:
Or equivalently in a custom values file:
Helm Parameters
The Istio CRDs (networking.istio.io) must be installed on the cluster before enabling this feature. The operator detects Istio availability at startup — if the CRDs are not present, DestinationRule reconciliation is skipped even when serviceMesh.enabled is true.
When enabled, the operator produces a DestinationRule for each EPP service equivalent to:
If you are not using the Dynamo operator’s Helm chart, you must create this DestinationRule manually for each EPP service. Without it, Istio’s default mTLS policy will conflict with the EPP’s gRPC TLS endpoint.
Inference-gateway Istio sidecar exclusion
When namespace-level Istio sidecar injection is enabled (istio-injection=enabled), the agentgateway-proxy pod also receives an Istio sidecar. This sidecar intercepts the ext_proc gRPC connection from agentgateway-proxy to EPP (port 9002) and routes it through PassthroughCluster, which breaks the connection and causes all inference requests to return HTTP 500 with an empty body.
The fix is to tell agentgateway to stamp sidecar.istio.io/inject: "false" on the proxy pod template so the Istio webhook skips that pod. EPP and worker pods still receive sidecars normally.
You have two options depending on how you set up the gateway:
Option A: Per-gateway AgentgatewayParameters (recommended)
This is what install_gaie_crd_agentgateway.sh does automatically. It only affects the inference-gateway proxy pods and leaves any other agentgateway-managed gateways untouched.
Create an AgentgatewayParameters resource in the same namespace as the inference-gateway Gateway (e.g. dynamo-cloud). It must be co-located with the Gateway because the Gateway API spec.infrastructure.parametersRef is a LocalParametersReference — it has no namespace field.
Apply it with server-side apply (recommended by agentgateway):
Wire the existing Gateway to use it. If the Gateway already exists, patch it in place:
Or include the infrastructure block directly in your Gateway manifest:
agentgateway will roll the proxy pod. Verify the new pod no longer has an istio-proxy container:
Option B: Patch the default AgentgatewayParameters CR (cluster-wide)
The agentgateway controller creates a default AgentgatewayParameters resource named agentgateway in agentgateway-system. Any Gateway that does not set spec.infrastructure.parametersRef inherits this default. Patching it affects all agentgateway-managed proxies in the cluster.
Use Option A instead if you have multiple agentgateway-managed gateways in the cluster and only want the inference-gateway proxy to skip injection.
The annotation is a no-op on clusters where Istio is not installed, so it is safe to set unconditionally.
With both the DestinationRule (for EPP) and the AgentgatewayParameters sidecar exclusion (for agentgateway-proxy) in place, end-to-end GAIE inference works correctly under Istio namespace-level injection.
Check that all resources are properly deployed:
Sample output:
The Inference Gateway provides HTTP endpoints for model inference.
a. To test the integration in minikube, proceed as below:
Use minikube tunnel to expose the gateway to the host. This requires sudo access to the host machine. Alternatively, you can use port-forward to expose the gateway to the host as shown in alternative (b).
b. To test on a cluster use commands below:
use port-forward to expose the gateway to the host
a. Query models:
Sample output:
b. Send inference request to gateway:
or
Sample inference output:
If you have more than one HTTPRoute running on the cluster
Add the host to your http-route.yaml and add the header
curl -H "Host: llama3-70b-agg.example.com" ... or curl -H "Host: llama3-70b-disagg.example.com" http://localhost:8000/v1/models
If you need to uninstall run:
This section documents the updated plugin implementation for Gateway API Inference Extension v1.5.0-rc.2.
EPP performs Dynamo router book keeping operations so the FrontEnd’s Router does not have to sync its state.
Since v1.5.0-rc.1, the EPP uses headers and body mutations for communicating routing decisions.
The plugins set HTTP headers for worker targeting and inject pre-computed token IDs
into the request body (nvext.token_data) so the frontend sidecar can skip redundant tokenization.