Every team in your organization wants to call an LLM. As the platform operator, you have two options: hand each team a raw provider key and lose track of it forever, or put a gateway you control between them and the provider. This page sets up the second option.
With the AI gateway enabled, tenants call one OpenAI-compatible endpoint using keys they issue themselves. The real provider credentials (OpenAI, Anthropic, Azure, Bedrock, …) exist only in the management cluster. Budgets, metering, and attribution come with it; those are covered in Budgets & Virtual Keys.
The multi-tenant layer (virtual keys, budgets, metering) is an Enterprise Edition feature. The agentgateway addon itself and the direct data-plane usage below work in both editions.
The data plane is agentgateway, an Envoy-based proxy built for LLM traffic, Model Context Protocol (MCP) servers, and Agent-to-Agent (A2A) connectivity. It ships as an addon in the kubelb-addons chart; KubeLB configures it, but you can also drive it directly.
Turn on the addons and the manager feature in the kubelb-manager chart values:
kubelb:
enableGatewayAPI: true
enableAIGateway: true
kubelb-addons:
enabled: true
agentgateway-crds:
enabled: true
agentgateway:
enabled: true
# Required for inline Day-window budget enforcement:
valkey:
enabled: true
ratelimit:
enabled: true
Nothing happens yet. The manager reconciles only once spec.ai.enabled is set on the Config, so an upgrade with the flag on changes nothing until you opt in:
apiVersion: kubelb.k8c.io/v1alpha1
kind: Config
metadata:
name: default
namespace: kubelb
spec:
ai:
enabled: true
defaultBudgets:
- tokens: 50000000
window: Month
onExceed: Block
alertThresholdPercent: 80
rateLimitService:
name: kubelb-ratelimit
namespace: kubelb
port: 8081
virtualKeys:
limit: 20 # max keys per tenant
maxTTL: 720h # default and ceiling for key expiry
Individual tenants can be opted out, given different budgets, or given a different key quota on their Tenant resource. The budget and key settings are explained in Budgets & Virtual Keys.
You author provider backends yourself as AgentgatewayBackend resources in the kubelb namespace. KubeLB deliberately does not render these: which providers exist, and under which commercial account, is your call.
The provider API key lives in a management-cluster Secret. Tenants never see it. They authenticate with their own virtual keys, and the gateway swaps in the real credential on the way out. Rotating a provider key is a one-Secret update, with no tenant involvement.
apiVersion: v1
kind: Secret
metadata:
name: openai-credentials
namespace: kubelb
type: Opaque
stringData:
Authorization: sk-proj-... # key MUST be named "Authorization"
---
apiVersion: agentgateway.dev/v1alpha1
kind: AgentgatewayBackend
metadata:
name: openai
namespace: kubelb
spec:
ai:
provider:
openai: {} # model taken from the request when unset
policies:
auth:
secretRef:
name: openai-credentials
The Authorization data key is an agentgateway convention: the credential from that key is sent as Authorization: Bearer <value> to the provider.
Attach the backend to the managed kubelb-ai Gateway with an HTTPRoute:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: openai
namespace: kubelb
spec:
parentRefs:
- name: kubelb-ai
namespace: kubelb
rules:
- backendRefs:
- name: openai
namespace: kubelb
group: agentgateway.dev
kind: AgentgatewayBackend
KubeLB applies a passive-health policy to every backend automatically: responses with status >= 500 or 429 count as failures, and an endpoint is evicted after 3 consecutive failures. Failover between providers works without any per-backend configuration.
With spec.ai.enabled, the manager renders and solely owns these objects in the kubelb namespace:
| Resource | Name | Purpose |
|---|---|---|
| Gateway | kubelb-ai |
Shared entry point, class agentgateway |
| AgentgatewayPolicy | kubelb-ai |
Key auth, metric + access-log attribution, global rate limit |
| AgentgatewayPolicy | kubelb-ai-backend-health |
Passive health for all backends |
| Secret | ai-keys-<tenant> |
Per-tenant virtual keys |
| ConfigMap | ratelimit-config |
Day-window descriptors for the rate-limit service |
Do not hand-edit them; the manager reverts your changes on the next reconcile.
agentgateway merges policies field by field, but a singular field (apiKeyAuthentication, rateLimit, jwtAuthentication, mcp) set by two policies on the same target does not compose: one of the two is silently dropped, while both still report Attached: True. There is no error and no log line. Do not attach your own AgentgatewayPolicy that sets one of those fields to the kubelb-ai Gateway. Policies that set different fields, such as authorization rules or jwtAuthentication on your own routes, merge with the managed policy and are safe.
Key Secrets survive a disable: turning AI off for a tenant or globally preserves the ai-keys-* Secrets, so re-enabling does not re-issue anyone’s keys. They are removed only when the Tenant resource itself is deleted.
To switch the feature off, set Config.spec.ai.enabled: false first and let the manager clean up. Only then, optionally, remove enableAIGateway from the chart values. Removing the flag first strands the rendered resources with nothing left to clean them up.
The addon is a full gateway in its own right. You can create your own Gateway with the agentgateway GatewayClass and author backends and routes against it, with no multi-tenant layer involved. Today that is how MCP and A2A traffic is exposed.
agentgateway federates one or more Model Context Protocol servers behind a single endpoint. The same AgentgatewayBackend CRD is used, with an mcp spec instead of ai:
apiVersion: agentgateway.dev/v1alpha1
kind: AgentgatewayBackend
metadata:
name: mcp-backend
namespace: kubelb
spec:
mcp:
targets:
- name: mcp-target
backendRef:
name: mcp-website-fetcher
port: 80
protocol: SSE
backendRef.name must resolve to a Kubernetes Service in the same namespace as the AgentgatewayBackend. Attach it with an HTTPRoute scoped to the /mcp path prefix so MCP traffic is kept apart from LLM backends:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: mcp
namespace: kubelb
spec:
parentRefs:
- name: kubelb-ai
namespace: kubelb
rules:
- matches:
- path:
type: PathPrefix
value: /mcp
backendRefs:
- name: mcp-backend
namespace: kubelb
group: agentgateway.dev
kind: AgentgatewayBackend
For static vs. dynamic targets, virtual MCP aggregation, tool-level access control, JWT auth, and rate limiting, see the MCP connectivity guide.
agentgateway also proxies A2A traffic for connecting AI agents through the gateway. See the Agent connectivity guide.
All AI gateway images (agentgateway proxy and controller, rate-limit service, valkey) are digest-pinned in the image lists shipped with each release, and the addon subcharts honour global.imageRegistry. See Air-Gapped Installation.