Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ Detailed instructions are enrolled in the README of each chart.
* [api7-control-plane](./charts/api7/README.md)
* [api7-gateway](./charts/gateway/README.md)
* [api7-ingress-controller](./charts/ingress-controller/README.md)
* [aisix](./charts/aisix/README.md)
13 changes: 13 additions & 0 deletions charts/aisix/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Patterns to ignore when building packages.
.DS_Store
.git/
.gitignore
.gitmodules
*.swp
*.bak
*.tmp
*.orig
*~
.vscode/
*.tmproj
.idea/
6 changes: 6 additions & 0 deletions charts/aisix/Chart.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dependencies:
- name: etcd
repository: https://charts.bitnami.com/bitnami
version: 8.7.7
digest: sha256:c03ff5323e855335d94ce6cfce35745b84d03538dbb197e1a27520a7d69ea3ef
generated: "2026-04-15T17:14:56.064889296+08:00"
20 changes: 20 additions & 0 deletions charts/aisix/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: v2
name: aisix
description: A Helm chart for AISIX AI Gateway

type: application

version: 0.1.0

appVersion: "0.1.0"

maintainers:
- name: API7
email: support@api7.ai
url: https://api7.ai

dependencies:
- name: etcd
version: 8.7.7
repository: https://charts.bitnami.com/bitnami
condition: etcd.enabled
65 changes: 65 additions & 0 deletions charts/aisix/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# AISIX Helm Chart

