From c23b81da225509c9e7eae744380c6dd0bc23eacb Mon Sep 17 00:00:00 2001 From: Jarvis Date: Tue, 14 Jul 2026 21:20:46 +0800 Subject: [PATCH 1/4] docs(gateway): add configuration examples to chart README The README only had the auto-generated values table, which does not show how to actually use multi-field values like additionalTrustedCAs. Add a Configuration examples section (rendered from README.md.gotmpl) covering: trusting additional outbound CAs, exposing via LoadBalancer, setting replicas/resources, and injecting extra env vars. 3.9 line of the main-branch change. --- charts/gateway/Chart.yaml | 2 +- charts/gateway/README.md | 79 ++++++++++++++++++++++++++++++++ charts/gateway/README.md.gotmpl | 80 +++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 1 deletion(-) diff --git a/charts/gateway/Chart.yaml b/charts/gateway/Chart.yaml index ccd95c7a..8aebe25f 100644 --- a/charts/gateway/Chart.yaml +++ b/charts/gateway/Chart.yaml @@ -16,7 +16,7 @@ type: application # Versions are expected to follow Semantic Versioning (https://semver.org/) # major.minor mirrors the API7 EE release line (3.9.x), patch is this chart's # own counter on that line and is decoupled from the app patch (see appVersion). -version: 3.9.6 +version: 3.9.7 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/charts/gateway/README.md b/charts/gateway/README.md index 04c19721..56237d06 100644 --- a/charts/gateway/README.md +++ b/charts/gateway/README.md @@ -30,6 +30,85 @@ helm delete [RELEASE_NAME] --namespace api7 The command removes all the Kubernetes components associated with the chart and deletes the release. +## Configuration examples + +The full list of values is in the [Parameters](#parameters) table below. The snippets here cover a +few common setups — put them in a `values.yaml` and pass it with `-f values.yaml`, or translate each +line into a `--set key=value` flag. + +### Trust additional CA certificates for outbound TLS + +The gateway verifies the TLS certificate of any external service it dials (for example an +`openid-connect` identity provider) against its outbound trust store, which is the system CA bundle +plus `gateway.tls.existingCASecret`. In a Control Plane-managed deployment `existingCASecret` already +carries the Control Plane CA, so use `gateway.tls.additionalTrustedCAs` to trust an extra private or +enterprise CA **on top of** it, without modifying that Secret. + +Create a Secret that holds the CA certificate: + +```sh +kubectl -n api7 create secret generic keycloak-ca --from-file=keycloak-ca.crt=./keycloak-ca.crt +``` + +Reference it (each entry mounts `filename` from `secretName` and appends it to the trust store): + +```yaml +gateway: + tls: + additionalTrustedCAs: + - secretName: keycloak-ca + filename: keycloak-ca.crt +``` + +The rendered `ssl_trusted_certificate` becomes `system,,`, so the +system CAs and the existing CA are preserved. The trust store is merged when the gateway starts, so +restart the gateway Pods after adding an entry or changing the Secret contents: + +```sh +kubectl -n api7 rollout restart deploy/[RELEASE_NAME] +``` + +### Expose the gateway through a LoadBalancer + +`gateway.type` defaults to `NodePort`. To publish the proxy through a cloud load balancer instead: + +```yaml +gateway: + type: LoadBalancer + http: + servicePort: 80 + tls: + servicePort: 443 +``` + +### Set replicas and resource limits + +```yaml +apisix: + replicaCount: 3 + resources: + requests: + cpu: 500m + memory: 512Mi + limits: + cpu: "2" + memory: 2Gi +``` + +### Inject extra environment variables + +```yaml +apisix: + extraEnvVars: + - name: MY_ENV + value: "my-value" + - name: TOKEN_ENV + valueFrom: + secretKeyRef: + name: my-secret + key: token +``` + ## Parameters ## Values diff --git a/charts/gateway/README.md.gotmpl b/charts/gateway/README.md.gotmpl index eb1ea9e9..294b1c59 100644 --- a/charts/gateway/README.md.gotmpl +++ b/charts/gateway/README.md.gotmpl @@ -31,6 +31,86 @@ helm delete [RELEASE_NAME] --namespace api7 The command removes all the Kubernetes components associated with the chart and deletes the release. +## Configuration examples + +The full list of values is in the [Parameters](#parameters) table below. The snippets here cover a +few common setups — put them in a `values.yaml` and pass it with `-f values.yaml`, or translate each +line into a `--set key=value` flag. + +### Trust additional CA certificates for outbound TLS + +The gateway verifies the TLS certificate of any external service it dials (for example an +`openid-connect` identity provider) against its outbound trust store, which is the system CA bundle +plus `gateway.tls.existingCASecret`. In a Control Plane-managed deployment `existingCASecret` already +carries the Control Plane CA, so use `gateway.tls.additionalTrustedCAs` to trust an extra private or +enterprise CA **on top of** it, without modifying that Secret. + +Create a Secret that holds the CA certificate: + +```sh +kubectl -n api7 create secret generic keycloak-ca --from-file=keycloak-ca.crt=./keycloak-ca.crt +``` + +Reference it (each entry mounts `filename` from `secretName` and appends it to the trust store): + +```yaml +gateway: + tls: + additionalTrustedCAs: + - secretName: keycloak-ca + filename: keycloak-ca.crt +``` + +The rendered `ssl_trusted_certificate` becomes `system,,`, so the +system CAs and the existing CA are preserved. The trust store is merged when the gateway starts, so +restart the gateway Pods after adding an entry or changing the Secret contents: + +```sh +kubectl -n api7 rollout restart deploy/[RELEASE_NAME] +``` + +### Expose the gateway through a LoadBalancer + +`gateway.type` defaults to `NodePort`. To publish the proxy through a cloud load balancer instead: + +```yaml +gateway: + type: LoadBalancer + http: + servicePort: 80 + tls: + servicePort: 443 +``` + +### Set replicas and resource limits + +```yaml +apisix: + replicaCount: 3 + resources: + requests: + cpu: 500m + memory: 512Mi + limits: + cpu: "2" + memory: 2Gi +``` + +### Inject extra environment variables + +```yaml +apisix: + extraEnvVars: + - name: MY_ENV + value: "my-value" + - name: TOKEN_ENV + valueFrom: + secretKeyRef: + name: my-secret + key: token +``` + + ## Parameters {{ template "chart.valuesSection" . }} From c8ea7eb07a64e2aec2badfb31e9f05daddb0b3aa Mon Sep 17 00:00:00 2001 From: Jarvis Date: Tue, 14 Jul 2026 21:31:26 +0800 Subject: [PATCH 2/4] chore(gateway): drop unnecessary chart version bump ct lint runs with --charts (explicit list), which disables version-increment checking, so a docs-only README change does not require a Chart.yaml bump. --- charts/gateway/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/gateway/Chart.yaml b/charts/gateway/Chart.yaml index 8aebe25f..ccd95c7a 100644 --- a/charts/gateway/Chart.yaml +++ b/charts/gateway/Chart.yaml @@ -16,7 +16,7 @@ type: application # Versions are expected to follow Semantic Versioning (https://semver.org/) # major.minor mirrors the API7 EE release line (3.9.x), patch is this chart's # own counter on that line and is decoupled from the app patch (see appVersion). -version: 3.9.7 +version: 3.9.6 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to From 83ce8850504220aa7c51d594ec0a5c2017686433 Mon Sep 17 00:00:00 2001 From: Jarvis Date: Tue, 14 Jul 2026 21:38:38 +0800 Subject: [PATCH 3/4] docs(gateway): make gateway.tls.enabled explicit in TLS examples --- charts/gateway/README.md | 2 ++ charts/gateway/README.md.gotmpl | 2 ++ 2 files changed, 4 insertions(+) diff --git a/charts/gateway/README.md b/charts/gateway/README.md index 56237d06..cda8f2f7 100644 --- a/charts/gateway/README.md +++ b/charts/gateway/README.md @@ -55,6 +55,7 @@ Reference it (each entry mounts `filename` from `secretName` and appends it to t ```yaml gateway: tls: + enabled: true # default; additionalTrustedCAs only applies while the TLS listener is enabled additionalTrustedCAs: - secretName: keycloak-ca filename: keycloak-ca.crt @@ -78,6 +79,7 @@ gateway: http: servicePort: 80 tls: + enabled: true # required to expose the HTTPS port servicePort: 443 ``` diff --git a/charts/gateway/README.md.gotmpl b/charts/gateway/README.md.gotmpl index 294b1c59..718d3e1c 100644 --- a/charts/gateway/README.md.gotmpl +++ b/charts/gateway/README.md.gotmpl @@ -56,6 +56,7 @@ Reference it (each entry mounts `filename` from `secretName` and appends it to t ```yaml gateway: tls: + enabled: true # default; additionalTrustedCAs only applies while the TLS listener is enabled additionalTrustedCAs: - secretName: keycloak-ca filename: keycloak-ca.crt @@ -79,6 +80,7 @@ gateway: http: servicePort: 80 tls: + enabled: true # required to expose the HTTPS port servicePort: 443 ``` From c976aee3699e727b92226f068a9030875ba3c816 Mon Sep 17 00:00:00 2001 From: Jarvis Date: Tue, 14 Jul 2026 21:48:28 +0800 Subject: [PATCH 4/4] fix(gateway): decouple outbound CA trust store from tls.enabled ssl_trusted_certificate is the gateway's OUTBOUND trust store (used to verify etcd/Control Plane, openid-connect, loggers and other services the gateway dials). It has nothing to do with the inbound HTTPS listener, but existingCASecret and additionalTrustedCAs were gated on gateway.tls.enabled, so with the listener disabled the trust store (and its Secret mounts) silently disappeared even though etcd.auth.tls.verify or an openid-connect ssl_verify still needs it. Gate the config rendering and the Secret mounts on whether a CA is actually configured, not on gateway.tls.enabled. No change for the default (tls.enabled true); only fixes the tls.enabled=false case. Also revert the misleading tls.enabled note added to the README examples. --- charts/gateway/Chart.yaml | 2 +- charts/gateway/README.md | 2 -- charts/gateway/README.md.gotmpl | 2 -- charts/gateway/templates/_helpers.tpl | 14 +++++++------- charts/gateway/templates/_pod.tpl | 8 ++------ 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/charts/gateway/Chart.yaml b/charts/gateway/Chart.yaml index ccd95c7a..8aebe25f 100644 --- a/charts/gateway/Chart.yaml +++ b/charts/gateway/Chart.yaml @@ -16,7 +16,7 @@ type: application # Versions are expected to follow Semantic Versioning (https://semver.org/) # major.minor mirrors the API7 EE release line (3.9.x), patch is this chart's # own counter on that line and is decoupled from the app patch (see appVersion). -version: 3.9.6 +version: 3.9.7 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/charts/gateway/README.md b/charts/gateway/README.md index cda8f2f7..56237d06 100644 --- a/charts/gateway/README.md +++ b/charts/gateway/README.md @@ -55,7 +55,6 @@ Reference it (each entry mounts `filename` from `secretName` and appends it to t ```yaml gateway: tls: - enabled: true # default; additionalTrustedCAs only applies while the TLS listener is enabled additionalTrustedCAs: - secretName: keycloak-ca filename: keycloak-ca.crt @@ -79,7 +78,6 @@ gateway: http: servicePort: 80 tls: - enabled: true # required to expose the HTTPS port servicePort: 443 ``` diff --git a/charts/gateway/README.md.gotmpl b/charts/gateway/README.md.gotmpl index 718d3e1c..294b1c59 100644 --- a/charts/gateway/README.md.gotmpl +++ b/charts/gateway/README.md.gotmpl @@ -56,7 +56,6 @@ Reference it (each entry mounts `filename` from `secretName` and appends it to t ```yaml gateway: tls: - enabled: true # default; additionalTrustedCAs only applies while the TLS listener is enabled additionalTrustedCAs: - secretName: keycloak-ca filename: keycloak-ca.crt @@ -80,7 +79,6 @@ gateway: http: servicePort: 80 tls: - enabled: true # required to expose the HTTPS port servicePort: 443 ``` diff --git a/charts/gateway/templates/_helpers.tpl b/charts/gateway/templates/_helpers.tpl index a2446bbd..1871f02a 100644 --- a/charts/gateway/templates/_helpers.tpl +++ b/charts/gateway/templates/_helpers.tpl @@ -199,14 +199,15 @@ Output: JSON {"entries": [{"port": 9200, "nodePort": ""}, ...]} {{/* Build the value of `apisix.ssl.ssl_trusted_certificate` — the gateway's outbound -trust store. Starts from the system CA bundle (`system`), then appends the -Control Plane CA (gateway.tls.existingCASecret) and every entry in -gateway.tls.additionalTrustedCAs, matching the mount paths rendered in _pod.tpl. -Returns an empty string when TLS is disabled or no CA is configured, so the -caller can omit the key entirely. +trust store, used to verify external services the gateway dials (etcd/Control +Plane, openid-connect, loggers, ...). It is independent of the inbound HTTPS +listener (gateway.tls.enabled). Starts from the system CA bundle (`system`), +then appends the Control Plane CA (gateway.tls.existingCASecret) and every entry +in gateway.tls.additionalTrustedCAs, matching the mount paths rendered in +_pod.tpl. Returns an empty string when no CA is configured, so the caller can +omit the key entirely. */}} {{- define "gateway.sslTrustedCertificate" -}} -{{- if .Values.gateway.tls.enabled -}} {{- $paths := list -}} {{- if .Values.gateway.tls.existingCASecret -}} {{- $paths = append $paths (printf "/usr/local/apisix/conf/ssl/%s" .Values.gateway.tls.certCAFilename) -}} @@ -218,4 +219,3 @@ caller can omit the key entirely. {{- printf "system,%s" (join "," $paths) -}} {{- end -}} {{- end -}} -{{- end -}} diff --git a/charts/gateway/templates/_pod.tpl b/charts/gateway/templates/_pod.tpl index fe7165e9..c8ed09d8 100644 --- a/charts/gateway/templates/_pod.tpl +++ b/charts/gateway/templates/_pod.tpl @@ -184,18 +184,16 @@ spec: - mountPath: /usr/local/apisix/conf/config.yaml name: apisix-config subPath: config.yaml - {{- if and .Values.gateway.tls.enabled .Values.gateway.tls.existingCASecret }} + {{- if .Values.gateway.tls.existingCASecret }} - mountPath: /usr/local/apisix/conf/ssl/{{ .Values.gateway.tls.certCAFilename }} name: ssl subPath: {{ .Values.gateway.tls.certCAFilename }} {{- end }} - {{- if .Values.gateway.tls.enabled }} {{- range $i, $ca := .Values.gateway.tls.additionalTrustedCAs }} - mountPath: /usr/local/apisix/conf/ssl/additional-ca-{{ $i }} name: additional-ca-{{ $i }} readOnly: true {{- end }} - {{- end }} {{- if .Values.etcd.auth.tls.enabled }} - mountPath: /etcd-ssl @@ -298,12 +296,11 @@ spec: - configMap: name: {{ include "apisix.fullname" . }} name: apisix-config - {{- if and .Values.gateway.tls.enabled .Values.gateway.tls.existingCASecret }} + {{- if .Values.gateway.tls.existingCASecret }} - secret: secretName: {{ .Values.gateway.tls.existingCASecret | quote }} name: ssl {{- end }} - {{- if .Values.gateway.tls.enabled }} {{- range $i, $ca := .Values.gateway.tls.additionalTrustedCAs }} - secret: secretName: {{ $ca.secretName | quote }} @@ -312,7 +309,6 @@ spec: path: {{ $ca.filename | quote }} name: additional-ca-{{ $i }} {{- end }} - {{- end }} {{- if .Values.etcd.auth.tls.enabled }} - secret: secretName: {{ .Values.etcd.auth.tls.existingSecret | quote }}