Gateway Routing and DNS
This guide explains how NVCF self-hosted deployments route traffic through the Kubernetes Gateway API, and how to configure DNS and HTTPS for production environments.
Overview
The NVCF self-hosted deployment uses the Kubernetes Gateway API for ingress traffic management. This provides:
- Hostname-based routing for HTTP services (API Keys, NVCF API, Invocation)
- Port-based routing for gRPC and optional LLM reverse QUIC traffic
- One or more load balancers, based on the Gateway and listener layout
- Cross-namespace routing through
ReferenceGrant
The Gateway API is a Kubernetes standard with multiple implementations. The examples on this page use Envoy Gateway, but you can use any Gateway API-compliant controller that supports the requirements below.
Gateway quickstart
Use this procedure before any remote Helmfile deployment that needs NVCF services reachable through Gateway API.
Skip this section for local k3d flows that already create the local Gateway and route hostnames.
Install Gateway API CRDs
Install the Kubernetes Gateway API CRDs v1.2.0:
If you replace v1.2.0 with another version, verify compatibility with the GatewayClass and Gateway resources that you create.
Create namespaces and labels
Create the namespaces used by the Gateway and NVCF services, then label the route-owning namespaces so the Gateway can accept cross-namespace routes:
Install Envoy Gateway
Install Envoy Gateway as the Gateway API controller:
Verify the controller pod is running:
Create EnvoyProxy and GatewayClass
Create an EnvoyProxy resource before you create the GatewayClass. The
envoyDeployment.replicas setting controls the Envoy proxy data-plane pods that
handle ingress traffic. It does not control Envoy Gateway controller pods.
Service annotations on a Gateway do not configure the Envoy data-plane
Service. Set them in EnvoyProxy.spec.provider.kubernetes.envoyService so
Envoy Gateway copies them to the generated Service.
Before applying the EnvoyProxy on EKS, determine which Service controller
owns load balancers. Do not apply the manifest until you have selected the
matching envoyService configuration:
An EKS API result of True selects
EKS Auto Mode.
Otherwise, a successful Deployment lookup selects the AWS Load Balancer
Controller. If neither is present, confirm that the cluster intentionally uses
the legacy AWS cloud provider Service controller, or install the AWS Load
Balancer Controller, before applying the example.
The applied manifest below uses the
AWS Load Balancer Controller
with instance targets and an internet-facing Network Load Balancer (NLB).
For EKS Auto Mode, replace its envoyService map before applying it with:
For the legacy AWS cloud provider Service controller, replace the map with:
The legacy controller creates an internet-facing load balancer by default. Add
service.beta.kubernetes.io/aws-load-balancer-internal: "true" for an internal
NLB. Do not combine the legacy nlb controller selector with the AWS Load
Balancer Controller target type and scheme annotations. The legacy controller
supports an NLB Service whose ports use only TCP or only UDP, but rejects one
Service that combines TCP and UDP ports. Use the AWS Load Balancer Controller
when the generated Envoy Service combines protocols. For another cloud
provider, replace the envoyService map with that provider’s Service
configuration before applying it.
Create the GatewayClass with a parametersRef that points to the
EnvoyProxy resource:
Create Gateway
Create the Gateway resource with an HTTP listener on port 80, a TCP listener on port 10081 for gRPC, and a TCP listener on port 4222 for NATS.
gRPC worker callback listener
Split or multi-cluster gRPC invocation needs an additional TCP listener for the worker callback path. Add this listener only when enabling split or multi-cluster gRPC invocation.
The listener name must match
ingress.gatewayApi.routes.grpcWorker.listenerName.
The grpcWorker route is beta in 0.6.0. Enable it only when the control-plane
grpc-proxy runs one replica and the grpc-proxy HPA is disabled. Multiple
grpc-proxy replicas are not supported by this shared TCPRoute.
LLM worker listeners
LLM workers in another cluster or region need a TLS-terminated HTTP/2 path for
gRPC registration and watches, plus a UDP path for the reverse QUIC tunnel.
These paths are separate from the grpcWorker callback route.
The following example uses separate Gateways so the infrastructure can create
one HTTPS load balancer and one UDP load balancer. A provider that supports
mixed HTTPS and UDP listeners can use one Gateway for both listeners. In that case,
set llmGrpc.name and llmQuic.name to the same Gateway name.
Enable the chart-owned routes and reference the listener names:
The secure configuration above creates GRPCRoute/llm-worker-grpc,
UDPRoute/llm-worker-quic, ReferenceGrant/allow-llm-worker-routes, and an
Envoy BackendTrafficPolicy with the gRPC request timeout disabled. In
grpcTls.mode=certManager, it also creates the dedicated gRPC Certificate;
existingSecret mode uses the operator-owned Secret instead. Plaintext
development mode renders a TCPRoute and neither the policy nor the
Certificate. Both routes target
Service/llm-request-router-backend-router in the nvcf namespace on ports
50071 and 50072. The Service remains ClusterIP by design. Do not change it
to LoadBalancer or NodePort; the Gateway data-plane Service owns external
exposure.
The GRPCRoute deliberately omits hostnames, and its dedicated HTTPS
listener must omit hostname. The listener serves the dedicated certificate
for external-SNI verification, while Pylon keeps the selected Stargate pod
identity in HTTP/2 :authority so the backend router can forward each stream.
A listener hostname would constrain both values and reject the internal
authority. With grpcTls.mode: existingSecret, create the named Secret in the
Gateway namespace yourself; the chart renders no Certificate. Plaintext is
development-only and requires an explicit http:// dial URI plus
grpcTls.allowInsecureHttp: true.
Configure worker-facing HTTPS and UDP dial addresses as described in Remote compute clusters and regions.
Capture Gateway values
Wait for the Gateway to be programmed and export the values used by the install guides:
Use GATEWAY_ADDR as the route hostname suffix for test environments without
production DNS. Use your production domain instead when you configure DNS and
HTTPS.
Use Gateway values with install paths
Configure the CLI for Gateway access
For remote Helmfile deployments, configure the CLI after Gateway API ingress is available. The CLI calls API, API Keys, invocation, and gRPC endpoints during token minting, cluster registration, health checks, and function operations.
Do not leave literal shell variables in the YAML. If you use production DNS and
HTTPS, set STACK_DOMAIN to your production domain and update the URL schemes
and ports accordingly.
Gateway API Implementations
The nvcf-gateway-routes chart creates standard Kubernetes Gateway API
resources, including HTTPRoute, GRPCRoute, TCPRoute, UDPRoute, and
ReferenceGrant. Use a controller that supports every route kind enabled in
your environment.
Popular implementations include Envoy Gateway (used in our examples), Istio, Traefik, Kong, Contour, and cloud-native options like GKE Gateway Controller.
There is no service mesh requirement. Envoy Gateway is not a service mesh. It is a Gateway API controller. You don’t need service mesh features like mTLS between pods for NVCF to function. If you already have Istio or another service mesh, you can use its Gateway API support instead.
Minimum Requirements
Any Gateway API implementation you choose must support:
HTTPRoutefor HTTP/HTTPS routing with hostname matchingGRPCRoutefor HTTPS worker APIs and secure remote LLM registrationTCPRoutefor gRPC invocation, optional split or multi-cluster gRPC invocation, and NATS routing (requires experimental Gateway API CRDs)UDPRoutefor remote LLM reverse tunnels when thellmWorkerroute is enabled (requires experimental Gateway API CRDs)- Cross-namespace routing and
ReferenceGrantfor routes that reference Services in another namespace
TCPRoute and UDPRoute are experimental. Some Gateway API implementations
have limited support for them. Verify the controller’s supported versions
before deploying. Secure remote LLM workers require GRPCRoute and UDPRoute.
Using a Different Implementation
To use a different Gateway API implementation instead of Envoy Gateway:
-
Install your chosen controller following its documentation
-
Create namespaces with
nvcf/platform=truelabels as shown in Gateway quickstart -
Create a
GatewayClassfor your controller -
Create a
Gatewaywithhttp(port 80),tcp(port 10081), andnats(port 4222) listeners. Addworker-tcp(port 10086) only when enabling split or multi-cluster gRPC invocation. When remote LLM workers use the Gateway securely, addllm-grpcas an HTTPS listener on port 50071 with a TLS certificate reference, plusllm-quicas a UDP listener on port 50072. The renderedGRPCRouteattaches to the HTTPS listener. Use a TCPllm-grpclistener only for the explicit plaintext development mode withllmRequestRouter.grpcTls.allowInsecureHttp: true. -
Update your install configuration to reference your Gateway:
The nvcf-gateway-routes chart creates the enabled routes and attaches them to
the configured Gateways and listeners.
Not Using Gateway API
While technically possible to bypass the Gateway API entirely, this is not recommended:
- The
nvcf-gateway-routeschart specifically creates Gateway API resources - You would need to manually create and maintain all routing configuration
- Traditional Kubernetes Ingress does not provide
TCPRouteorUDPRoute - Multiple LoadBalancer services would require multiple external IPs
If you have a specific requirement that prevents using Gateway API, you would need to:
- Disable
nvcf-gateway-routesin your helmfile - Create your own Ingress or Service resources for each NVCF service
- Configure hostname routing manually
- Set up TCP load balancers for gRPC on port 10081, optional split or multi-cluster gRPC invocation on port 10086, and NATS on port 4222
- When serving remote LLM workers, terminate verified TLS with ALPN
h2on port 50071 and forward h2c tollm-request-router-backend-router; route UDP port 50072 to the same Service without bypassing its authority and SNI selection
Gateway Architecture
Components
The gateway architecture consists of two layers:
User-configured resources
These resources must be created manually before deploying the control plane:
- Namespaces with
nvcf/platform=truelabels - Gateway API controller installation (Envoy Gateway, Istio, Traefik, etc.)
GatewayClassresourceGatewayresource withhttp(port 80),tcp(port 10081), andnats(port 4222) listeners- Optional
worker-tcp(port 10086) listener for split or multi-cluster gRPC invocation - Optional
llm-grpc(HTTPS port 50071) andllm-quic(UDP port 50072) listeners for remote LLM workers
Resources created by nvcf-gateway-routes
When you deploy the control plane via helmfile, the nvcf-gateway-routes chart automatically creates:
HTTPRoutesfor API Keys, NVCF API, and Invocation services- Optional LLM invocation HTTPRoute when the
llmInvocationroute is enabled - Optional Vanity Gateway HTTPRoute only when the stack package includes the addon and the
vanityGatewayroute is enabled - Optional NVCF UI HTTPRoute only when the stack package includes the addon and the
nvcfUiroute is enabled TCPRoutefor gRPC- Optional
TCPRoutefor split or multi-cluster gRPC invocation when thegrpcWorkerroute is enabled - Optional
TCPRoutefor NATS when thenatsroute is enabled - Optional
UDPRouteplus aGRPCRoutefor secure LLM worker traffic or aTCPRoutefor plaintext development when thellmWorkerroute is enabled - Optional Envoy stream timeout policy when secure LLM worker routing has
grpcTls.enabled=true - Optional gRPC listener
Certificatewhen secure LLM worker routing usesgrpcTls.mode=certManager ReferenceGrantsfor cross-namespace routing permissions
These routes attach to the Gateway you prepared in Gateway quickstart.
Route Configuration
The <domain> is your Gateway’s load balancer address (e.g., a1b2c3d4.us-west-2.elb.amazonaws.com) or your custom domain. The helmfile deployment automatically configures the HTTPRoute hostnames using this value from your environment configuration.
When the LLM invocation route is enabled in self-managed deployments, send OpenAI-compatible requests to http://${GATEWAY_ADDR}/v1/... with Host: llm.invocation.${GATEWAY_ADDR} and set model to <function-id>/<model-name>.
Invocation Path Diagrams
For local and multi-cluster invocation-path diagrams, see Generic HTTP Function Invocation, gRPC Function Invocation, and LLM Gateway.
Vanity Gateway (Optional)
Vanity Gateway is disabled by default. It is available only in stack packages
that include the Vanity Gateway addon. If your extracted stack package does not
contain a vanity-gateway release and vanityGateway route values, skip this
section until you use a stack package that includes them.
Enable it only when you need a customer-facing hostname or mapping layer in front of the standard NVCF service routes. In Helmfile-based stack packages that include the addon, set:
By default, the route host is vanity.<domain> and the backend is
vanity-gateway.nvcf:8080. Use addons.vanityGateway.mappingConfig for the
host and path mappings required by your deployment. If you need custom vanity
hostnames instead of vanity.<domain>, configure the route hostname overrides
supported by your stack package, then create matching DNS records for those
hosts.
NVCF UI (Optional)
NVCF UI is optional and disabled by default. It is available only in
stack packages that include the NVCF UI addon. If your extracted stack
package does not contain a nvcf-ui release and nvcfUi route
values, skip this section until you use a stack package that includes them.
Enable it only when you need a customer-facing NVCF admin-panel UI.
The NVCF UI admin panel is currently unauthenticated. Do not expose it to the
public internet. Restrict access to a trusted network, VPN, or an
authenticating proxy in front of the nvcf-ui route.
In stack packages that include the addon, set the value shape in your environment file:
By default, the route host is nvcf-ui.<domain> and the backend is
nvcf-ui.nvcf-ui:8300.
How Routing Works
- The main Gateway’s LoadBalancer Service exposes ports 80 (HTTP), 10081 (gRPC), and 4222 (NATS) externally.
- HTTP requests arrive at port 80. The Gateway inspects the
Hostheader and matches it against HTTPRoute hostnames. - The matching HTTPRoute forwards the request to the appropriate backend service (e.g.,
api-keysservice on port 8080). - gRPC requests arrive at port 10081. The TCPRoute forwards all traffic directly to the
grpcservice. No hostname matching is required. - NATS connections arrive at port 4222. When enabled, the NATS TCPRoute forwards traffic directly to the NATS service.
- Remote LLM gRPC connections arrive at the configured
llmGrpclistener. The listener verifies and terminates TLS, then the GRPCRoute forwards h2c to the backend-router Service on port 50071 without changing:authority. - Remote LLM reverse tunnels arrive at the configured
llmQuiclistener. The UDPRoute forwards them to the same Service on port 50072. The TCP and UDP listeners can use separate Gateways and load balancers.
gRPC doesn’t need Host headers because it uses a dedicated TCP listener on port 10081. The gateway routes all traffic on that port directly to the gRPC service without hostname matching.
Verifying Gateway Configuration
After deploying the control plane, use these commands to verify your gateway configuration.
Get the Gateway Load Balancer Address
Verify HTTPRoute Hostnames
The gateway routes requests based on the Host header. Check what hostnames are configured:
If Vanity Gateway is disabled or your stack package does not include the addon,
the vanity-gateway HTTPRoute is not expected.
Verify TCPRoutes
Verify LLM worker routes
After applying the stack with llmWorker.enabled: true, verify both route
parents and the cross-namespace backend reference:
Each route parent must report Accepted=True and ResolvedRefs=True. The
Service type must remain ClusterIP, with TCP port 50071 and UDP port
50072. In cert-manager mode the dedicated certificate must be Ready. In
secure mode the request timeout must be 0s; plaintext mode does not render
the BackendTrafficPolicy. The zero timeout is the Envoy Gateway
v1.5-compatible setting that disables the default 15-second timeout for
streaming gRPC calls.
Also wait for each referenced Gateway to report
Programmed=True and confirm that its status contains an external address.
Verify the public certificate and ALPN without disabling validation:
Route status proves that the controller accepted the configuration. It does not prove that firewall rules, cross-region routing, DNS, or UDP forwarding work from a compute cluster. Test both external endpoints from every worker network before deploying production LLM functions.
Test Connectivity
Development: Host Header Routing
For development and testing when you don’t have DNS configured, you can use Host header overrides to route requests through the gateway.
Why Host Headers Are Needed
The Envoy Gateway uses hostname-based routing to direct traffic to different backend services through a single load balancer. When you send a request to the raw load balancer address (e.g., http://a1b2c3d4.elb.amazonaws.com), the gateway needs to know which service to route to.
Without the correct Host header, the gateway cannot match the request to an HTTPRoute and returns 404.
The NVCA agent on a self-managed GPU cluster has the same requirement when it reaches the control plane through a load-balancer-fronted gateway. Configure its host-header overrides in the operator values, not the CLI config. See self-managed-clusters.
Host header routing only works with plaintext HTTP traffic. Without TLS/SNI spoofing support in your client, you cannot use HTTPS with this method. The TLS handshake occurs before the Host header is sent, so the server cannot route based on a custom Host header when using HTTPS. For encrypted traffic, use proper DNS records as described in production-dns-https.
Configuring Host Headers
When using tools that support custom Host headers (like the NVCF CLI or curl), specify the expected hostname:
For the NVCF CLI, configure the *_host settings in your configuration file:
See cli-configuration for complete CLI configuration documentation.
Production: DNS and HTTPS
For production deployments, configure proper DNS and TLS to eliminate the need for Host header overrides.
Benefits
With proper DNS and HTTPS:
- DNS records resolve service hostnames (e.g.,
api-keys.nvcf.example.com) to your Gateway’s load balancer - TLS certificates secure all traffic
- Clients use simple URLs without Host header overrides
- Browsers and other clients can access services directly
Step 1: Choose a Domain
Select a domain you control for your NVCF deployment:
Step 2: Create DNS Records
Create DNS records pointing to your Gateway’s load balancer address:
AWS Route 53 example
Automate with external-dns. The nvcf-gateway-routes chart supports routeAnnotations for automatic DNS record creation via external-dns. See the chart’s README for configuration examples.
Step 3: Update HTTPRoute Hostnames
Update your helmfile environment to use your custom domain instead of the load balancer address:
Redeploy to update the HTTPRoute hostnames:
Verify the routes updated:
Step 4: Configure TLS (HTTPS)
For TLS, you have two main options:
Option A: TLS at the Load Balancer (recommended for AWS)
Terminate TLS at the AWS NLB using ACM certificates:
- Request a certificate in AWS Certificate Manager for
*.nvcf.example.com - Update the Gateway to use HTTPS listeners
Option B: TLS at the Gateway with cert-manager
Use cert-manager to automatically provision Let’s Encrypt certificates:
Then update your Gateway to use HTTPS listeners with the certificate secret.
Step 5: Update Client Configuration
With DNS and HTTPS configured, client configurations simplify significantly:
Development vs Production Comparison
Troubleshooting
404 Errors
If you receive 404 errors when accessing services:
-
Verify the Host header matches the HTTPRoute hostname:
-
Confirm the gateway is programmed:
-
Check route attachment:
Routes Not Attaching
If routes show 0 attached in gateway status:
-
Verify namespace labels:
-
Check
ReferenceGrantsexist: -
Review gateway listener configuration:
gRPC Connection Issues
For gRPC connection problems:
-
Verify port 10081 is exposed:
-
Test with
grpcurl: -
Check
TCPRoutestatus:
Related Documentation
- helmfile-installation - Helmfile values that consume Gateway quickstart outputs
- cli-configuration - CLI configuration including Host header settings
- Kubernetes Gateway API
- Envoy Gateway