Skip to content

Commit e48e24e

Browse files
committed
MINOR: haproxy: add support for loadBalancerClass
The Service template rendered loadBalancerIP and loadBalancerSourceRanges but had no way to select a non-default load balancer implementation, leaving this the only chart in the repo without loadBalancerClass after 1.2.0 added it to haproxy-unified-gateway. Unlike the other two charts, this one declares kubeVersion ">=1.17.0-0", which predates the field entirely (added in Kubernetes 1.21, GA in 1.24). Gate it behind semverCompare ">=1.21.0-0", matching how the same template already gates trafficDistribution behind 1.31, and additionally on type=LoadBalancer since the API server forbids loadBalancerClass on any other Service type. No ci/ values file: `ct install` and integration-test.sh use `helm install --wait`, which blocks until a LoadBalancer Service reports status.loadBalancer.ingress, and this chart is not in LB_CHARTS in .github/scripts/install_charts.sh so cloud-provider-kind is not running. The test_loadbalancer_fields checks in test/local-test.sh pick this chart up automatically now that values.yaml carries the key. Also fix the absence assertion in that helper to use [[:space:]] instead of the GNU-only \s, which BSD grep does not support in ERE; on macOS the check could never match and so always passed. Chart version 1.29.0 -> 1.30.0. Signed-off-by: Dinko Korunic <dkorunic@haproxy.com>
1 parent 1bddcb5 commit e48e24e

5 files changed

Lines changed: 29 additions & 2 deletions

File tree

haproxy/Chart.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ apiVersion: v2
1616
name: haproxy
1717
description: A Helm chart for HAProxy on Kubernetes
1818
type: application
19-
version: 1.29.0
19+
version: 1.30.0
2020
appVersion: 3.3.10
2121
kubeVersion: ">=1.17.0-0"
2222
keywords:
@@ -39,3 +39,4 @@ annotations:
3939
url: https://github.com/haproxytech/helm-charts/issues
4040
artifacthub.io/changes: |
4141
- Update base image to HAProxy 3.3.10
42+
- Add support for loadBalancerClass

haproxy/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,21 @@ helm install my-haproxy4 haproxytech/haproxy \
135135

136136
**_NOTE_**: With helm `--set` it is needed to put quotes and escape dots in the annotation key and commas in the value string.
137137

138+
### Selecting a LoadBalancer implementation
139+
140+
When more than one load balancer controller runs in a cluster, `service.loadBalancerClass` picks which one reconciles the Service. Leaving it unset uses the cluster's default implementation:
141+
142+
```console
143+
helm install my-haproxy5 haproxytech/haproxy \
144+
--set service.type=LoadBalancer \
145+
--set service.loadBalancerClass="example.com/internal-lb" \
146+
--set service.loadBalancerSourceRanges[0]="192.0.2.0/24"
147+
```
148+
149+
**_NOTE_**: `loadBalancerClass` renders only when `service.type` is `LoadBalancer` and the cluster is Kubernetes 1.21 or newer (the field is GA as of 1.24). On older clusters it is omitted.
150+
151+
**_NOTE_**: `loadBalancerClass` is immutable while the Service stays type `LoadBalancer`. Kubernetes rejects a change on an existing Service, so `helm upgrade` cannot alter it in place - the Service has to be recreated.
152+
138153
### Using values from YAML file
139154

140155
As opposed to using many `--set` invocations, much simpler approach is to define value overrides in a separate YAML file and specify them when invoking Helm.

haproxy/templates/service.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ spec:
5151
loadBalancerSourceRanges:
5252
{{- toYaml . | nindent 2 }}
5353
{{- end }}
54+
{{- /* loadBalancerClass exists from Kubernetes 1.21 (GA 1.24) and the API
55+
server forbids it unless type is LoadBalancer, so gate on both. */}}
56+
{{- if and (semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version) (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerClass }}
57+
loadBalancerClass: {{ .Values.service.loadBalancerClass | quote }}
58+
{{- end }}
5459
{{- if .Values.service.ipFamilies }}
5560
ipFamilies:
5661
{{- toYaml .Values.service.ipFamilies | nindent 2 }}

haproxy/values.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,12 @@ service:
506506
# ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/
507507
loadBalancerSourceRanges: []
508508

509+
## Class of load balancer implementation, rendered only when type is
510+
## LoadBalancer and Kubernetes is >= 1.21 (GA in 1.24). Immutable while the
511+
## Service stays type LoadBalancer, so helm upgrade cannot change it in place
512+
# ref: https://kubernetes.io/docs/concepts/services-networking/service/#load-balancer-class
513+
loadBalancerClass: null
514+
509515
## Service ExternalIPs
510516
# ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips
511517
externalIPs: []

test/local-test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ test_loadbalancer_fields() {
467467
local label="$chart: LoadBalancer fields absent with default Service type"
468468
local output
469469
output=$(helm template test-release "$REPO_ROOT/$chart" 2>&1)
470-
if echo "$output" | grep -qE '^\s+loadBalancer(IP|Class|SourceRanges):'; then
470+
if echo "$output" | grep -qE '^[[:space:]]+loadBalancer(IP|Class|SourceRanges):'; then
471471
log_fail "$label"
472472
else
473473
log_pass "$label"

0 commit comments

Comments
 (0)