mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add Helm chart for standalone AI Gateway (#27256)
Adds the `coder-ai-gateway` Helm chart for deploying the Coder AI Gateway as a standalone Kubernetes workload. Adds the coder-ai-gateway Helm chart for deploying the Coder AI Gateway as a standalone Kubernetes workload. The chart supports AI Gateway keys from an existing Secret or environment configuration, Coder connectivity through CODER_URL, listener and Coder-facing TLS, and optional Service, Ingress, and Gateway API HTTPRoute resources. Integrates the chart with existing Helm build, lint, golden generation, release artifact, Helm repository, and OCI publishing workflows.
This commit is contained in:
+9
-1
@@ -13,7 +13,7 @@ all: lint
|
||||
lint: lint/helm
|
||||
.PHONY: lint
|
||||
|
||||
lint/helm: lint/helm/coder lint/helm/provisioner
|
||||
lint/helm: lint/helm/coder lint/helm/provisioner lint/helm/ai-gateway
|
||||
.PHONY: lint/helm
|
||||
|
||||
lint/helm/coder:
|
||||
@@ -25,3 +25,11 @@ lint/helm/provisioner:
|
||||
helm dependency update --skip-refresh provisioner/
|
||||
helm lint --strict --set coder.image.tag=v0.0.1 provisioner/
|
||||
.PHONY: lint/helm/provisioner
|
||||
|
||||
lint/helm/ai-gateway:
|
||||
helm dependency update --skip-refresh ai-gateway/
|
||||
helm lint --strict \
|
||||
--set coder.image.tag=v0.0.1 \
|
||||
--set aigateway.keySecret.name=test \
|
||||
ai-gateway/
|
||||
.PHONY: lint/helm/ai-gateway
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
tests
|
||||
@@ -0,0 +1,6 @@
|
||||
dependencies:
|
||||
- name: libcoder
|
||||
repository: file://../libcoder
|
||||
version: 0.1.0
|
||||
digest: sha256:5c9a99109258073b590a9f98268490ef387fde24c0c7c7ade9c1a8c7ef5e6e10
|
||||
generated: "2026-07-14T17:15:50.670279008Z"
|
||||
@@ -0,0 +1,24 @@
|
||||
apiVersion: v2
|
||||
name: coder-ai-gateway
|
||||
description: Standalone AI Gateway for Coder
|
||||
home: https://github.com/coder/coder
|
||||
# These versions are replaced when Coder releases the chart.
|
||||
type: application
|
||||
version: "0.1.0"
|
||||
appVersion: "0.1.0"
|
||||
kubeVersion: ">= 1.23.0-0"
|
||||
keywords:
|
||||
- coder
|
||||
- ai
|
||||
sources:
|
||||
- https://github.com/coder/coder/tree/main/helm/ai-gateway
|
||||
icon: https://helm.coder.com/coder_logo_black.png
|
||||
maintainers:
|
||||
- name: Coder Technologies, Inc.
|
||||
email: support@coder.com
|
||||
url: https://coder.com/contact
|
||||
|
||||
dependencies:
|
||||
- name: libcoder
|
||||
version: 0.1.0
|
||||
repository: file://../libcoder
|
||||
@@ -0,0 +1,189 @@
|
||||
# Coder AI Gateway Helm chart
|
||||
|
||||
This chart deploys the Coder AI Gateway as a standalone Kubernetes Deployment.
|
||||
The Gateway connects to Coder using `CODER_URL` and an AI Gateway key. To forward
|
||||
proxied AI traffic to the standalone Gateway, configure the Coder AI Gateway
|
||||
Proxy (`aibridgeproxyd`) after installing the chart.
|
||||
|
||||
The chart does not create credentials or TLS Secrets.
|
||||
|
||||
## Install
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- An AI Gateway key created in Coder.
|
||||
- A Coder image that includes the `coder ai-gateway start` command. The official
|
||||
Coder v2.36.0 image is the first version to include this command.
|
||||
|
||||
### Configure the chart
|
||||
|
||||
Create a `values.yaml` file with the Coder URL and an AI Gateway key source. The
|
||||
following example uses a Kubernetes Secret in the Helm release namespace:
|
||||
|
||||
```console
|
||||
kubectl create secret generic coder-ai-gateway-key \
|
||||
--namespace <release-namespace> \
|
||||
--from-literal=key='<AI gateway key>'
|
||||
```
|
||||
|
||||
```yaml
|
||||
coder:
|
||||
image:
|
||||
# Required when installing the chart directly from Git.
|
||||
tag: "<coder version>"
|
||||
env:
|
||||
- name: CODER_URL
|
||||
value: https://coder.example.com
|
||||
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: coder-ai-gateway-key
|
||||
```
|
||||
|
||||
The Gateway can also connect to Coder through an in-cluster Service, for
|
||||
example:
|
||||
|
||||
```yaml
|
||||
coder:
|
||||
env:
|
||||
- name: CODER_URL
|
||||
value: http://coder.coder.svc.cluster.local:80
|
||||
```
|
||||
|
||||
For HTTPS, the Coder certificate must cover the internal Service hostname and
|
||||
the Gateway must trust its issuing CA.
|
||||
|
||||
Instead of `aigateway.keySecret`, set `CODER_AI_GATEWAY_KEY` or
|
||||
`CODER_AI_GATEWAY_KEY_FILE` through `coder.env`. Environment variables can also
|
||||
be supplied through `coder.envFrom`. The chart does not check for variable
|
||||
conflicts, regardless of whether values come from Helm options, `coder.env`, or
|
||||
`coder.envFrom`.
|
||||
|
||||
When installing a released chart package, the chart automatically uses the
|
||||
matching Coder image version. Set `coder.image.tag` only when installing
|
||||
directly from Git or overriding the image version. Custom images must provide
|
||||
the `coder ai-gateway start` command.
|
||||
|
||||
### Install the chart
|
||||
|
||||
```console
|
||||
helm install ai-gateway ./helm/ai-gateway \
|
||||
--namespace <release-namespace> \
|
||||
--values values.yaml
|
||||
```
|
||||
|
||||
## Connect Coder to the standalone Gateway
|
||||
|
||||
To route proxied AI requests through the standalone Gateway, configure the Coder
|
||||
AI Gateway Proxy with a target URL. When `service.enable` is true, the chart
|
||||
notes show the direct in-cluster Service URL, including the scheme selected by
|
||||
`aigateway.listenerTLS`. Retrieve it with:
|
||||
|
||||
```console
|
||||
helm get notes ai-gateway --namespace <release-namespace>
|
||||
```
|
||||
|
||||
The chart notes do not show an Ingress or `HTTPRoute` URL. To route through one
|
||||
of these entry points, set `CODER_AI_GATEWAY_PROXY_TARGET` to its URL instead.
|
||||
When `service.enable` is false, set the target to the URL of your user-managed
|
||||
route to the Deployment.
|
||||
|
||||
When listener TLS uses a private CA, the AI Gateway Proxy must trust that CA to
|
||||
connect directly to the Service over HTTPS.
|
||||
|
||||
## TLS
|
||||
|
||||
For Gateway-to-Coder HTTPS with a private CA, set
|
||||
`aigateway.coderTLS.caSecret`. If Coder requires client mTLS, also set
|
||||
`aigateway.coderTLS.clientSecret`.
|
||||
|
||||
Prefer terminating client-facing TLS at a Kubernetes Ingress or a `Gateway`
|
||||
resource from the Kubernetes Gateway API. To terminate TLS in the AI Gateway
|
||||
process, set `aigateway.listenerTLS.name` to an existing TLS Secret.
|
||||
|
||||
Client-facing TLS and backend TLS are independent. The `ingress.tls` settings
|
||||
configure TLS between clients and the Ingress. For `HTTPRoute`, the Gateway
|
||||
listener that accepts client connections is configured outside this chart.
|
||||
These settings do not configure whether the Ingress or Gateway connects to the
|
||||
AI Gateway Service using HTTP or HTTPS.
|
||||
|
||||
When `aigateway.listenerTLS` is enabled behind an Ingress or `HTTPRoute`,
|
||||
configure the entry point to connect to the Service using HTTPS and trust the AI
|
||||
Gateway certificate. Ingress backend TLS is controller-specific and can usually
|
||||
be configured with `ingress.annotations`. Gateway API backend TLS uses a
|
||||
separate `BackendTLSPolicy`, which can be managed outside this chart or rendered
|
||||
with `extraTemplates`. The chart does not infer or validate this
|
||||
controller-specific configuration. Without backend TLS, the entry point sends
|
||||
plaintext HTTP to the HTTPS listener, which typically results in a TLS handshake
|
||||
error reported as HTTP 502.
|
||||
|
||||
All referenced TLS Secrets must exist in the Helm release namespace.
|
||||
|
||||
## Networking
|
||||
|
||||
The data-plane Service, which carries LLM traffic, is a `ClusterIP` by default.
|
||||
`NodePort` and `LoadBalancer` are explicit alternatives. Ingress and `HTTPRoute`
|
||||
are optional and both route to the data-plane Service. If you enable Ingress or
|
||||
`HTTPRoute`, use a `ClusterIP` Service unless you intentionally need a second
|
||||
external entry point through a `LoadBalancer` Service.
|
||||
|
||||
## Scaling and resources
|
||||
|
||||
Set `coder.replicaCount` to run multiple AI Gateway replicas. The default
|
||||
resource requests are 1 CPU and 1 GiB of memory per replica. These requests are
|
||||
a starting point, not a capacity guarantee. CPU and memory usage depend heavily
|
||||
on concurrent requests and payload size.
|
||||
|
||||
Adjust `coder.resources` after observing production traffic. Consider setting
|
||||
`CODER_AI_GATEWAY_MAX_CONCURRENCY` through `coder.env` to bound concurrent
|
||||
requests per replica. The application default is unlimited. The chart does not
|
||||
set resource limits by default, which avoids CPU throttling and fixed memory
|
||||
limits for bursty workloads. Manage resources such as a Horizontal Pod
|
||||
Autoscaler or PodDisruptionBudget through your platform configuration or
|
||||
`extraTemplates`.
|
||||
|
||||
## Metrics
|
||||
|
||||
Every pod runs an unauthenticated metrics listener on the named `metrics` port,
|
||||
which maps to port `2112`. The chart does not create monitoring discovery
|
||||
resources. Configure pod-based discovery with `coder.podAnnotations`, for
|
||||
example:
|
||||
|
||||
```yaml
|
||||
coder:
|
||||
podAnnotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "2112"
|
||||
```
|
||||
|
||||
Alternatively, create discovery resources such as a `ServiceMonitor` through
|
||||
your monitoring stack or `extraTemplates`.
|
||||
|
||||
## Key rotation
|
||||
|
||||
1. Create a new AI Gateway key in Coder.
|
||||
2. Update the configured key source:
|
||||
- For `aigateway.keySecret`, update the referenced Secret or set `name` to a
|
||||
new Secret.
|
||||
- For a key supplied through `coder.env`, update the environment variable or
|
||||
the file it references.
|
||||
3. If the update did not trigger a rollout, restart the Deployment, for example:
|
||||
|
||||
```console
|
||||
kubectl rollout restart deployment/coder-ai-gateway \
|
||||
--namespace <release-namespace>
|
||||
```
|
||||
|
||||
4. Verify every replica is ready and serving with the new key.
|
||||
5. Revoke the old key.
|
||||
|
||||
Secret updates do not change the Deployment pod template automatically. A
|
||||
reloader controller can be configured through `coder.annotations` or
|
||||
`coder.podAnnotations`.
|
||||
|
||||
## Extra manifests
|
||||
|
||||
`extraTemplates` renders additional Kubernetes manifests as part of the Helm
|
||||
release. Entries can be YAML strings or Kubernetes objects, and can use Helm
|
||||
release values and chart helpers. Use them for small companion resources, such
|
||||
as a `NetworkPolicy`.
|
||||
@@ -0,0 +1,13 @@
|
||||
Coder AI Gateway is installed as {{ include "coder.name" . }}.
|
||||
|
||||
{{- if .Values.service.enable }}
|
||||
Configure the Coder deployment with:
|
||||
|
||||
CODER_AI_GATEWAY_PROXY_TARGET={{ ternary "https" "http" (not (empty .Values.aigateway.listenerTLS.name)) }}://{{ include "coder.name" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.port }}
|
||||
{{- else }}
|
||||
The chart-managed Service is disabled. Configure CODER_AI_GATEWAY_PROXY_TARGET
|
||||
with the URL of the user-managed route to this deployment.
|
||||
{{- end }}
|
||||
|
||||
The metrics listener is active on port 2112. Configure discovery with
|
||||
coder.podAnnotations or resources managed by your monitoring stack.
|
||||
@@ -0,0 +1,150 @@
|
||||
{{/*
|
||||
Service account to merge into the libcoder template. The Gateway never needs
|
||||
the Kubernetes API, so the token is not mounted.
|
||||
*/}}
|
||||
{{- define "coder-ai-gateway.serviceaccount" -}}
|
||||
automountServiceAccountToken: false
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
HTTP probe shared by startup, liveness, and readiness configuration.
|
||||
*/}}
|
||||
{{- define "coder-ai-gateway.probe" -}}
|
||||
httpGet:
|
||||
path: {{ .path }}
|
||||
port: http
|
||||
scheme: {{ .scheme }}
|
||||
initialDelaySeconds: {{ .probe.initialDelaySeconds }}
|
||||
{{- range $field := list "periodSeconds" "timeoutSeconds" "successThreshold" "failureThreshold" }}
|
||||
{{- if hasKey $.probe $field }}
|
||||
{{ $field }}: {{ index $.probe $field }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Component annotation for pod metadata.
|
||||
*/}}
|
||||
{{- define "coder.componentAnnotation" -}}
|
||||
app.kubernetes.io/component: ai-gateway
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Deployment to merge into the libcoder template.
|
||||
*/}}
|
||||
{{- define "coder-ai-gateway.deployment" -}}
|
||||
spec:
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 0
|
||||
maxSurge: 1
|
||||
template:
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
terminationGracePeriodSeconds: {{ .Values.aigateway.terminationGracePeriodSeconds }}
|
||||
containers:
|
||||
-
|
||||
{{ include "libcoder.containerspec" (list . "coder-ai-gateway.containerspec") | indent 8 }}
|
||||
volumes:
|
||||
{{- if .Values.aigateway.keySecret.name }}
|
||||
- name: ai-gateway-auth
|
||||
secret:
|
||||
secretName: {{ .Values.aigateway.keySecret.name }}
|
||||
items:
|
||||
- key: {{ .Values.aigateway.keySecret.key }}
|
||||
path: key
|
||||
{{- end }}
|
||||
{{- if .Values.aigateway.listenerTLS.name }}
|
||||
- name: ai-gateway-listener
|
||||
secret:
|
||||
secretName: {{ .Values.aigateway.listenerTLS.name }}
|
||||
items:
|
||||
- key: {{ .Values.aigateway.listenerTLS.certKey }}
|
||||
path: tls.crt
|
||||
- key: {{ .Values.aigateway.listenerTLS.keyKey }}
|
||||
path: tls.key
|
||||
{{- end }}
|
||||
{{- if .Values.aigateway.coderTLS.caSecret.name }}
|
||||
- name: coder-client-ca
|
||||
secret:
|
||||
secretName: {{ .Values.aigateway.coderTLS.caSecret.name }}
|
||||
items:
|
||||
- key: {{ .Values.aigateway.coderTLS.caSecret.key }}
|
||||
path: ca.crt
|
||||
{{- end }}
|
||||
{{- if .Values.aigateway.coderTLS.clientSecret.name }}
|
||||
- name: coder-client-tls
|
||||
secret:
|
||||
secretName: {{ .Values.aigateway.coderTLS.clientSecret.name }}
|
||||
items:
|
||||
- key: {{ .Values.aigateway.coderTLS.clientSecret.certKey }}
|
||||
path: tls.crt
|
||||
- key: {{ .Values.aigateway.coderTLS.clientSecret.keyKey }}
|
||||
path: tls.key
|
||||
{{- end }}
|
||||
{{- include "coder.volumeList" . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
ContainerSpec for the AI Gateway container of the deployment.
|
||||
*/}}
|
||||
{{- define "coder-ai-gateway.containerspec" -}}
|
||||
args:
|
||||
- ai-gateway
|
||||
- start
|
||||
{{- with .Values.coder.envFrom }}
|
||||
envFrom:
|
||||
{{ toYaml . }}
|
||||
{{- end }}
|
||||
env:
|
||||
{{ include "coder-ai-gateway.defaultEnv" . }}
|
||||
{{/*
|
||||
User additions follow chart defaults so they may reference or override them.
|
||||
*/}}
|
||||
{{- with .Values.coder.env }}
|
||||
{{ toYaml . }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 4001
|
||||
protocol: TCP
|
||||
- name: metrics
|
||||
containerPort: 2112
|
||||
protocol: TCP
|
||||
{{- $scheme := ternary "HTTPS" "HTTP" (not (empty .Values.aigateway.listenerTLS.name)) }}
|
||||
{{- if .Values.coder.startupProbe.enabled }}
|
||||
startupProbe:
|
||||
{{ include "coder-ai-gateway.probe" (dict "probe" .Values.coder.startupProbe "path" "/healthz" "scheme" $scheme) | indent 2 }}
|
||||
{{- end }}
|
||||
{{- if .Values.coder.livenessProbe.enabled }}
|
||||
livenessProbe:
|
||||
{{ include "coder-ai-gateway.probe" (dict "probe" .Values.coder.livenessProbe "path" "/healthz" "scheme" $scheme) | indent 2 }}
|
||||
{{- end }}
|
||||
{{- if .Values.coder.readinessProbe.enabled }}
|
||||
readinessProbe:
|
||||
{{ include "coder-ai-gateway.probe" (dict "probe" .Values.coder.readinessProbe "path" "/readyz" "scheme" $scheme) | indent 2 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
{{- if .Values.aigateway.keySecret.name }}
|
||||
- name: ai-gateway-auth
|
||||
mountPath: /etc/coder/ai-gateway-auth
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.aigateway.listenerTLS.name }}
|
||||
- name: ai-gateway-listener
|
||||
mountPath: /etc/coder/ai-gateway-listener
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.aigateway.coderTLS.caSecret.name }}
|
||||
- name: coder-client-ca
|
||||
mountPath: /etc/coder/coder-client-ca
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if .Values.aigateway.coderTLS.clientSecret.name }}
|
||||
- name: coder-client-tls
|
||||
mountPath: /etc/coder/coder-client-tls
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- include "coder.volumeMountList" . | nindent 0 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,73 @@
|
||||
{{/*
|
||||
Environment variables configured by the chart. User-supplied variables follow
|
||||
these entries, including when a name is duplicated.
|
||||
*/}}
|
||||
{{- define "coder-ai-gateway.defaultEnv" -}}
|
||||
- name: CODER_AI_GATEWAY_HTTP_ADDRESS
|
||||
value: 0.0.0.0:4001
|
||||
{{- if .Values.aigateway.keySecret.name }}
|
||||
- name: CODER_AI_GATEWAY_KEY_FILE
|
||||
value: /etc/coder/ai-gateway-auth/key
|
||||
{{- end }}
|
||||
- name: CODER_PROMETHEUS_ENABLE
|
||||
value: "true"
|
||||
- name: CODER_PROMETHEUS_ADDRESS
|
||||
value: 0.0.0.0:2112
|
||||
{{- if .Values.aigateway.listenerTLS.name }}
|
||||
- name: CODER_AI_GATEWAY_TLS_CERT_FILE
|
||||
value: /etc/coder/ai-gateway-listener/tls.crt
|
||||
- name: CODER_AI_GATEWAY_TLS_KEY_FILE
|
||||
value: /etc/coder/ai-gateway-listener/tls.key
|
||||
{{- end }}
|
||||
{{- if .Values.aigateway.coderTLS.caSecret.name }}
|
||||
- name: CODER_CLIENT_TLS_CA_FILE
|
||||
value: /etc/coder/coder-client-ca/ca.crt
|
||||
{{- end }}
|
||||
{{- if .Values.aigateway.coderTLS.clientSecret.name }}
|
||||
- name: CODER_CLIENT_TLS_CERT_FILE
|
||||
value: /etc/coder/coder-client-tls/tls.crt
|
||||
- name: CODER_CLIENT_TLS_KEY_FILE
|
||||
value: /etc/coder/coder-client-tls/tls.key
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Cross-field validation, invoked once from aigateway.yaml. Emits nothing and
|
||||
aborts rendering with a specific message on inconsistent values. Each failure
|
||||
message is asserted verbatim in tests/chart_test.go.
|
||||
*/}}
|
||||
{{- define "coder-ai-gateway.validate" -}}
|
||||
{{- if and .Values.aigateway.keySecret.name (not .Values.aigateway.keySecret.key) }}
|
||||
{{- fail "aigateway.keySecret.key is required when name is set." }}
|
||||
{{- end }}
|
||||
{{- if and .Values.ingress.enable (not .Values.service.enable) }}
|
||||
{{- fail "service.enable must be true when ingress.enable is true." }}
|
||||
{{- end }}
|
||||
{{- if and .Values.ingress.enable (not .Values.ingress.host) }}
|
||||
{{- fail "ingress.host is required when ingress.enable is true." }}
|
||||
{{- end }}
|
||||
{{- if and .Values.httproute.enable (not .Values.service.enable) }}
|
||||
{{- fail "service.enable must be true when httproute.enable is true." }}
|
||||
{{- end }}
|
||||
{{- if and .Values.httproute.enable (empty .Values.httproute.parentRefs) }}
|
||||
{{- fail "httproute.parentRefs is required when httproute.enable is true." }}
|
||||
{{- end }}
|
||||
{{- $listener := .Values.aigateway.listenerTLS }}
|
||||
{{- if and $listener.name (or (not $listener.certKey) (not $listener.keyKey)) }}
|
||||
{{- fail "aigateway.listenerTLS.certKey and keyKey are required when name is set." }}
|
||||
{{- end }}
|
||||
{{- if and .Values.httproute.enable (not (.Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1/HTTPRoute")) }}
|
||||
{{- fail "httproute.enable requires the gateway.networking.k8s.io/v1 HTTPRoute CRD." }}
|
||||
{{- end }}
|
||||
{{- $client := .Values.aigateway.coderTLS.clientSecret }}
|
||||
{{- if and $client.name (or (not $client.certKey) (not $client.keyKey)) }}
|
||||
{{- fail "aigateway.coderTLS.clientSecret.certKey and keyKey are required when name is set." }}
|
||||
{{- end }}
|
||||
{{- $ca := .Values.aigateway.coderTLS.caSecret }}
|
||||
{{- if and $ca.name (not $ca.key) }}
|
||||
{{- fail "aigateway.coderTLS.caSecret.key is required when name is set." }}
|
||||
{{- end }}
|
||||
{{- if and .Values.service.nodePort (not (has .Values.service.type (list "NodePort" "LoadBalancer"))) }}
|
||||
{{- fail "service.nodePort requires service.type to be NodePort or LoadBalancer." }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,8 @@
|
||||
{{- include "coder-ai-gateway.validate" . -}}
|
||||
---
|
||||
{{- if not .Values.coder.serviceAccount.disableCreate }}
|
||||
{{ include "libcoder.serviceaccount" (list . "coder-ai-gateway.serviceaccount") }}
|
||||
{{- end }}
|
||||
|
||||
---
|
||||
{{ include "libcoder.deployment" (list . "coder-ai-gateway.deployment") }}
|
||||
@@ -0,0 +1,4 @@
|
||||
{{- range .Values.extraTemplates }}
|
||||
---
|
||||
{{ include "coder.renderTemplate" (dict "value" . "context" $) }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,30 @@
|
||||
{{- if .Values.httproute.enable }}
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: {{ include "coder.name" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "coder.labels" . | nindent 4 }}
|
||||
{{- with .Values.httproute.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.httproute.parentRefs }}
|
||||
parentRefs:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.httproute.hostnames }}
|
||||
hostnames:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
backendRefs:
|
||||
- name: {{ include "coder.name" . }}
|
||||
port: {{ .Values.service.port }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,36 @@
|
||||
{{- if .Values.ingress.enable }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "coder.name" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "coder.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.ingress.className }}
|
||||
ingressClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls.enable }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .Values.ingress.host | quote }}
|
||||
{{- with .Values.ingress.tls.secretName }}
|
||||
secretName: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ .Values.ingress.host | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: {{ .Values.ingress.path }}
|
||||
pathType: {{ .Values.ingress.pathType }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "coder.name" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,35 @@
|
||||
{{- if .Values.service.enable }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "coder.name" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "coder.labels" . | nindent 4 }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
sessionAffinity: {{ .Values.service.sessionAffinity }}
|
||||
{{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }}
|
||||
externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.loadBalancerClass }}
|
||||
loadBalancerClass: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.service.loadBalancerIP }}
|
||||
loadBalancerIP: {{ . }}
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "coder.selectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
{{- with .Values.service.nodePort }}
|
||||
nodePort: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,229 @@
|
||||
package tests // nolint: testpackage
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
)
|
||||
|
||||
var updateGoldenFiles = flag.Bool("update", false, "Update golden files")
|
||||
|
||||
var testCases = []testCase{
|
||||
{
|
||||
name: "default_values",
|
||||
fixture: "default_values",
|
||||
},
|
||||
{
|
||||
name: "networking",
|
||||
fixture: "networking",
|
||||
namespace: "ai-gateway-test",
|
||||
apiVersions: []string{"gateway.networking.k8s.io/v1/HTTPRoute"},
|
||||
},
|
||||
{
|
||||
name: "custom",
|
||||
fixture: "custom",
|
||||
namespace: "ai-gateway-test",
|
||||
},
|
||||
{
|
||||
name: "nodeport",
|
||||
fixture: "nodeport",
|
||||
},
|
||||
{
|
||||
name: "missing_key_field",
|
||||
fixture: "fails_missing_key_field",
|
||||
expectedError: "aigateway.keySecret.key is required when name is set.",
|
||||
},
|
||||
{
|
||||
name: "partial_listener_tls",
|
||||
fixture: "fails_partial_listener_tls",
|
||||
expectedError: "aigateway.listenerTLS.certKey and keyKey are required when name is set.",
|
||||
},
|
||||
// This verifies that listener TLS and Ingress can be rendered together.
|
||||
// Production use requires controller-specific backend TLS and certificate
|
||||
// trust configuration outside this chart.
|
||||
{
|
||||
name: "listener_tls_with_ingress",
|
||||
fixture: "listener_tls_with_ingress",
|
||||
},
|
||||
{
|
||||
name: "partial_client_tls",
|
||||
fixture: "fails_partial_client_tls",
|
||||
expectedError: "aigateway.coderTLS.clientSecret.certKey and keyKey are required when name is set.",
|
||||
},
|
||||
{
|
||||
name: "partial_ca_tls",
|
||||
fixture: "fails_partial_ca_tls",
|
||||
expectedError: "aigateway.coderTLS.caSecret.key is required when name is set.",
|
||||
},
|
||||
{
|
||||
name: "ingress_without_service",
|
||||
fixture: "fails_ingress_without_service",
|
||||
expectedError: "service.enable must be true when ingress.enable is true.",
|
||||
},
|
||||
{
|
||||
name: "ingress_without_host",
|
||||
fixture: "fails_ingress_without_host",
|
||||
expectedError: "ingress.host is required when ingress.enable is true.",
|
||||
},
|
||||
{
|
||||
name: "httproute_without_service",
|
||||
fixture: "fails_httproute_without_service",
|
||||
expectedError: "service.enable must be true when httproute.enable is true.",
|
||||
},
|
||||
{
|
||||
name: "httproute_without_parent_refs",
|
||||
fixture: "fails_httproute_without_parent_refs",
|
||||
expectedError: "httproute.parentRefs is required when httproute.enable is true.",
|
||||
apiVersions: []string{"gateway.networking.k8s.io/v1/HTTPRoute"},
|
||||
},
|
||||
{
|
||||
name: "httproute_without_crd",
|
||||
fixture: "networking",
|
||||
expectedError: "httproute.enable requires the gateway.networking.k8s.io/v1 HTTPRoute CRD.",
|
||||
},
|
||||
{
|
||||
name: "nodeport_with_clusterip",
|
||||
fixture: "fails_nodeport_with_clusterip",
|
||||
expectedError: "service.nodePort requires service.type to be NodePort or LoadBalancer.",
|
||||
},
|
||||
}
|
||||
|
||||
type testCase struct {
|
||||
name string
|
||||
fixture string
|
||||
namespace string
|
||||
expectedError string
|
||||
apiVersions []string
|
||||
}
|
||||
|
||||
func (tc testCase) valuesFilePath() string {
|
||||
return filepath.Join("testdata", tc.fixture+".yaml")
|
||||
}
|
||||
|
||||
func (tc testCase) goldenFilePath() string {
|
||||
if tc.namespace == "default" {
|
||||
return filepath.Join("testdata", tc.name+".golden")
|
||||
}
|
||||
return filepath.Join("testdata", tc.name+"_"+tc.namespace+".golden")
|
||||
}
|
||||
|
||||
func TestRenderChart(t *testing.T) {
|
||||
t.Parallel()
|
||||
if *updateGoldenFiles {
|
||||
t.Skip("Golden files are being updated")
|
||||
}
|
||||
if testutil.InCI() && (runtime.GOOS == "windows" || runtime.GOOS == "darwin") {
|
||||
t.Skip("Skipping Helm tests on Windows and macOS in CI")
|
||||
}
|
||||
|
||||
helmPath := lookupHelm(t)
|
||||
err := updateHelmDependencies(t, helmPath, "..")
|
||||
require.NoError(t, err, "failed to build Helm dependencies")
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
if tc.namespace == "" {
|
||||
tc.namespace = "default"
|
||||
}
|
||||
t.Run(tc.namespace+"/"+tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
output, err := runHelmTemplate(t, helmPath, tc.valuesFilePath(), tc.namespace, tc.apiVersions)
|
||||
if tc.expectedError != "" {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, output, tc.expectedError)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err, output)
|
||||
golden, err := os.ReadFile(tc.goldenFilePath())
|
||||
require.NoError(t, err)
|
||||
golden = bytes.ReplaceAll(golden, []byte("\r"), nil)
|
||||
require.Equal(t, string(golden), output)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateGoldenFiles(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !*updateGoldenFiles {
|
||||
t.Skip("Run with -update to update golden files")
|
||||
}
|
||||
|
||||
helmPath := lookupHelm(t)
|
||||
err := updateHelmDependencies(t, helmPath, "..")
|
||||
require.NoError(t, err, "failed to build Helm dependencies")
|
||||
for _, tc := range testCases {
|
||||
if tc.expectedError != "" {
|
||||
continue
|
||||
}
|
||||
if tc.namespace == "" {
|
||||
tc.namespace = "default"
|
||||
}
|
||||
output, err := runHelmTemplate(t, helmPath, tc.valuesFilePath(), tc.namespace, tc.apiVersions)
|
||||
require.NoError(t, err, output)
|
||||
require.NoError(t, os.WriteFile(tc.goldenFilePath(), []byte(output), 0o644)) // nolint:gosec
|
||||
}
|
||||
}
|
||||
|
||||
func runHelmTemplate(t testing.TB, helmPath, valuesFile, namespace string, apiVersions []string) (string, error) {
|
||||
t.Helper()
|
||||
args := []string{"template", "ai-gateway", "..", "-f", valuesFile, "--namespace", namespace}
|
||||
for _, apiVersion := range apiVersions {
|
||||
args = append(args, "--api-versions", apiVersion)
|
||||
}
|
||||
cmd := exec.Command(helmPath, args...)
|
||||
cmd.Dir = "."
|
||||
output, err := cmd.CombinedOutput()
|
||||
return string(output), err
|
||||
}
|
||||
|
||||
// updateDepsOnce guards updateHelmDependencies: parallel top-level tests
|
||||
// share the charts/ directory, and rebuilding it while another test
|
||||
// templates the chart races.
|
||||
var (
|
||||
updateDepsOnce sync.Once
|
||||
errUpdateDeps error
|
||||
)
|
||||
|
||||
// updateHelmDependencies runs `helm dependency update .` on the given chartDir.
|
||||
func updateHelmDependencies(t testing.TB, helmPath, chartDir string) error {
|
||||
t.Helper()
|
||||
updateDepsOnce.Do(func() {
|
||||
// Remove charts/ from chartDir if it exists.
|
||||
err := os.RemoveAll(filepath.Join(chartDir, "charts"))
|
||||
if err != nil {
|
||||
errUpdateDeps = xerrors.Errorf("failed to remove charts/ directory: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
cmd := exec.Command(helmPath, "dependency", "update", "--skip-refresh", ".")
|
||||
cmd.Dir = chartDir
|
||||
t.Logf("exec command: %v", cmd.Args)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
errUpdateDeps = xerrors.Errorf("failed to run `helm dependency update`: %w\noutput: %s", err, out)
|
||||
return
|
||||
}
|
||||
})
|
||||
return errUpdateDeps
|
||||
}
|
||||
|
||||
func lookupHelm(t testing.TB) string {
|
||||
t.Helper()
|
||||
helmPath, err := exec.LookPath("helm")
|
||||
require.NoError(t, err, "helm not found in PATH")
|
||||
return helmPath
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
flag.Parse()
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
startupProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
successThreshold: 1
|
||||
failureThreshold: 7
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 12
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 13
|
||||
successThreshold: 1
|
||||
failureThreshold: 17
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 22
|
||||
periodSeconds: 25
|
||||
timeoutSeconds: 23
|
||||
successThreshold: 21
|
||||
failureThreshold: 27
|
||||
serviceAccount:
|
||||
name: workload-identity
|
||||
disableCreate: true
|
||||
env:
|
||||
- name: CODER_URL
|
||||
value: https://coder-primary.coder-system.svc.cluster.local:8443
|
||||
- name: CODER_AI_GATEWAY_HTTP_ADDRESS
|
||||
value: 127.0.0.1:4444
|
||||
- name: CODER_VERBOSE
|
||||
value: "true"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: gateway-config
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: ai-gateway-key
|
||||
key: token
|
||||
coderTLS:
|
||||
caSecret:
|
||||
name: coder-ca
|
||||
key: root.pem
|
||||
clientSecret:
|
||||
name: coder-client
|
||||
certKey: client.crt
|
||||
keyKey: client.key
|
||||
listenerTLS:
|
||||
name: gateway-tls
|
||||
certKey: cert.pem
|
||||
keyKey: key.pem
|
||||
extraTemplates:
|
||||
- |
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: '{{ include "coder.name" . }}-extra'
|
||||
namespace: '{{ .Release.Namespace }}'
|
||||
data:
|
||||
release: '{{ .Release.Name }}'
|
||||
- apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: '{{ include "coder.name" . }}-object'
|
||||
namespace: '{{ .Release.Namespace }}'
|
||||
data:
|
||||
namespace: '{{ .Release.Namespace }}'
|
||||
@@ -0,0 +1,214 @@
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/extra-templates.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: 'coder-ai-gateway-extra'
|
||||
namespace: 'ai-gateway-test'
|
||||
data:
|
||||
release: 'ai-gateway'
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/extra-templates.yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
namespace: 'ai-gateway-test'
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: 'coder-ai-gateway-object'
|
||||
namespace: 'ai-gateway-test'
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: coder-ai-gateway
|
||||
namespace: ai-gateway-test
|
||||
labels:
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
type: ClusterIP
|
||||
sessionAffinity: None
|
||||
selector:
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/aigateway.yaml
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
name: coder-ai-gateway
|
||||
namespace: ai-gateway-test
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
app.kubernetes.io/component: ai-gateway
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- args:
|
||||
- ai-gateway
|
||||
- start
|
||||
command:
|
||||
- /opt/coder
|
||||
env:
|
||||
- name: CODER_AI_GATEWAY_HTTP_ADDRESS
|
||||
value: 0.0.0.0:4001
|
||||
- name: CODER_AI_GATEWAY_KEY_FILE
|
||||
value: /etc/coder/ai-gateway-auth/key
|
||||
- name: CODER_PROMETHEUS_ENABLE
|
||||
value: "true"
|
||||
- name: CODER_PROMETHEUS_ADDRESS
|
||||
value: 0.0.0.0:2112
|
||||
- name: CODER_AI_GATEWAY_TLS_CERT_FILE
|
||||
value: /etc/coder/ai-gateway-listener/tls.crt
|
||||
- name: CODER_AI_GATEWAY_TLS_KEY_FILE
|
||||
value: /etc/coder/ai-gateway-listener/tls.key
|
||||
- name: CODER_CLIENT_TLS_CA_FILE
|
||||
value: /etc/coder/coder-client-ca/ca.crt
|
||||
- name: CODER_CLIENT_TLS_CERT_FILE
|
||||
value: /etc/coder/coder-client-tls/tls.crt
|
||||
- name: CODER_CLIENT_TLS_KEY_FILE
|
||||
value: /etc/coder/coder-client-tls/tls.key
|
||||
- name: CODER_URL
|
||||
value: https://coder-primary.coder-system.svc.cluster.local:8443
|
||||
- name: CODER_AI_GATEWAY_HTTP_ADDRESS
|
||||
value: 127.0.0.1:4444
|
||||
- name: CODER_VERBOSE
|
||||
value: "true"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: gateway-config
|
||||
image: ghcr.io/coder/coder:v2.36.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
livenessProbe:
|
||||
failureThreshold: 17
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
scheme: HTTPS
|
||||
initialDelaySeconds: 12
|
||||
periodSeconds: 15
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 13
|
||||
name: coder
|
||||
ports:
|
||||
- containerPort: 4001
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: 2112
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 27
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: http
|
||||
scheme: HTTPS
|
||||
initialDelaySeconds: 22
|
||||
periodSeconds: 25
|
||||
successThreshold: 21
|
||||
timeoutSeconds: 23
|
||||
resources:
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 1Gi
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
startupProbe:
|
||||
failureThreshold: 7
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
scheme: HTTPS
|
||||
initialDelaySeconds: 2
|
||||
periodSeconds: 5
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 3
|
||||
volumeMounts:
|
||||
- mountPath: /etc/coder/ai-gateway-auth
|
||||
name: ai-gateway-auth
|
||||
readOnly: true
|
||||
- mountPath: /etc/coder/ai-gateway-listener
|
||||
name: ai-gateway-listener
|
||||
readOnly: true
|
||||
- mountPath: /etc/coder/coder-client-ca
|
||||
name: coder-client-ca
|
||||
readOnly: true
|
||||
- mountPath: /etc/coder/coder-client-tls
|
||||
name: coder-client-tls
|
||||
readOnly: true
|
||||
restartPolicy: Always
|
||||
serviceAccountName: workload-identity
|
||||
terminationGracePeriodSeconds: 330
|
||||
volumes:
|
||||
- name: ai-gateway-auth
|
||||
secret:
|
||||
items:
|
||||
- key: token
|
||||
path: key
|
||||
secretName: ai-gateway-key
|
||||
- name: ai-gateway-listener
|
||||
secret:
|
||||
items:
|
||||
- key: cert.pem
|
||||
path: tls.crt
|
||||
- key: key.pem
|
||||
path: tls.key
|
||||
secretName: gateway-tls
|
||||
- name: coder-client-ca
|
||||
secret:
|
||||
items:
|
||||
- key: root.pem
|
||||
path: ca.crt
|
||||
secretName: coder-ca
|
||||
- name: coder-client-tls
|
||||
secret:
|
||||
items:
|
||||
- key: client.crt
|
||||
path: tls.crt
|
||||
- key: client.key
|
||||
path: tls.key
|
||||
secretName: coder-client
|
||||
@@ -0,0 +1,133 @@
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/aigateway.yaml
|
||||
apiVersion: v1
|
||||
automountServiceAccountToken: false
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
name: coder-ai-gateway
|
||||
namespace: default
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: coder-ai-gateway
|
||||
namespace: default
|
||||
labels:
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
type: ClusterIP
|
||||
sessionAffinity: None
|
||||
selector:
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/aigateway.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
name: coder-ai-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
app.kubernetes.io/component: ai-gateway
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- args:
|
||||
- ai-gateway
|
||||
- start
|
||||
command:
|
||||
- /opt/coder
|
||||
env:
|
||||
- name: CODER_AI_GATEWAY_HTTP_ADDRESS
|
||||
value: 0.0.0.0:4001
|
||||
- name: CODER_PROMETHEUS_ENABLE
|
||||
value: "true"
|
||||
- name: CODER_PROMETHEUS_ADDRESS
|
||||
value: 0.0.0.0:2112
|
||||
- name: CODER_URL
|
||||
value: https://coder.example.com
|
||||
- name: CODER_AI_GATEWAY_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: key
|
||||
name: ai-gateway-key
|
||||
image: ghcr.io/coder/coder:v2.36.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
name: coder
|
||||
ports:
|
||||
- containerPort: 4001
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: 2112
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
resources:
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 1Gi
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
volumeMounts: []
|
||||
restartPolicy: Always
|
||||
serviceAccountName: coder-ai-gateway
|
||||
terminationGracePeriodSeconds: 330
|
||||
volumes: []
|
||||
@@ -0,0 +1,13 @@
|
||||
coder:
|
||||
replicaCount: 3
|
||||
image:
|
||||
tag: v2.36.0
|
||||
env:
|
||||
- name: CODER_URL
|
||||
value: https://coder.example.com
|
||||
- name: CODER_AI_GATEWAY_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: ai-gateway-key
|
||||
key: key
|
||||
aigateway: {}
|
||||
@@ -0,0 +1,8 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: ai-gateway-key
|
||||
httproute:
|
||||
enable: true
|
||||
@@ -0,0 +1,10 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: ai-gateway-key
|
||||
service:
|
||||
enable: false
|
||||
httproute:
|
||||
enable: true
|
||||
@@ -0,0 +1,8 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: key
|
||||
ingress:
|
||||
enable: true
|
||||
@@ -0,0 +1,11 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: key
|
||||
service:
|
||||
enable: false
|
||||
ingress:
|
||||
enable: true
|
||||
host: ai.example.com
|
||||
@@ -0,0 +1,7 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: ai-gateway-key
|
||||
key: ""
|
||||
@@ -0,0 +1,8 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: ai-gateway-key
|
||||
service:
|
||||
nodePort: 30080
|
||||
@@ -0,0 +1,10 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: ai-gateway-key
|
||||
coderTLS:
|
||||
caSecret:
|
||||
name: coder-ca
|
||||
key: ""
|
||||
@@ -0,0 +1,10 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: key
|
||||
coderTLS:
|
||||
clientSecret:
|
||||
name: client
|
||||
certKey: ""
|
||||
@@ -0,0 +1,9 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: key
|
||||
listenerTLS:
|
||||
name: listener
|
||||
keyKey: ""
|
||||
@@ -0,0 +1,180 @@
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/aigateway.yaml
|
||||
apiVersion: v1
|
||||
automountServiceAccountToken: false
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
name: coder-ai-gateway
|
||||
namespace: default
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: coder-ai-gateway
|
||||
namespace: default
|
||||
labels:
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
type: ClusterIP
|
||||
sessionAffinity: None
|
||||
selector:
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/aigateway.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
name: coder-ai-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
app.kubernetes.io/component: ai-gateway
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- args:
|
||||
- ai-gateway
|
||||
- start
|
||||
command:
|
||||
- /opt/coder
|
||||
env:
|
||||
- name: CODER_AI_GATEWAY_HTTP_ADDRESS
|
||||
value: 0.0.0.0:4001
|
||||
- name: CODER_AI_GATEWAY_KEY_FILE
|
||||
value: /etc/coder/ai-gateway-auth/key
|
||||
- name: CODER_PROMETHEUS_ENABLE
|
||||
value: "true"
|
||||
- name: CODER_PROMETHEUS_ADDRESS
|
||||
value: 0.0.0.0:2112
|
||||
- name: CODER_AI_GATEWAY_TLS_CERT_FILE
|
||||
value: /etc/coder/ai-gateway-listener/tls.crt
|
||||
- name: CODER_AI_GATEWAY_TLS_KEY_FILE
|
||||
value: /etc/coder/ai-gateway-listener/tls.key
|
||||
- name: CODER_URL
|
||||
value: http://coder.default.svc.cluster.local:80
|
||||
image: ghcr.io/coder/coder:v2.36.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
name: coder
|
||||
ports:
|
||||
- containerPort: 4001
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: 2112
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: http
|
||||
scheme: HTTPS
|
||||
initialDelaySeconds: 0
|
||||
resources:
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 1Gi
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
volumeMounts:
|
||||
- mountPath: /etc/coder/ai-gateway-auth
|
||||
name: ai-gateway-auth
|
||||
readOnly: true
|
||||
- mountPath: /etc/coder/ai-gateway-listener
|
||||
name: ai-gateway-listener
|
||||
readOnly: true
|
||||
restartPolicy: Always
|
||||
serviceAccountName: coder-ai-gateway
|
||||
terminationGracePeriodSeconds: 330
|
||||
volumes:
|
||||
- name: ai-gateway-auth
|
||||
secret:
|
||||
items:
|
||||
- key: key
|
||||
path: key
|
||||
secretName: ai-gateway-key
|
||||
- name: ai-gateway-listener
|
||||
secret:
|
||||
items:
|
||||
- key: tls.crt
|
||||
path: tls.crt
|
||||
- key: tls.key
|
||||
path: tls.key
|
||||
secretName: listener-tls
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: coder-ai-gateway
|
||||
namespace: default
|
||||
labels:
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
rules:
|
||||
- host: "ai.example.com"
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: coder-ai-gateway
|
||||
port:
|
||||
number: 80
|
||||
@@ -0,0 +1,14 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
env:
|
||||
- name: CODER_URL
|
||||
value: http://coder.default.svc.cluster.local:80
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: ai-gateway-key
|
||||
listenerTLS:
|
||||
name: listener-tls
|
||||
ingress:
|
||||
enable: true
|
||||
host: ai.example.com
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
env:
|
||||
- name: CODER_URL
|
||||
value: http://coder.ai-gateway-test.svc.cluster.local:80
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: ai-gateway-key
|
||||
service:
|
||||
type: LoadBalancer
|
||||
port: 443
|
||||
annotations:
|
||||
service.example.com/internal: "true"
|
||||
loadBalancerClass: example.com/lb
|
||||
ingress:
|
||||
enable: true
|
||||
className: nginx
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
host: ai.example.com
|
||||
tls:
|
||||
enable: true
|
||||
secretName: ai-example-tls
|
||||
httproute:
|
||||
enable: true
|
||||
parentRefs:
|
||||
- name: shared-gateway
|
||||
namespace: gateway-system
|
||||
hostnames:
|
||||
- ai.example.com
|
||||
annotations:
|
||||
example.com/route: ai
|
||||
@@ -0,0 +1,206 @@
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/aigateway.yaml
|
||||
apiVersion: v1
|
||||
automountServiceAccountToken: false
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
name: coder-ai-gateway
|
||||
namespace: ai-gateway-test
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: coder-ai-gateway
|
||||
namespace: ai-gateway-test
|
||||
labels:
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
annotations:
|
||||
service.example.com/internal: "true"
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
sessionAffinity: None
|
||||
externalTrafficPolicy: Cluster
|
||||
loadBalancerClass: example.com/lb
|
||||
selector:
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
ports:
|
||||
- name: http
|
||||
port: 443
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/aigateway.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
name: coder-ai-gateway
|
||||
namespace: ai-gateway-test
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
app.kubernetes.io/component: ai-gateway
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- args:
|
||||
- ai-gateway
|
||||
- start
|
||||
command:
|
||||
- /opt/coder
|
||||
env:
|
||||
- name: CODER_AI_GATEWAY_HTTP_ADDRESS
|
||||
value: 0.0.0.0:4001
|
||||
- name: CODER_AI_GATEWAY_KEY_FILE
|
||||
value: /etc/coder/ai-gateway-auth/key
|
||||
- name: CODER_PROMETHEUS_ENABLE
|
||||
value: "true"
|
||||
- name: CODER_PROMETHEUS_ADDRESS
|
||||
value: 0.0.0.0:2112
|
||||
- name: CODER_URL
|
||||
value: http://coder.ai-gateway-test.svc.cluster.local:80
|
||||
image: ghcr.io/coder/coder:v2.36.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
name: coder
|
||||
ports:
|
||||
- containerPort: 4001
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: 2112
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
resources:
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 1Gi
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
volumeMounts:
|
||||
- mountPath: /etc/coder/ai-gateway-auth
|
||||
name: ai-gateway-auth
|
||||
readOnly: true
|
||||
restartPolicy: Always
|
||||
serviceAccountName: coder-ai-gateway
|
||||
terminationGracePeriodSeconds: 330
|
||||
volumes:
|
||||
- name: ai-gateway-auth
|
||||
secret:
|
||||
items:
|
||||
- key: key
|
||||
path: key
|
||||
secretName: ai-gateway-key
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: coder-ai-gateway
|
||||
namespace: ai-gateway-test
|
||||
labels:
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts:
|
||||
- "ai.example.com"
|
||||
secretName: ai-example-tls
|
||||
rules:
|
||||
- host: "ai.example.com"
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: coder-ai-gateway
|
||||
port:
|
||||
number: 443
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/httproute.yaml
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: coder-ai-gateway
|
||||
namespace: ai-gateway-test
|
||||
labels:
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
annotations:
|
||||
example.com/route: ai
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: shared-gateway
|
||||
namespace: gateway-system
|
||||
hostnames:
|
||||
- ai.example.com
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
backendRefs:
|
||||
- name: coder-ai-gateway
|
||||
port: 443
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/aigateway.yaml
|
||||
apiVersion: v1
|
||||
automountServiceAccountToken: false
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
name: coder-ai-gateway
|
||||
namespace: default
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/service.yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: coder-ai-gateway
|
||||
namespace: default
|
||||
labels:
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: "0.1.0"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
type: NodePort
|
||||
sessionAffinity: ClientIP
|
||||
externalTrafficPolicy: Local
|
||||
selector:
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
nodePort: 30401
|
||||
---
|
||||
# Source: coder-ai-gateway/templates/aigateway.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
name: coder-ai-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
app.kubernetes.io/component: ai-gateway
|
||||
labels:
|
||||
app.kubernetes.io/instance: ai-gateway
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: coder-ai-gateway
|
||||
app.kubernetes.io/part-of: coder-ai-gateway
|
||||
app.kubernetes.io/version: 0.1.0
|
||||
helm.sh/chart: coder-ai-gateway-0.1.0
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
containers:
|
||||
- args:
|
||||
- ai-gateway
|
||||
- start
|
||||
command:
|
||||
- /opt/coder
|
||||
env:
|
||||
- name: CODER_AI_GATEWAY_HTTP_ADDRESS
|
||||
value: 0.0.0.0:4001
|
||||
- name: CODER_AI_GATEWAY_KEY_FILE
|
||||
value: /etc/coder/ai-gateway-auth/key
|
||||
- name: CODER_PROMETHEUS_ENABLE
|
||||
value: "true"
|
||||
- name: CODER_PROMETHEUS_ADDRESS
|
||||
value: 0.0.0.0:2112
|
||||
- name: CODER_URL
|
||||
value: http://coder.default.svc.cluster.local:80
|
||||
image: ghcr.io/coder/coder:v2.36.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
lifecycle: {}
|
||||
name: coder
|
||||
ports:
|
||||
- containerPort: 4001
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: 2112
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: http
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 0
|
||||
resources:
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 1Gi
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
volumeMounts:
|
||||
- mountPath: /etc/coder/ai-gateway-auth
|
||||
name: ai-gateway-auth
|
||||
readOnly: true
|
||||
restartPolicy: Always
|
||||
serviceAccountName: coder-ai-gateway
|
||||
terminationGracePeriodSeconds: 330
|
||||
volumes:
|
||||
- name: ai-gateway-auth
|
||||
secret:
|
||||
items:
|
||||
- key: key
|
||||
path: key
|
||||
secretName: ai-gateway-key
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
coder:
|
||||
image:
|
||||
tag: v2.36.0
|
||||
env:
|
||||
- name: CODER_URL
|
||||
value: http://coder.default.svc.cluster.local:80
|
||||
aigateway:
|
||||
keySecret:
|
||||
name: ai-gateway-key
|
||||
service:
|
||||
type: NodePort
|
||||
nodePort: 30401
|
||||
externalTrafficPolicy: Local
|
||||
sessionAffinity: ClientIP
|
||||
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"libcoder": {"type": "object"},
|
||||
"nameOverride": {"type": "string"},
|
||||
"coder": {
|
||||
"type": "object", "additionalProperties": false,
|
||||
"required": ["env", "envFrom", "image", "initContainers", "annotations", "labels", "podAnnotations", "podLabels", "serviceAccount", "securityContext", "podSecurityContext", "volumes", "volumeMounts", "replicaCount", "lifecycle", "resources", "startupProbe", "livenessProbe", "readinessProbe", "certs", "affinity", "tolerations", "nodeSelector", "topologySpreadConstraints", "priorityClassName", "command"],
|
||||
"properties": {
|
||||
"env": {"type": "array", "items": {"type": "object", "required": ["name"]}},
|
||||
"envFrom": {"type": "array", "items": {"type": "object"}},
|
||||
"image": {
|
||||
"type": "object", "additionalProperties": false,
|
||||
"required": ["repo", "tag", "pullPolicy", "pullSecrets"],
|
||||
"properties": {
|
||||
"repo": {"type": "string", "minLength": 1},
|
||||
"tag": {"type": "string"},
|
||||
"pullPolicy": {"enum": ["Always", "IfNotPresent", "Never"]},
|
||||
"pullSecrets": {"type": "array", "items": {"type": "object"}}
|
||||
}
|
||||
},
|
||||
"initContainers": {"type": "array"},
|
||||
"annotations": {"type": "object"},
|
||||
"labels": {"type": "object"},
|
||||
"podAnnotations": {"type": "object"},
|
||||
"podLabels": {"type": "object"},
|
||||
"serviceAccount": {
|
||||
"type": "object", "additionalProperties": false,
|
||||
"required": ["annotations", "name", "disableCreate"],
|
||||
"properties": {
|
||||
"annotations": {"type": "object"},
|
||||
"name": {"type": "string", "minLength": 1},
|
||||
"disableCreate": {"type": "boolean"},
|
||||
"labels": {"type": "object"}
|
||||
}
|
||||
},
|
||||
"securityContext": {"type": "object"},
|
||||
"podSecurityContext": {"type": "object"},
|
||||
"volumes": {"type": "array"},
|
||||
"volumeMounts": {"type": "array"},
|
||||
"replicaCount": {"type": "integer", "minimum": 0},
|
||||
"lifecycle": {"type": "object"},
|
||||
"resources": {"type": "object"},
|
||||
"startupProbe": {"$ref": "#/definitions/healthProbe"},
|
||||
"livenessProbe": {"$ref": "#/definitions/healthProbe"},
|
||||
"readinessProbe": {"$ref": "#/definitions/probe"},
|
||||
"certs": {
|
||||
"type": "object", "additionalProperties": false, "required": ["secrets"],
|
||||
"properties": {
|
||||
"secrets": {"type": "array", "items": {"type": "object", "required": ["name", "key"]}}
|
||||
}
|
||||
},
|
||||
"affinity": {"type": "object"},
|
||||
"tolerations": {"type": "array"},
|
||||
"nodeSelector": {"type": "object"},
|
||||
"topologySpreadConstraints": {"type": "array"},
|
||||
"priorityClassName": {"type": "string"},
|
||||
"command": {"type": "array", "minItems": 1, "items": {"type": "string"}}
|
||||
}
|
||||
},
|
||||
"aigateway": {
|
||||
"type": "object", "additionalProperties": false,
|
||||
"required": ["keySecret", "coderTLS", "listenerTLS", "terminationGracePeriodSeconds"],
|
||||
"properties": {
|
||||
"keySecret": {
|
||||
"type": "object", "additionalProperties": false,
|
||||
"required": ["name", "key"],
|
||||
"properties": {"name": {"type": "string"}, "key": {"type": "string"}}
|
||||
},
|
||||
"coderTLS": {
|
||||
"type": "object", "additionalProperties": false,
|
||||
"required": ["caSecret", "clientSecret"],
|
||||
"properties": {
|
||||
"caSecret": {
|
||||
"type": "object", "additionalProperties": false, "required": ["name", "key"],
|
||||
"properties": {"name": {"type": "string"}, "key": {"type": "string"}}
|
||||
},
|
||||
"clientSecret": {
|
||||
"type": "object", "additionalProperties": false, "required": ["name", "certKey", "keyKey"],
|
||||
"properties": {"name": {"type": "string"}, "certKey": {"type": "string"}, "keyKey": {"type": "string"}}
|
||||
}
|
||||
}
|
||||
},
|
||||
"listenerTLS": {
|
||||
"type": "object", "additionalProperties": false, "required": ["name", "certKey", "keyKey"],
|
||||
"properties": {"name": {"type": "string"}, "certKey": {"type": "string"}, "keyKey": {"type": "string"}}
|
||||
},
|
||||
"terminationGracePeriodSeconds": {"type": "integer", "minimum": 0}
|
||||
}
|
||||
},
|
||||
"service": {
|
||||
"type": "object", "additionalProperties": false,
|
||||
"required": ["enable", "type", "port", "annotations", "sessionAffinity", "externalTrafficPolicy", "loadBalancerClass", "loadBalancerIP", "nodePort"],
|
||||
"properties": {
|
||||
"enable": {"type": "boolean"},
|
||||
"type": {"enum": ["ClusterIP", "NodePort", "LoadBalancer"]},
|
||||
"port": {"type": "integer", "minimum": 1, "maximum": 65535},
|
||||
"annotations": {"type": "object"},
|
||||
"sessionAffinity": {"enum": ["None", "ClientIP"]},
|
||||
"externalTrafficPolicy": {"enum": ["Cluster", "Local"]},
|
||||
"loadBalancerClass": {"type": "string"},
|
||||
"loadBalancerIP": {"type": "string"},
|
||||
"nodePort": {"type": ["integer", "null"], "minimum": 30000, "maximum": 32767}
|
||||
}
|
||||
},
|
||||
"ingress": {
|
||||
"type": "object", "additionalProperties": false,
|
||||
"required": ["enable", "className", "annotations", "host", "path", "pathType", "tls"],
|
||||
"properties": {
|
||||
"enable": {"type": "boolean"}, "className": {"type": "string"}, "annotations": {"type": "object"},
|
||||
"host": {"type": "string"}, "path": {"type": "string"}, "pathType": {"enum": ["Exact", "Prefix", "ImplementationSpecific"]},
|
||||
"tls": {"type": "object", "additionalProperties": false, "required": ["enable", "secretName"], "properties": {"enable": {"type": "boolean"}, "secretName": {"type": "string"}}}
|
||||
}
|
||||
},
|
||||
"httproute": {
|
||||
"type": "object", "additionalProperties": false, "required": ["enable", "parentRefs", "hostnames", "annotations"],
|
||||
"properties": {"enable": {"type": "boolean"}, "parentRefs": {"type": "array"}, "hostnames": {"type": "array", "items": {"type": "string"}}, "annotations": {"type": "object"}}
|
||||
},
|
||||
"extraTemplates": {"type": "array", "items": {"oneOf": [{"type": "string"}, {"type": "object"}]}}
|
||||
},
|
||||
"required": ["coder", "aigateway", "service", "ingress", "httproute", "extraTemplates"],
|
||||
"definitions": {
|
||||
"healthProbe": {
|
||||
"allOf": [
|
||||
{"$ref": "#/definitions/probe"},
|
||||
{"properties": {"successThreshold": {"type": "integer", "const": 1}}}
|
||||
]
|
||||
},
|
||||
"probe": {
|
||||
"type": "object", "additionalProperties": false, "required": ["enabled", "initialDelaySeconds"],
|
||||
"properties": {
|
||||
"enabled": {"type": "boolean"},
|
||||
"initialDelaySeconds": {"type": "integer", "minimum": 0},
|
||||
"periodSeconds": {"type": "integer", "minimum": 1},
|
||||
"timeoutSeconds": {"type": "integer", "minimum": 1},
|
||||
"successThreshold": {"type": "integer", "minimum": 1},
|
||||
"failureThreshold": {"type": "integer", "minimum": 1}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
# coder -- Common workload configuration options.
|
||||
coder:
|
||||
# coder.env -- Additional environment variables for the AI Gateway
|
||||
# container. These are rendered after chart-configured variables, including
|
||||
# when a variable name is duplicated.
|
||||
env: []
|
||||
# - name: "CODER_VERBOSE"
|
||||
# value: "true"
|
||||
|
||||
# coder.envFrom -- Additional envFrom sources for the AI Gateway container.
|
||||
envFrom: []
|
||||
|
||||
# coder.image -- The image to use for the AI Gateway.
|
||||
image:
|
||||
# coder.image.repo -- The repository of the image.
|
||||
repo: "ghcr.io/coder/coder"
|
||||
# coder.image.tag -- The tag of the image, defaults to {{.Chart.AppVersion}}
|
||||
# if not set. If you're using the chart directly from git, the default
|
||||
# app version will not work and you'll need to set this value. The helm
|
||||
# chart helpfully fails quickly in this case.
|
||||
tag: ""
|
||||
# coder.image.pullPolicy -- The pull policy to use for the image. See:
|
||||
# https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy
|
||||
pullPolicy: IfNotPresent
|
||||
# coder.image.pullSecrets -- The secrets used for pulling the Coder image
|
||||
# from a private registry.
|
||||
pullSecrets: []
|
||||
# - name: "pull-secret"
|
||||
|
||||
# coder.initContainers -- Init containers for the deployment. See:
|
||||
# https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
|
||||
initContainers:
|
||||
[]
|
||||
# - name: init-container
|
||||
# image: busybox:1.28
|
||||
# command: ['sh', '-c', "sleep 2"]
|
||||
|
||||
# coder.annotations -- The Deployment annotations. See:
|
||||
# https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
|
||||
annotations: {}
|
||||
|
||||
# coder.labels -- The Deployment labels. See:
|
||||
# https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
|
||||
labels: {}
|
||||
|
||||
# coder.podAnnotations -- The pod annotations. See:
|
||||
# https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
|
||||
# The annotation `app.kubernetes.io/component: ai-gateway` is added
|
||||
# automatically.
|
||||
podAnnotations: {}
|
||||
|
||||
# coder.podLabels -- The pod labels. See:
|
||||
# https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
|
||||
podLabels: {}
|
||||
|
||||
# coder.serviceAccount -- Configuration for the automatically created
|
||||
# service account.
|
||||
serviceAccount:
|
||||
# coder.serviceAccount.annotations -- The service account annotations.
|
||||
annotations: {}
|
||||
# coder.serviceAccount.name -- The service account name.
|
||||
name: coder-ai-gateway
|
||||
# coder.serviceAccount.disableCreate -- Whether to create the service
|
||||
# account or use an existing service account.
|
||||
disableCreate: false
|
||||
|
||||
# coder.securityContext -- Fields related to the container's security
|
||||
# context (as opposed to the pod). Some fields are also present in the pod
|
||||
# security context, in which case these values will take precedence.
|
||||
securityContext:
|
||||
# coder.securityContext.runAsNonRoot -- Requires that the container
|
||||
# runs as an unprivileged user.
|
||||
runAsNonRoot: true
|
||||
# coder.securityContext.runAsUser -- Sets the user id of the container.
|
||||
runAsUser: 1000
|
||||
# coder.securityContext.runAsGroup -- Sets the group id of the container.
|
||||
runAsGroup: 1000
|
||||
# coder.securityContext.seccompProfile -- Sets the seccomp profile for
|
||||
# the container.
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
# coder.securityContext.allowPrivilegeEscalation -- Controls whether
|
||||
# the container can gain additional privileges.
|
||||
allowPrivilegeEscalation: false
|
||||
|
||||
# coder.podSecurityContext -- Pod-level security context settings. See:
|
||||
# https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
|
||||
podSecurityContext: {}
|
||||
|
||||
# coder.volumes -- A list of extra volumes to add to the AI Gateway pod.
|
||||
volumes: []
|
||||
# - name: "my-volume"
|
||||
# emptyDir: {}
|
||||
|
||||
# coder.volumeMounts -- A list of extra volume mounts to add to the AI
|
||||
# Gateway container.
|
||||
volumeMounts: []
|
||||
# - name: "my-volume"
|
||||
# mountPath: "/mnt/my-volume"
|
||||
|
||||
# coder.replicaCount -- The number of AI Gateway pods.
|
||||
replicaCount: 1
|
||||
|
||||
# coder.lifecycle -- Container lifecycle handlers, allowing for lifecycle
|
||||
# events such as postStart and preStop. See:
|
||||
# https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/
|
||||
lifecycle:
|
||||
{}
|
||||
# postStart:
|
||||
# exec:
|
||||
# command: ["/bin/sh", "-c", "echo postStart"]
|
||||
|
||||
# coder.resources -- The resources to request for the AI Gateway container.
|
||||
resources:
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 1Gi
|
||||
|
||||
# coder.startupProbe -- Startup probe configuration for the AI Gateway.
|
||||
# Enable this with a failure threshold long enough for initial provider load
|
||||
# before enabling the liveness probe.
|
||||
startupProbe:
|
||||
enabled: false
|
||||
initialDelaySeconds: 0
|
||||
|
||||
# coder.livenessProbe -- Liveness probe configuration for the AI Gateway.
|
||||
# Without this probe, Kubernetes does not restart a running but unresponsive
|
||||
# Gateway. Enable and tune the startup probe before enabling this probe.
|
||||
livenessProbe:
|
||||
enabled: false
|
||||
initialDelaySeconds: 0
|
||||
|
||||
# coder.readinessProbe -- Readiness probe configuration for the AI Gateway.
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 0
|
||||
|
||||
# coder.certs -- CA bundles to mount inside the AI Gateway pod.
|
||||
certs:
|
||||
# coder.certs.secrets -- A list of CA bundle secrets to mount into the
|
||||
# pod. The secrets should exist in the same namespace as the Helm
|
||||
# deployment. The given key in each secret is mounted at
|
||||
# `/etc/ssl/certs/{secret_name}.crt`.
|
||||
secrets:
|
||||
[]
|
||||
# - name: "my-ca-bundle"
|
||||
# key: "ca-bundle.crt"
|
||||
|
||||
# coder.affinity -- Allows specifying an affinity rule for the deployment.
|
||||
affinity: {}
|
||||
|
||||
# coder.tolerations -- Tolerations for tainted nodes. See:
|
||||
# https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
|
||||
tolerations: []
|
||||
|
||||
# coder.nodeSelector -- Node labels for constraining pods to nodes. See:
|
||||
# https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
|
||||
nodeSelector: {}
|
||||
|
||||
# coder.topologySpreadConstraints -- Topology spread constraints for the
|
||||
# pods. See:
|
||||
# https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/
|
||||
topologySpreadConstraints: []
|
||||
|
||||
# coder.priorityClassName -- The priority class name for the pods.
|
||||
priorityClassName: ""
|
||||
|
||||
# coder.command -- The command to use when running the container. Used
|
||||
# for customizing the location of the `coder` binary in your image.
|
||||
command:
|
||||
- /opt/coder
|
||||
|
||||
# Authentication and listener settings for the standalone gateway.
|
||||
aigateway:
|
||||
# Optional existing Secret containing an AI Gateway key. When unset, provide
|
||||
# CODER_AI_GATEWAY_KEY or CODER_AI_GATEWAY_KEY_FILE through coder.env.
|
||||
keySecret:
|
||||
name: ""
|
||||
key: key
|
||||
coderTLS:
|
||||
caSecret:
|
||||
name: ""
|
||||
key: ca.crt
|
||||
clientSecret:
|
||||
name: ""
|
||||
certKey: tls.crt
|
||||
keyKey: tls.key
|
||||
# The certificate must cover every hostname clients use.
|
||||
listenerTLS:
|
||||
name: ""
|
||||
certKey: tls.crt
|
||||
keyKey: tls.key
|
||||
# This must exceed the application's 300-second shutdown timeout.
|
||||
terminationGracePeriodSeconds: 330
|
||||
|
||||
# Stable data-plane Service fronting the container's port 4001 listener.
|
||||
service:
|
||||
enable: true
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
annotations: {}
|
||||
sessionAffinity: None
|
||||
externalTrafficPolicy: Cluster
|
||||
loadBalancerClass: ""
|
||||
loadBalancerIP: ""
|
||||
nodePort: null
|
||||
|
||||
# Optional networking.k8s.io/v1 Ingress.
|
||||
ingress:
|
||||
enable: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
host: ""
|
||||
path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
enable: false
|
||||
secretName: ""
|
||||
|
||||
# Optional Gateway API HTTPRoute. Requires the v1 HTTPRoute CRD.
|
||||
httproute:
|
||||
enable: false
|
||||
parentRefs: []
|
||||
hostnames: []
|
||||
annotations: {}
|
||||
|
||||
# Additional templated Kubernetes manifests.
|
||||
extraTemplates: []
|
||||
Reference in New Issue
Block a user