A Helm chart for [AISIX](https://github.com/api7/aisix) — an open source, high-performance AI Gateway and LLM proxy built in Rust.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

## Prerequisites

- Kubernetes 1.21+
- Helm 3.7+

## Installing the Chart

```bash
helm repo add api7 https://charts.api7.ai
helm repo update

helm install my-aisix api7/aisix \
--set deployment.admin.adminKey[0].key=<your-admin-key>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
```

## Uninstalling the Chart

```bash
helm uninstall my-aisix
```

## Configuration

The following table lists the key configurable parameters. See `values.yaml` for the full list.

| Parameter | Description | Default |
|-----------|-------------|---------|
| `image.repository` | AISIX image repository | `ghcr.io/api7/aisix` |
Comment thread
AlinsRan marked this conversation as resolved.
Outdated
| `image.tag` | AISIX image tag | `0.1.0` |
| `replicaCount` | Number of replicas | `1` |
Comment thread
AlinsRan marked this conversation as resolved.
Outdated
| `deployment.admin.adminKey` | Admin API key list | `[{key: "changeme"}]` |
| `deployment.admin.existingSecret` | Existing Secret for admin key | `""` |
| `deployment.etcd.host` | External etcd hosts (when `etcd.enabled=false`) | `["http://etcd.host:2379"]` |
| `deployment.etcd.prefix` | etcd key prefix | `/aisix` |
| `server.proxy.listen` | Proxy API listen address | `0.0.0.0:3000` |
| `server.admin.listen` | Admin API listen address | `0.0.0.0:3001` |
| `proxyService.type` | Proxy Service type | `NodePort` |
| `adminService.type` | Admin Service type | `ClusterIP` |
| `etcd.enabled` | Install bundled etcd | `true` |
Comment thread
AlinsRan marked this conversation as resolved.
Outdated
| `ingress.enabled` | Enable Ingress for proxy | `false` |
| `adminIngress.enabled` | Enable Ingress for admin | `false` |
| `autoscaling.enabled` | Enable HPA | `false` |

## Using an Existing Secret for the Admin Key

```bash
kubectl create secret generic aisix-admin-secret \
--from-literal=admin-key=<your-strong-key>

helm install my-aisix api7/aisix \
--set deployment.admin.existingSecret=aisix-admin-secret
```

## Using an External etcd

```bash
helm install my-aisix api7/aisix \
--set etcd.enabled=false \
--set deployment.etcd.host[0]="http://my-etcd:2379" \
--set deployment.admin.adminKey[0].key=<your-admin-key>
```
Binary file added charts/aisix/charts/etcd-8.7.7.tgz
Binary file not shown.
33 changes: 33 additions & 0 deletions charts/aisix/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
AISIX has been installed. Check its status by running:
kubectl --namespace {{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ include "aisix.name" . }}"

1. Get the Proxy API URL:
{{- if .Values.ingress.enabled }}
{{- range .Values.ingress.hosts }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ .host }}
{{- end }}
{{- else if eq .Values.proxyService.type "NodePort" }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "aisix.fullname" . }}-proxy)
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo "Proxy API: http://$NODE_IP:$NODE_PORT"
{{- else if eq .Values.proxyService.type "LoadBalancer" }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "aisix.fullname" . }}-proxy --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo "Proxy API: http://$SERVICE_IP:{{ .Values.proxyService.port }}"
{{- else }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "aisix.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 3000:{{ .Values.proxyService.containerPort }}
echo "Proxy API: http://127.0.0.1:3000"
{{- end }}

2. Get the Admin UI URL:
{{- if .Values.adminIngress.enabled }}
{{- range .Values.adminIngress.hosts }}
http{{ if $.Values.adminIngress.tls }}s{{ end }}://{{ .host }}/ui
{{- end }}
{{- else }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "aisix.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 3001:{{ .Values.adminService.containerPort }}
echo "Admin UI: http://127.0.0.1:3001/ui"
echo "Admin API: http://127.0.0.1:3001/aisix/admin"
{{- end }}
92 changes: 92 additions & 0 deletions charts/aisix/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "aisix.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "aisix.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "aisix.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "aisix.labels" -}}
helm.sh/chart: {{ include "aisix.chart" . }}
{{ include "aisix.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "aisix.selectorLabels" -}}
app.kubernetes.io/name: {{ include "aisix.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "aisix.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "aisix.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

{{/*
Scheme to use while connecting etcd
*/}}
{{- define "aisix.etcd.scheme" -}}
{{- if .Values.etcd.auth.tls.enabled }}
{{- "https" }}
{{- else }}
{{- "http" }}
{{- end }}
{{- end }}

{{/*
Etcd host URL(s) to inject into config.yaml.
When etcd subchart is enabled, construct the in-cluster FQDN automatically.
When disabled, use the user-supplied deployment.etcd.host list.
*/}}
{{- define "aisix.etcd.hosts" -}}
{{- if .Values.etcd.enabled }}
{{- $scheme := include "aisix.etcd.scheme" . }}
{{- if .Values.etcd.fullnameOverride }}
- "{{ $scheme }}://{{ .Values.etcd.fullnameOverride }}:{{ .Values.etcd.service.port }}"
{{- else }}
- "{{ $scheme }}://{{ .Release.Name }}-etcd.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.etcd.service.port }}"
{{- end }}
{{- else }}
{{- toYaml .Values.deployment.etcd.host }}
{{- end }}
{{- end }}
32 changes: 32 additions & 0 deletions charts/aisix/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "aisix.fullname" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "aisix.labels" . | nindent 4 }}
data:
config.yaml: |-
deployment:
etcd:
host:
{{- include "aisix.etcd.hosts" . | nindent 10 }}
prefix: {{ .Values.deployment.etcd.prefix | quote }}
timeout: {{ .Values.deployment.etcd.timeout }}
admin:
admin_key:
{{- if .Values.deployment.admin.existingSecret }}
- key: "{{"{{"}}AISIX_ADMIN_KEY{{"}}"}}"
{{- else }}
{{- toYaml .Values.deployment.admin.adminKey | nindent 10 }}
{{- end }}
Comment thread
AlinsRan marked this conversation as resolved.
Outdated

server:
proxy:
listen: {{ .Values.server.proxy.listen | quote }}
tls:
enabled: {{ .Values.server.proxy.tls.enabled }}
cert_file: {{ .Values.server.proxy.tls.certFile | quote }}
key_file: {{ .Values.server.proxy.tls.keyFile | quote }}
admin:
listen: {{ .Values.server.admin.listen | quote }}
119 changes: 119 additions & 0 deletions charts/aisix/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "aisix.fullname" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "aisix.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "aisix.selectorLabels" . | nindent 6 }}
{{- if .Values.updateStrategy }}
strategy: {{ toYaml .Values.updateStrategy | nindent 4 }}
{{- end }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
Comment thread
AlinsRan marked this conversation as resolved.
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "aisix.selectorLabels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.global.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
Comment thread
AlinsRan marked this conversation as resolved.
Outdated
{{- end }}
serviceAccountName: {{ include "aisix.serviceAccountName" . }}
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.extraInitContainers }}
initContainers:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: aisix
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: proxy
containerPort: {{ .Values.proxyService.containerPort }}
protocol: TCP
- name: admin
containerPort: {{ .Values.adminService.containerPort }}
protocol: TCP
{{- if .Values.livenessProbe }}
livenessProbe:
{{- toYaml .Values.livenessProbe | nindent 12 }}
{{- end }}
{{- if .Values.readinessProbe }}
readinessProbe:
{{- toYaml .Values.readinessProbe | nindent 12 }}
{{- end }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
env:
{{- if .Values.timezone }}
- name: TZ
value: {{ .Values.timezone | quote }}
{{- end }}
- name: RUST_LOG
value: "info"
{{- if .Values.deployment.admin.existingSecret }}
- name: AISIX_ADMIN_KEY
valueFrom:
secretKeyRef:
name: {{ .Values.deployment.admin.existingSecret }}
key: {{ .Values.deployment.admin.existingSecretKey }}
{{- end }}
{{- with .Values.extraEnvVars }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- if .Values.extraEnvVarsCM }}
envFrom:
- configMapRef:
name: {{ .Values.extraEnvVarsCM }}
Comment thread
AlinsRan marked this conversation as resolved.
Outdated
Comment thread
AlinsRan marked this conversation as resolved.
Outdated
{{- end }}
volumeMounts:
- name: aisix-config
mountPath: /etc/aisix/config.yaml
subPath: config.yaml
readOnly: true
{{- with .Values.extraVolumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
volumes:
- name: aisix-config
configMap:
name: {{ include "aisix.fullname" . }}
{{- with .Values.extraVolumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
Loading
Loading