helm/README.md
Rama main · réplica de lectura del repositorio original.
# GoModel Helm chart
Deploys [GoModel](https://gomodel.enterpilot.io), an OpenAI-compatible AI gateway, on Kubernetes.
## Quick start
```bash
helm install gomodel ./helm -n gomodel --create-namespace \
--set secretEnv.GOMODEL_MASTER_KEY=change-me \
--set secretEnv.OPENAI_API_KEY=sk-...
kubectl -n gomodel port-forward svc/gomodel 8080:8080
curl -H "Authorization: Bearer change-me" http://127.0.0.1:8080/v1/models
```
The default install runs one pod with SQLite on a 1Gi PersistentVolumeClaim,
Prometheus metrics on `/metrics`, a read-only root filesystem, and the image's
non-root user (UID 65532).
## Configuration
GoModel is configured entirely through environment variables. Any variable from
[`.env.template`](../.env.template) goes in one of two maps:
| Value | Stored in | Use for |
| ----------- | --------- | -------------------------------------------------- |
| `env` | ConfigMap | Plain settings: `LOG_LEVEL`, `REDIS_URL`, `BASE_PATH`, … |
| `secretEnv` | Secret | `GOMODEL_MASTER_KEY`, provider API keys, database URLs |
Changing either rolls the pods. To keep secrets out of Helm values, create the
Secret yourself and reference it:
```yaml
extraEnvFrom:
- secretRef:
name: gomodel-keys # keys: GOMODEL_MASTER_KEY, OPENAI_API_KEY, ...
```
Set `GOMODEL_MASTER_KEY`. Without it the gateway accepts unauthenticated requests
and the install notes print a warning.
### config.yaml
Use `config` for settings that env vars cannot express (per-provider resilience,
custom provider names, model allowlists). It is mounted at
`/app/config/config.yaml`; env vars still override it.
```yaml
config: |
providers:
openai-eu:
type: openai
api_key: ${OPENAI_EU_API_KEY}
base_url: https://eu.api.openai.com/v1
```
Or point `existingConfigMap` at a ConfigMap that has a `config.yaml` key.
### Storage and replicas
| `storage.type` | Replicas | Data location |
| -------------- | -------- | ---------------------------------------------- |
| `sqlite` | 1 | PVC at `/app/data` (`persistence.enabled: true`) |
| `postgresql` | any | `storage.url` or `POSTGRES_URL` |
| `mongodb` | any | `storage.url` or `MONGODB_URL` |
SQLite is per pod, so the chart refuses `replicaCount > 1` or autoscaling until
you switch to PostgreSQL or MongoDB:
```yaml
replicaCount: 3
storage:
type: postgresql
url: postgres://gomodel:secret@postgresql:5432/gomodel
```
`storage.url` lands in the chart Secret. If the URL already lives in a Secret of
your own, load it through `extraEnvFrom` or an `extraEnv` entry named
`POSTGRES_URL` / `MONGODB_URL` instead and leave `storage.url` empty.
`helm uninstall` deletes the claim with the release. To keep the database, add
`persistence.annotations: {helm.sh/resource-policy: keep}`.
With SQLite on a ReadWriteOnce volume the Deployment uses the `Recreate`
strategy, so upgrades briefly stop the gateway. Set `persistence.enabled: false`
for a throwaway install; the data then lives on an emptyDir and is lost when the
pod is replaced.
### Exposing the gateway
Ingress:
```yaml
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt
hosts:
- host: gomodel.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: gomodel-tls
hosts: [gomodel.example.com]
```
Gateway API:
```yaml
httpRoute:
enabled: true
parentRefs:
- name: public-gateway
namespace: gateway-system
hostnames: [gomodel.example.com]
```
To serve under a path prefix set `env.BASE_PATH: /g`; probe, metrics and
HTTPRoute paths follow automatically.
For pod-to-pod HTTPS without an ingress, mount a certificate Secret through
`extraVolumes`/`extraVolumeMounts` and set `env.SERVER_TLS_CERT_FILE` and
`env.SERVER_TLS_KEY_FILE`; both probes (unless a probe sets its own
`httpGet.scheme`), `helm test` and the port-forward install notes switch to
HTTPS on their own. The ServiceMonitor scrapes
plain HTTP, so define your own with `scheme: https`. With mTLS
(`env.SERVER_TLS_CLIENT_CA_FILE`) `/metrics` needs a client certificate too, so
give it a `tlsConfig` with `ca` for the gateway's CA plus `cert` and `keySecret`. See
[Native TLS](https://gomodel.enterpilot.io/guides/production#native-tls) for a
cert-manager example.
### Metrics
`metrics.enabled` (default `true`) exposes `/metrics` without authentication.
With the Prometheus Operator, set `metrics.serviceMonitor.enabled: true` and add
the labels your Prometheus selects on under `metrics.serviceMonitor.labels`.
### Cloud provider credentials
Give the pod's ServiceAccount a cloud identity for AWS Bedrock or Google Vertex AI:
```yaml
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/gomodel
```
## Values
| Key | Default | Description |
| --- | --- | --- |
| `replicaCount` | `1` | Pods. More than one needs `storage.type` postgresql or mongodb. |
| `image.repository` | `enterpilot/gomodel` | |
| `image.tag` | `""` | Defaults to the chart `appVersion`. |
| `env` | `{}` | Plain environment variables. |
| `secretEnv` | `{}` | Secret environment variables. |
| `extraEnvFrom` | `[]` | Existing Secrets/ConfigMaps loaded as env vars. |
| `extraEnv` | `[]` | Raw container env entries (`valueFrom`). |
| `config` | `""` | Inline `config.yaml`. |
| `existingConfigMap` | `""` | ConfigMap with a `config.yaml` key. |
| `storage.type` | `sqlite` | `sqlite`, `postgresql`, or `mongodb`. |
| `storage.url` | `""` | Connection URL for postgresql/mongodb. |
| `persistence.enabled` | `true` | PVC for SQLite data. |
| `persistence.size` | `1Gi` | |
| `persistence.storageClass` | `""` | Cluster default. `-` disables dynamic provisioning. |
| `persistence.existingClaim` | `""` | Reuse a PVC. |
| `updateStrategy` | `{}` | Overrides the automatic Recreate/RollingUpdate choice. |
| `metrics.enabled` | `true` | Expose `/metrics`. |
| `metrics.serviceMonitor.enabled` | `false` | Prometheus Operator ServiceMonitor. |
| `service.type` | `ClusterIP` | |
| `service.port` | `8080` | |
| `ingress.enabled` | `false` | |
| `httpRoute.enabled` | `false` | Gateway API HTTPRoute; needs `httpRoute.parentRefs`. |
| `serviceAccount.create` | `true` | |
| `serviceAccount.annotations` | `{}` | Cloud IAM bindings. |
| `resources` | `100m/128Mi` requests, `512Mi` limit | No CPU limit by default. |
| `autoscaling.enabled` | `false` | HPA on CPU (70%) and optionally memory. |
| `podDisruptionBudget.enabled` | `true` | Created only when more than one pod can run. |
| `terminationGracePeriodSeconds` | `45` | Covers GoModel's 30s drain. |
| `livenessProbe` / `readinessProbe` | `/health`, `/health/ready` | Readiness fails while storage is down. |
| `podSecurityContext` / `securityContext` | non-root 65532, read-only FS | |
| `extraVolumes` / `extraVolumeMounts` | `[]` | CA bundles, local model catalogs, … |
| `nodeSelector`, `tolerations`, `affinity`, `topologySpreadConstraints`, `priorityClassName`, `podAnnotations`, `podLabels` | | Standard scheduling knobs. |
## Upgrading from chart 0.1.x
Chart 0.2.0 replaced the per-provider values and the Redis subchart with the
generic `env` / `secretEnv` maps:
| 0.1.x | 0.2.0 |
| --- | --- |
| `auth.masterKey` | `secretEnv.GOMODEL_MASTER_KEY` |
| `providers.openai.apiKey` | `secretEnv.OPENAI_API_KEY` (same pattern for every provider) |
| `providers.openai.baseUrl` | `env.OPENAI_BASE_URL` |
| `providers.existingSecret` | `extraEnvFrom: [{secretRef: {name: ...}}]` |
| `redis.enabled` / `cache.redis.url` | `env.REDIS_URL` pointing at your own Redis |
| `gateway.*` | `httpRoute.*` |
| `server.basePath` | `env.BASE_PATH` |
The chart refuses to render while any of the old top-level keys (`auth`,
`providers`, `redis`, `cache`, `gateway`, `server`, `logging`) are still present,
so an upgrade cannot silently drop the master key. The default `replicaCount`
dropped from 2 to 1 because SQLite is per pod, the pod now runs as the image's
UID 65532, and `/app/data` is on a PVC.
## Testing the chart
```bash
helm lint --strict ./helm -f helm/ci/default-values.yaml
helm template gomodel ./helm -f helm/ci/full-values.yaml | kubeconform -strict
helm install gomodel ./helm -n gomodel --create-namespace -f helm/ci/default-values.yaml --wait
helm test gomodel -n gomodel
```
The `ci/*-values.yaml` profiles are what the CI workflow lints, validates,
and installs on a kind cluster.