Skip to content

Commit d8fbbcb

Browse files
authored
feat(helm): add support for nodePort specification in LoadBalancer services helm chart (coder#16032)
## Short description: This pull request introduces support for optionally specify `nodePort` values when using `LoadBalancer` service type in the Coder Helm chart. This enhancement addresses a limitation where `httpNodePort` and `httpsNodePort` values were previously ignored for `LoadBalancer` services. This PR should expand the service customization options without disrupting existing configurations. ## Why this is Useful In some enterprise environments, applications may be required to use specific ports for compliance with organizational policies or cloud infrastructure requirements. For instance: - Reserved port blocks are allocated for specific applications for security and clarity. - Ensuring predictable port assignments helps in debugging and management scenarios. Since LoadBalancer in Kubernetes operates on top of nodePort, this feature is useful for enabling enterprises to adhere to such policies if they whish. ## What Was Changed - Updated helm/coder/templates/service.yaml: - Allowed nodePort specification for both NodePort and LoadBalancer service types. - Updated helm/coder/templates/values.yaml: - Updated inline comments to reflect the changes for nodeport values use cases. ### Regarding backward compatibility: If nodePort is not specified, Kubernetes dynamically assigns a port, maintaining the current behavior. ### Testing Performed - Validated through Helm dry-run: nodePort values are rendered correctly in the resulting Kubernetes YAML. - Deployed the updated chart in an enterprise Kubernetes cluster. - Tested coder environment with LoadBalancer service and specified nodePort values for both HTTP and HTTPS. ## Additional Notes - This PR expands the nodeport functionality introduced in PR coder#8993 to the Loadbalancer service. - If merged, an update to the documentation to include examples of LoadBalancer with nodePort values may be useful. - I've read the contributing guidelines and code of conduct. This is my first PR for the Coder project, and I hope it meets the community standards. Any advice, feedback, or help is greatly appreciated!
1 parent 2913fe8 commit d8fbbcb

25 files changed

+427
-26
lines changed

helm/coder/templates/service.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@ spec:
1616
port: 80
1717
targetPort: "http"
1818
protocol: TCP
19-
{{ if eq .Values.coder.service.type "NodePort" }}
19+
{{- if or (eq .Values.coder.service.type "NodePort") (eq .Values.coder.service.type "LoadBalancer") }}
2020
nodePort: {{ .Values.coder.service.httpNodePort }}
21-
{{ end }}
21+
{{- end }}
2222
{{- if eq (include "coder.tlsEnabled" .) "true" }}
2323
- name: "https"
2424
port: 443
2525
targetPort: "https"
2626
protocol: TCP
27-
{{ if eq .Values.coder.service.type "NodePort" }}
27+
{{- if or (eq .Values.coder.service.type "NodePort") (eq .Values.coder.service.type "LoadBalancer") }}
2828
nodePort: {{ .Values.coder.service.httpsNodePort }}
29-
{{ end }}
29+
{{- end }}
3030
{{- end }}
3131
{{- if eq "LoadBalancer" .Values.coder.service.type }}
3232
{{- with .Values.coder.service.loadBalancerIP }}

helm/coder/tests/chart_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ var testCases = []testCase{
100100
name: "svc_loadbalancer_class",
101101
expectedError: "",
102102
},
103+
{
104+
name: "svc_nodeport",
105+
expectedError: "",
106+
},
107+
{
108+
name: "svc_loadbalancer",
109+
expectedError: "",
110+
},
103111
}
104112

