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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions charts/kong/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

### Added

* Added `additionalProxies` configuration to support multiple proxy services.
This allows creating additional Kubernetes Services (e.g., ClusterIP for
internal access) alongside the primary proxy service (e.g., LoadBalancer with
proxy_protocol for external access). Each additional proxy automatically
registers its listeners in `KONG_PROXY_LISTEN` and `KONG_PORT_MAPS`, and
exposes the corresponding container ports in the deployment.

* Added `containerSecurityContext.enabled` option to allow disabling the
container security context for OpenShift compatibility.
[#1456](https://github.com/Kong/charts/pull/1456)
Expand Down
79 changes: 79 additions & 0 deletions charts/kong/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ helm install kong/kong --generate-name
- [Kong Service Parameters](#kong-service-parameters)
- [Admin Service mTLS](#admin-service-mtls)
- [Stream listens](#stream-listens)
- [Additional Proxy Services](#additional-proxy-services)
- [Ingress Controller Parameters](#ingress-controller-parameters)
- [The `env` section](#the-env-section)
- [The `customEnv` section](#the-customenv-section)
Expand Down Expand Up @@ -763,6 +764,84 @@ are configured using an array of objects under `proxy.stream` and `udpProxy.stre
| hostPort | Host port to use for a stream listen | |
| parameters | Array of additional listen parameters | `[]` |

#### Additional Proxy Services

The `additionalProxies` map allows you to create additional Kubernetes
Services that route to the same Kong proxy container. This is useful when
you need Kong proxy accessible through multiple distinct network paths with
different configurations.

A common use case is exposing Kong through both an external LoadBalancer
(e.g. AWS NLB with `proxy_protocol`) and an internal ClusterIP service
(without `proxy_protocol`) simultaneously, from a single Helm release.

Each entry in the map creates a separate Service (and optionally an
Ingress) and automatically registers its listeners in `KONG_PROXY_LISTEN`
and `KONG_PORT_MAPS`, and exposes the corresponding container ports in
the deployment.

**Important:** Use container ports that do not conflict with the primary
proxy ports (8000/8443) or any other Kong listener ports.

The keys under each named entry follow the same `SVC.*` pattern described
in [Kong Service Parameters](#kong-service-parameters) (`http`, `tls`,
`stream`, `type`, `annotations`, `labels`, `ingress`, etc.).

Example values:

```yaml
# Primary proxy -- external LB with proxy_protocol
proxy:
enabled: true
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
http:
enabled: true
servicePort: 80
containerPort: 8000
parameters:
- proxy_protocol
tls:
enabled: true
servicePort: 443
containerPort: 8443
parameters:
- http2
- proxy_protocol

# Additional internal proxy -- ClusterIP, no proxy_protocol
additionalProxies:
internal:
enabled: true
type: ClusterIP
annotations: {}
labels:
proxy-type: "internal"
http:
enabled: true
servicePort: 80
containerPort: 7000
parameters: []
tls:
enabled: true
servicePort: 443
containerPort: 7443
parameters:
- http2
appProtocol: ""
stream: []
ingress:
enabled: false
```

This produces two Services:
- `<release>-kong-proxy` (LoadBalancer with proxy_protocol)
- `<release>-kong-proxy-internal` (ClusterIP without proxy_protocol)

And the resulting `KONG_PROXY_LISTEN` will include listeners for all
configured ports across both the primary and additional proxies.

### Ingress Controller Parameters

All of the following properties are nested under the `ingressController`
Expand Down
45 changes: 45 additions & 0 deletions charts/kong/ci/additional-proxy-services-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Test additional proxy services feature
# This creates a second proxy service (ClusterIP) alongside the primary proxy (LoadBalancer)
# simulating the use case of external LB with proxy_protocol + internal ClusterIP without proxy_protocol

proxy:
enabled: true
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
http:
enabled: true
servicePort: 80
containerPort: 8000
parameters:
- proxy_protocol
tls:
enabled: true
servicePort: 443
containerPort: 8443
parameters:
- http2
- proxy_protocol

additionalProxies:
internal:
enabled: true
type: ClusterIP
annotations: {}
labels:
proxy-type: "internal"
http:
enabled: true
servicePort: 80
containerPort: 7000
parameters: []
tls:
enabled: true
servicePort: 443
containerPort: 7443
parameters:
- http2
appProtocol: ""
stream: []
ingress:
enabled: false
24 changes: 22 additions & 2 deletions charts/kong/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,17 @@ the template that it itself is using form the above sections.
{{- $_ := set $autoEnv "KONG_ADMIN_API_URI" (include "kong.ingress.serviceUrl" .Values.admin.ingress) -}}
{{- end -}}

{{- $_ := set $autoEnv "KONG_PROXY_LISTEN" (include "kong.listen" .Values.proxy) -}}
{{- $proxyListenStrings := list -}}
{{- $proxyListenStrings = append $proxyListenStrings (include "kong.listen" .Values.proxy) -}}
{{- range $name, $svcConfig := .Values.additionalProxies -}}
{{- if $svcConfig.enabled -}}
{{- $additionalListen := (include "kong.listen" $svcConfig) -}}
{{- if (ne $additionalListen "off") -}}
{{- $proxyListenStrings = append $proxyListenStrings $additionalListen -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $_ := set $autoEnv "KONG_PROXY_LISTEN" ($proxyListenStrings | join ", ") -}}

{{- $streamStrings := list -}}
{{- if .Values.proxy.enabled -}}
Expand All @@ -1094,7 +1104,17 @@ the template that it itself is using form the above sections.
{{- $_ := set $autoEnv "KONG_STATUS_LISTEN" (include "kong.listen" .Values.status) -}}

{{- if .Values.proxy.enabled -}}
{{- $_ := set $autoEnv "KONG_PORT_MAPS" (include "kong.port_maps" .Values.proxy) -}}
{{- $portMapStrings := list -}}
{{- $portMapStrings = append $portMapStrings (include "kong.port_maps" .Values.proxy) -}}
{{- range $name, $svcConfig := .Values.additionalProxies -}}
{{- if $svcConfig.enabled -}}
{{- $additionalPortMaps := (include "kong.port_maps" $svcConfig) -}}
{{- if (ne (len $additionalPortMaps) 0) -}}
{{- $portMapStrings = append $portMapStrings $additionalPortMaps -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $_ := set $autoEnv "KONG_PORT_MAPS" ($portMapStrings | join ", ") -}}
Comment on lines +1115 to +1125
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

additionalProxies streams are added to the deployment container ports, but are not included in KONG_STREAM_LISTEN here. This means Kong won't actually listen on those stream ports even though the container exposes them.

Should add something similar to what was done for KONG_PROXY_LISTEN above:

  {{- range $name, $svcConfig := .Values.additionalProxies -}}
    {{- if $svcConfig.enabled -}}
      {{- $additionalStream := (include "kong.streamListen" $svcConfig) -}}
      {{- if (not (eq $additionalStream "")) -}}
        {{- $streamStrings = (append $streamStrings $additionalStream) -}}
      {{- end -}}
    {{- end -}}
  {{- end -}}

{{- end -}}

{{- $_ := set $autoEnv "KONG_CLUSTER_LISTEN" (include "kong.listen" .Values.cluster) -}}
Expand Down
28 changes: 28 additions & 0 deletions charts/kong/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,34 @@ spec:
{{- end}}
protocol: {{ .protocol }}
{{- end }}
{{- range $name, $svcConfig := .Values.additionalProxies }}
{{- if $svcConfig.enabled }}
{{- if (and $svcConfig.http $svcConfig.http.enabled) }}
- name: {{ printf "px-%s" $name | trunc 15 | trimSuffix "-" }}
containerPort: {{ $svcConfig.http.containerPort }}
{{- if $svcConfig.http.hostPort }}
hostPort: {{ $svcConfig.http.hostPort }}
{{- end}}
protocol: TCP
{{- end }}
{{- if (and $svcConfig.tls $svcConfig.tls.enabled) }}
- name: {{ printf "px-%s-tls" $name | trunc 15 | trimSuffix "-" }}
containerPort: {{ $svcConfig.tls.containerPort }}
{{- if $svcConfig.tls.hostPort }}
hostPort: {{ $svcConfig.tls.hostPort }}
{{- end}}
protocol: TCP
{{- end }}
{{- range $svcConfig.stream }}
- name: {{ printf "pxs%s-%d" (ternary "u" "" (eq (default "TCP" .protocol) "UDP")) (int .containerPort) | trunc 15 | trimSuffix "-" }}
containerPort: {{ .containerPort }}
{{- if .hostPort }}
hostPort: {{ .hostPort }}
{{- end}}
protocol: {{ .protocol }}
{{- end }}
{{- end }}
{{- end }}
{{- range .Values.udpProxy.stream }}
- name: streamudp-{{ .containerPort }}
containerPort: {{ .containerPort }}
Expand Down
21 changes: 21 additions & 0 deletions charts/kong/templates/service-kong-proxy-additional.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{{- if .Values.deployment.kong.enabled }}
{{- range $name, $svcConfig := .Values.additionalProxies }}
{{- if $svcConfig.enabled }}
{{- if or (and $svcConfig.http $svcConfig.http.enabled) (and $svcConfig.tls $svcConfig.tls.enabled) }}
{{- $serviceConfig := dict -}}
{{- $serviceConfig := merge $serviceConfig $svcConfig -}}
{{- $_ := set $serviceConfig "fullName" (include "kong.fullname" $) -}}
{{- $_ := set $serviceConfig "namespace" (include "kong.namespace" $) -}}
{{- $_ := set $serviceConfig "metaLabels" (include "kong.metaLabels" $) -}}
{{- $_ := set $serviceConfig "selectorLabels" (include "kong.selectorLabels" $) -}}
{{- $_ := set $serviceConfig "serviceName" (printf "proxy-%s" $name) }}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerned about the length here; let me double-check the details.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final Service name rendered by kong.service is

{{- define "kong.service" -}}
apiVersion: v1
kind: Service
metadata:
name: {{ .nameOverride | default (printf "%s-%s" .fullName .serviceName) }}

where .fullName itself is already {{ .Release.Name }}-{{ .Chart.Name }}. Kubernetes limits Service names to 63 characters, so a long release name combined with a long $name key could exceed this limit.

The chart already applies trunc 63 | trimSuffix "-" in similar places, for example

{{- default (printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-") .Values.fullnameOverride -}}

I think we should do the same here. Something like:

{{- $_ := set $serviceConfig "serviceName" (printf "proxy-%s" $name | trunc 63 | trimSuffix "-") }}

---
{{ include "kong.service" $serviceConfig }}
{{- if (and $svcConfig.ingress $svcConfig.ingress.enabled) }}
---
{{ include "kong.ingress" $serviceConfig }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
48 changes: 48 additions & 0 deletions charts/kong/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,54 @@ udpProxy:
# # "ssl" is required for SNI-based routes. It is not supported on versions <2.0
# parameters: []

# --------------------------------------------------------------------------
# Additional proxy services
# --------------------------------------------------------------------------
# Define additional proxy services for the Kong proxy. Each entry creates a
# separate Kubernetes Service that routes to the same Kong proxy container.
# This is useful when you need multiple network paths with different
# configurations, for example:
# - An external LoadBalancer with proxy_protocol for AWS NLB traffic
# - An internal ClusterIP service without proxy_protocol for in-cluster access
#
# Each additional proxy adds its own listeners to KONG_PROXY_LISTEN and
# KONG_PORT_MAPS automatically, and exposes the corresponding container ports
# in the deployment.
#
# IMPORTANT: Use container ports that do not conflict with the primary proxy
# ports (8000/8443) or any other Kong listener ports.
additionalProxies: {}
# Example: an internal ClusterIP proxy without proxy_protocol
# internal:
# enabled: true
# type: ClusterIP
# loadBalancerClass: ""
# loadBalancerSourceRanges: []
# nameOverride: ""
# annotations: {}
# labels: {}
# http:
# enabled: true
# servicePort: 80
# containerPort: 7000
# parameters: []
# tls:
# enabled: true
# servicePort: 443
# containerPort: 7443
# parameters:
# - http2
# appProtocol: ""
# stream: []
# ingress:
# enabled: false
# ingressClassName:
# annotations: {}
# labels: {}
# hostname:
# path: /
# pathType: ImplementationSpecific

# Custom Kong plugins can be loaded into Kong by mounting the plugin code
# into the file-system of Kong container.
# The plugin code should be present in ConfigMap or Secret inside the same
Expand Down
Loading