Deploy the Open-Source AISIX Gateway on Kubernetes
The api7/aisix Helm chart deploys the open-source AISIX gateway on Kubernetes. Set controlPlane.enabled: false to run the gateway without a control plane or gateway certificate bundle and load its resources from a declarative resources.yaml file.
Provider keys, models, caller API keys, guardrails, MCP servers, and rate-limit policies all come from that file, while Kubernetes manages the gateway pods, Services, health checks, and rollouts. To deploy gateways for AISIX Cloud instead, follow Deploy AISIX Gateways on Kubernetes.
Prerequisites
- A Kubernetes cluster with
kubectlconfigured to access it. - Helm 3 and Docker.
- An upstream provider key and a caller API key. The examples use OpenAI and the model alias
gpt-4o-mini.
Prepare the Cluster and Credentials
Export the provider and caller credentials used by the examples:
# Replace with your OpenAI API key.
export OPENAI_API_KEY="YOUR_PROVIDER_API_KEY"
# Choose a caller API key for requests to AISIX.
export CALLER_API_KEY="YOUR_CALLER_API_KEY"
Add the chart repository, create a namespace, and store both credentials as Kubernetes Secrets:
helm repo add api7 https://charts.api7.ai
helm repo update
kubectl create namespace aisix
kubectl -n aisix create secret generic openai-credentials \
--from-literal=api-key="$OPENAI_API_KEY"
kubectl -n aisix create secret generic aisix-caller-keys \
--from-literal=my-caller="$CALLER_API_KEY"
Choose a Resource Source
controlPlane.enabled defaults to true. Each complete values.yaml below sets it to false and supplies resources.yaml from exactly one of three sources. Omitting the source, or setting more than one, causes Helm rendering to fail.
| Value | Where the file lives | Use it when |
|---|---|---|
standalone.resources | Inline in your values, as a YAML map. The chart renders it into a Secret it manages. | The file is managed together with the release. |
standalone.existingSecret | A Secret you create, under the key resources.yaml. | The file carries literal credentials, or something else owns its lifecycle. |
standalone.existingConfigMap | A ConfigMap you create, under the key resources.yaml. | Every credential in the file is a ${VAR} reference rather than a literal. |
Each installation example starts one gateway replica because rate-limit counters use per-replica memory by default. Configure shared Redis before increasing the replica count.
The chart renders standalone.resources into a Secret rather than a ConfigMap because provider keys are credentials. Credentials still do not have to sit in your values file: a ${VAR} reference is resolved from the container's environment when the file loads, so supply the value through extraEnvVars instead. See Environment Interpolation.
Choose one option below. The Secret and ConfigMap options begin with the same file-preparation step. Each option provides a complete values.yaml, then continues at Install the Gateway.
Use Inline Resources
Save the following chart values as values.yaml. The chart stores the inline resource document in a Secret, while the two credential values remain in the separate Secrets created above:
replicaCount: 1
image:
repository: ghcr.io/api7/aisix
tag: dev
controlPlane:
enabled: false
standalone:
resources:
_format_version: "1"
provider_keys:
- display_name: openai-main
provider: openai
adapter: openai
api_key: ${OPENAI_API_KEY}
api_base: https://api.openai.com/v1
models:
- display_name: gpt-4o-mini
provider: openai
model_name: gpt-4o-mini
provider_key: openai-main
api_keys:
- display_name: my-caller
key_env: CALLER_API_KEY
allowed_models:
- gpt-4o-mini
extraEnvVars:
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: openai-credentials
key: api-key
- name: CALLER_API_KEY
valueFrom:
secretKeyRef:
name: aisix-caller-keys
key: my-caller
Inline resources do not exist as a separate file to validate. Before installing, render the chart-managed Secret and extract the exact resource document assembled from values.yaml:
helm template aisix api7/aisix --namespace aisix \
-f values.yaml --show-only templates/secret.yaml |
awk '
/^ resources\.yaml: \|$/ { in_resources = 1; next }
in_resources && /^---$/ { exit }
in_resources { sub(/^ /, ""); print }
' > rendered-resources.yaml
Validate that rendered document with the credentials it references:
docker run --rm -v "$(pwd):/work:ro" \
-e OPENAI_API_KEY -e CALLER_API_KEY \
--entrypoint /usr/local/bin/aisix ghcr.io/api7/aisix:dev \
validate --resources /work/rendered-resources.yaml
Prepare a Resources File
The Secret and ConfigMap options both start with a local file. Create resources.yaml with the Open-Source AISIX Gateway Quickstart and Resources File Reference. Keep the ${OPENAI_API_KEY} and key_env: CALLER_API_KEY references from the quickstart.
Validate the file with the same environment variables that the gateway will receive. The validate subcommand parses the file without binding a listener:
docker run --rm -v "$(pwd):/work:ro" \
-e OPENAI_API_KEY -e CALLER_API_KEY \
--entrypoint /usr/local/bin/aisix ghcr.io/api7/aisix:dev \
validate --resources /work/resources.yaml
Use an Existing Secret
Store the validated file in a Secret:
kubectl -n aisix create secret generic aisix-resources \
--from-file=resources.yaml=./resources.yaml
Save the following chart values as values.yaml. extraEnvVars makes the credential variables referenced by resources.yaml available to the gateway container:
replicaCount: 1
image:
repository: ghcr.io/api7/aisix
tag: dev
controlPlane:
enabled: false
standalone:
existingSecret: aisix-resources
extraEnvVars:
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: openai-credentials
key: api-key
- name: CALLER_API_KEY
valueFrom:
secretKeyRef:
name: aisix-caller-keys
key: my-caller
Use an Existing ConfigMap
Use a ConfigMap only when every credential in the validated resources.yaml file is an environment-variable reference. Create the ConfigMap:
kubectl -n aisix create configmap aisix-resources \
--from-file=resources.yaml=./resources.yaml
Save the following chart values as values.yaml:
replicaCount: 1
image:
repository: ghcr.io/api7/aisix
tag: dev
controlPlane:
enabled: false
standalone:
existingConfigMap: aisix-resources
extraEnvVars:
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: openai-credentials
key: api-key
- name: CALLER_API_KEY
valueFrom:
secretKeyRef:
name: aisix-caller-keys
key: my-caller
Install the Gateway
Install the gateway from values.yaml:
helm install aisix api7/aisix --namespace aisix -f values.yaml
Verify the Deployment
Wait for the gateway Deployment to become available:
kubectl rollout status deployment/aisix --namespace aisix --timeout=5m
In a separate terminal, forward the proxy Service to your workstation:
kubectl -n aisix port-forward service/aisix 3000:80
Back in the original terminal, check readiness and list the models available to the caller key:
export AISIX_PROXY="http://127.0.0.1:3000"
curl -sS "$AISIX_PROXY/readyz"
curl -sS "$AISIX_PROXY/v1/models" \
-H "Authorization: Bearer $CALLER_API_KEY"
The readiness request should return ok, and the model list should contain gpt-4o-mini. Send a request through the gateway to verify the provider credential and upstream connection:
curl -sS "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer $CALLER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "Reply with: AISIX is ready"
}
]
}'
A successful response should contain the assistant message AISIX is ready. This confirms that the gateway loaded the resources and credentials, authenticated the caller, and reached the upstream provider.
What the Chart Configures
The chart mounts the resources file read-only at /etc/aisix/resources/resources.yaml. It renders the gateway's startup configuration from the config value into a ConfigMap, mounted read-only at /etc/aisix/chart/config.yaml, and fills in the keys it owns for standalone mode:
resources_file: /etc/aisix/resources/resources.yaml
admin:
enabled: false
With admin.enabled: true, the chart renders admin.enabled: true and an admin.addr that binds containerPorts.admin instead. See Enable the Admin API.
The chart also sets the proxy and metrics listener addresses and the rate-limit backend from its own values. Set any other startup configuration field under config, with the same section and key names as the configuration file. For example, this enables debug logging:
config:
observability:
log_level: debug
A change to config rolls the pods on helm upgrade. Settings that hold a credential, such as a Redis password, are read from a Secret through configSecrets instead. See Set Any Other Gateway Configuration for the keys the chart refuses under config and for configSecrets.
extraEnvVars is for system-level environment variables and for the variables the resources file references. Overriding a variable the chart sets itself is only a compatibility path for existing deployments; see Set Any Other Gateway Configuration.
The chart also sets enableServiceLinks: false on the gateway pods. Kubernetes would otherwise inject a Docker-style link variable for every Service in the namespace. A Service named aisix or aisix-something produces variables with the AISIX_ prefix that the gateway reads. See Kubernetes Service Links.
Apply a Change to the Resources File
The gateway re-reads resources.yaml on SIGHUP only, and the chart never sends one. A pod rollout is what applies a change.
-
Inline resources. Edit
standalone.resourcesand runhelm upgrade. The pod template carries a checksum of the rendered file, so the change rolls the pods on its own. -
An existing Secret or ConfigMap. Editing the object out of band does not roll anything — Kubernetes updates the mounted file in place and nothing tells the gateway. Apply it explicitly:
kubectl rollout restart deploy/<release>-aisix -n <namespace>
The chart prints the right command for your installation in its post-install notes.
Health Checks
Both probes target the proxy port. /livez answers once the proxy listener is bound. /readyz answers 200 when the instance can serve and 503 while it is draining. Against a file source, the listener binds as soon as the file parses, so the gateway does not wait on a configuration fetch. See Health Checks.
Expose, Scale, and Operate
Service exposure, autoscaling, Redis rate-limit counters, pod disruption budgets, termination, and draining do not depend on how the gateway receives resources. Deploy AISIX Gateways on Kubernetes covers these shared Kubernetes operations.
Configure a shared Redis backend before running more than one replica. Rate-limit counters are per-replica by default, so N replicas enforce N times every configured limit.
The listeners values work the same way here. An open-source gateway can serve HTTPS and plain HTTP side by side; see Serve HTTPS and Plain HTTP Together.
To see every value the chart accepts:
helm show values api7/aisix
The chart source is published in the api7/api7-helm-chart repository.
Enable the Admin API
The chart leaves the gateway's Admin API off by default. Set admin.enabled: true to bind it on containerPorts.admin (default 3001) and publish it on its own ClusterIP Service, <fullname>-admin, which is aisix-admin for a release named aisix. The proxy Service never carries it.
Against the resources file, /admin/v1/* is read-only: it lists and gets what the gateway loaded, including model status. Every request there needs one of the admin keys, sent as Authorization: Bearer <key> or x-api-key: <key>.
The same listener also serves the Playground, POST /playground/chat/completions. It authenticates with a caller API key, exactly like the proxy, and sends real requests to your upstream providers. Read-only applies to /admin/v1/* only, so treat access to the admin Service as access to the proxy.
Store the admin keys in a Secret you manage, so they stay out of your values file:
# Choose an admin API key.
export AISIX_ADMIN_KEY="YOUR_ADMIN_API_KEY"
kubectl -n aisix create secret generic aisix-admin-keys \
--from-literal=admin-keys="$AISIX_ADMIN_KEY"
Add the following to values.yaml:
admin:
enabled: true
existingSecret: aisix-admin-keys
| Value | Default | Description |
|---|---|---|
admin.enabled | false | Bind the Admin API and create the admin Service. |
admin.keys | [] | Admin keys, rendered into a chart-managed Secret. |
admin.existingSecret | "" | Read the admin keys from an existing Secret instead. |
admin.existingSecretKey | admin-keys | Key in admin.existingSecret that holds the admin keys. Several keys are separated by commas. |
containerPorts.admin | 3001 | Port the Admin API binds inside the container. |
admin.service.port | 3001 | Port of the admin Service. |
admin.service.annotations | {} | Extra annotations for the admin Service. |
Either way, the keys reach the gateway as the AISIX_ADMIN__ADMIN_KEYS environment variable from the Secret and are never written to the configuration ConfigMap. The gateway reads that variable as a comma-separated list, so an admin key cannot contain a comma.
The render fails if admin.enabled is true without keys from admin.keys or admin.existingSecret. It also fails if controlPlane.enabled is true: the Admin API is available in standalone mode only, because a gateway connected to a control plane has no Admin API.
Apply the values, then forward the admin Service when you need it:
helm upgrade aisix api7/aisix --namespace aisix -f values.yaml
kubectl rollout status deployment/aisix --namespace aisix --timeout=5m
kubectl -n aisix port-forward svc/aisix-admin 3001:3001
In another terminal, list the models the gateway loaded:
curl "http://127.0.0.1:3001/admin/v1/models" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}"
A release that already binds the Admin API through AISIX_ADMIN__* variables in extraEnvVars keeps working, because the environment overrides the configuration file. Moving those settings to admin also gives the API its Service.
Migrate to AISIX Cloud
The open-source gateway does not include the AISIX Cloud dashboard, organizations and environments, centralized usage and cost reporting, budgets, or per-environment configuration delivery. Export logs and metrics to systems you operate instead; see Exporters.
Deploy a gateway through AISIX Cloud and issue its gateway certificate from the control plane. Resources are not carried over; recreate them in AISIX Cloud as described in Plan a Migration.