105113
type testCase struct {

helm/coder/tests/testdata/auto_access_url_1.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
93+
nodePort:
9494
externalTrafficPolicy: "Cluster"
9595
selector:
9696
app.kubernetes.io/name: coder

helm/coder/tests/testdata/auto_access_url_2.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
93+
nodePort:
9494
externalTrafficPolicy: "Cluster"
9595
selector:
9696
app.kubernetes.io/name: coder

helm/coder/tests/testdata/auto_access_url_3.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
93+
nodePort:
9494
externalTrafficPolicy: "Cluster"
9595
selector:
9696
app.kubernetes.io/name: coder

helm/coder/tests/testdata/command.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
93+
nodePort:
9494
externalTrafficPolicy: "Cluster"
9595
selector:
9696
app.kubernetes.io/name: coder

helm/coder/tests/testdata/command_args.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
93+
nodePort:
9494
externalTrafficPolicy: "Cluster"
9595
selector:
9696
app.kubernetes.io/name: coder

helm/coder/tests/testdata/default_values.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
93+
nodePort:
9494
externalTrafficPolicy: "Cluster"
9595
selector:
9696
app.kubernetes.io/name: coder

helm/coder/tests/testdata/env_from.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
93+
nodePort:
9494
externalTrafficPolicy: "Cluster"
9595
selector:
9696
app.kubernetes.io/name: coder

helm/coder/tests/testdata/extra_templates.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ spec:
9999
port: 80
100100
targetPort: "http"
101101
protocol: TCP
102-
102+
nodePort:
103103
externalTrafficPolicy: "Cluster"
104104
selector:
105105
app.kubernetes.io/name: coder

helm/coder/tests/testdata/labels_annotations.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
93+
nodePort:
9494
externalTrafficPolicy: "Cluster"
9595
selector:
9696
app.kubernetes.io/name: coder

helm/coder/tests/testdata/prometheus.golden

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
9493
nodePort:
95-
9694
selector:
9795
app.kubernetes.io/name: coder
9896
app.kubernetes.io/instance: release-name

helm/coder/tests/testdata/provisionerd_psk.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
93+
nodePort:
9494
externalTrafficPolicy: "Cluster"
9595
selector:
9696
app.kubernetes.io/name: coder

helm/coder/tests/testdata/sa.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ spec:
9191
port: 80
9292
targetPort: "http"
9393
protocol: TCP
94-
94+
nodePort:
9595
externalTrafficPolicy: "Cluster"
9696
selector:
9797
app.kubernetes.io/name: coder

helm/coder/tests/testdata/sa_disabled.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ spec:
7676
port: 80
7777
targetPort: "http"
7878
protocol: TCP
79-
79+
nodePort:
8080
externalTrafficPolicy: "Cluster"
8181
selector:
8282
app.kubernetes.io/name: coder

helm/coder/tests/testdata/sa_extra_rules.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ spec:
104104
port: 80
105105
targetPort: "http"
106106
protocol: TCP
107-
107+
nodePort:
108108
externalTrafficPolicy: "Cluster"
109109
selector:
110110
app.kubernetes.io/name: coder
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
---
2+
# Source: coder/templates/coder.yaml
3+
apiVersion: v1
4+
kind: ServiceAccount
5+
metadata:
6+
annotations: {}
7+
labels:
8+
app.kubernetes.io/instance: release-name
9+
app.kubernetes.io/managed-by: Helm
10+
app.kubernetes.io/name: coder
11+
app.kubernetes.io/part-of: coder
12+
app.kubernetes.io/version: 0.1.0
13+
helm.sh/chart: coder-0.1.0
14+
name: coder
15+
---
16+
# Source: coder/templates/rbac.yaml
17+
apiVersion: rbac.authorization.k8s.io/v1
18+
kind: Role
19+
metadata:
20+
name: coder-workspace-perms
21+
rules:
22+
- apiGroups: [""]
23+
resources: ["pods"]
24+
verbs:
25+
- create
26+
- delete
27+
- deletecollection
28+
- get
29+
- list
30+
- patch
31+
- update
32+
- watch
33+
- apiGroups: [""]
34+
resources: ["persistentvolumeclaims"]
35+
verbs:
36+
- create
37+
- delete
38+
- deletecollection
39+
- get
40+
- list
41+
- patch
42+
- update
43+
- watch
44+
- apiGroups:
45+
- apps
46+
resources:
47+
- deployments
48+
verbs:
49+
- create
50+
- delete
51+
- deletecollection
52+
- get
53+
- list
54+
- patch
55+
- update
56+
- watch
57+
---
58+
# Source: coder/templates/rbac.yaml
59+
apiVersion: rbac.authorization.k8s.io/v1
60+
kind: RoleBinding
61+
metadata:
62+
name: "coder"
63+
subjects:
64+
- kind: ServiceAccount
65+
name: "coder"
66+
roleRef:
67+
apiGroup: rbac.authorization.k8s.io
68+
kind: Role
69+
name: coder-workspace-perms
70+
---
71+
# Source: coder/templates/service.yaml
72+
apiVersion: v1
73+
kind: Service
74+
metadata:
75+
name: coder
76+
labels:
77+
helm.sh/chart: coder-0.1.0
78+
app.kubernetes.io/name: coder
79+
app.kubernetes.io/instance: release-name
80+
app.kubernetes.io/part-of: coder
81+
app.kubernetes.io/version: "0.1.0"
82+
app.kubernetes.io/managed-by: Helm
83+
annotations:
84+
{}
85+
spec:
86+
type: LoadBalancer
87+
sessionAffinity: None
88+
ports:
89+
- name: "http"
90+
port: 80
91+
targetPort: "http"
92+
protocol: TCP
93+
nodePort: 30080
94+
externalTrafficPolicy: "Cluster"
95+
selector:
96+
app.kubernetes.io/name: coder
97+
app.kubernetes.io/instance: release-name
98+
---
99+
# Source: coder/templates/coder.yaml
100+
apiVersion: apps/v1
101+
kind: Deployment
102+
metadata:
103+
annotations: {}
104+
labels:
105+
app.kubernetes.io/instance: release-name
106+
app.kubernetes.io/managed-by: Helm
107+
app.kubernetes.io/name: coder
108+
app.kubernetes.io/part-of: coder
109+
app.kubernetes.io/version: 0.1.0
110+
helm.sh/chart: coder-0.1.0
111+
name: coder
112+
spec:
113+
replicas: 1
114+
selector:
115+
matchLabels:
116+
app.kubernetes.io/instance: release-name
117+
app.kubernetes.io/name: coder
118+
template:
119+
metadata:
120+
annotations: {}
121+
labels:
122+
app.kubernetes.io/instance: release-name
123+
app.kubernetes.io/managed-by: Helm
124+
app.kubernetes.io/name: coder
125+
app.kubernetes.io/part-of: coder
126+
app.kubernetes.io/version: 0.1.0
127+
helm.sh/chart: coder-0.1.0
128+
spec:
129+
affinity:
130+
podAntiAffinity:
131+
preferredDuringSchedulingIgnoredDuringExecution:
132+
- podAffinityTerm:
133+
labelSelector:
134+
matchExpressions:
135+
- key: app.kubernetes.io/instance
136+
operator: In
137+
values:
138+
- coder
139+
topologyKey: kubernetes.io/hostname
140+
weight: 1
141+
containers:
142+
- args:
143+
- server
144+
command:
145+
- /opt/coder
146+
env:
147+
- name: CODER_HTTP_ADDRESS
148+
value: 0.0.0.0:8080
149+
- name: CODER_PROMETHEUS_ADDRESS
150+
value: 0.0.0.0:2112
151+
- name: CODER_ACCESS_URL
152+
value: http://coder.default.svc.cluster.local
153+
- name: KUBE_POD_IP
154+
valueFrom:
155+
fieldRef:
156+
fieldPath: status.podIP
157+
- name: CODER_DERP_SERVER_RELAY_URL
158+
value: http://$(KUBE_POD_IP):8080
159+
image: ghcr.io/coder/coder:latest
160+
imagePullPolicy: IfNotPresent
161+
lifecycle: {}
162+
livenessProbe:
163+
httpGet:
164+
path: /healthz
165+
port: http
166+
scheme: HTTP
167+
name: coder
168+
ports:
169+
- containerPort: 8080
170+
name: http
171+
protocol: TCP
172+
readinessProbe:
173+
httpGet:
174+
path: /healthz
175+
port: http
176+
scheme: HTTP
177+
resources: {}
178+
securityContext:
179+
allowPrivilegeEscalation: false
180+
readOnlyRootFilesystem: null
181+
runAsGroup: 1000
182+
runAsNonRoot: true
183+
runAsUser: 1000
184+
seccompProfile:
185+
type: RuntimeDefault
186+
volumeMounts: []
187+
restartPolicy: Always
188+
serviceAccountName: coder
189+
terminationGracePeriodSeconds: 60
190+
volumes: []
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
coder:
2+
image:
3+
tag: latest
4+
5+
service:
6+
type: LoadBalancer
7+
httpNodePort: 30080
8+
httpsNodePort: 30043

helm/coder/tests/testdata/svc_loadbalancer_class.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
port: 80
9191
targetPort: "http"
9292
protocol: TCP
93-
93+
nodePort:
9494
externalTrafficPolicy: "Cluster"
9595
loadBalancerClass: "test"
9696
selector:

0 commit comments

Comments
 (0)