Skip to content

Commit af16a26

Browse files
authored
feat(chart): Simplify to access Selenium Grid from outside of Kubernetes (#2073)
[deploy] Signed-off-by: Viet Nguyen Duc <[email protected]>
1 parent 02e6af2 commit af16a26

18 files changed

+362
-39
lines changed

charts/selenium-grid/Chart.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ dependencies:
1010
version: 2.12.1
1111
name: keda
1212
condition: autoscaling.enabled
13+
- repository: https://kubernetes.github.io/ingress-nginx
14+
version: 4.8.3
15+
name: ingress-nginx
16+
condition: ingress-nginx.enabled
1317
maintainers:
1418
- name: SeleniumHQ
1519

charts/selenium-grid/README.md

Lines changed: 73 additions & 1 deletion
Large diffs are not rendered by default.

charts/selenium-grid/templates/NOTES.txt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,27 @@ Selenium Grid Server deployed successfully.
99
{{- if .Values.ingress.enabled }}
1010
{{- if .Values.ingress.hostname }}
1111
1. Ingress is enabled, and it exposes the Grid Hub or Grid Router with the hostname you supplied.
12-
To access Selenium from outside of Kubernetes, simply open http://{{ .Values.ingress.hostname }}.
13-
{{- else}}
12+
To access Selenium from outside of Kubernetes, simply open {{ include "seleniumGrid.url" .}}.
13+
{{- else if and (empty .Values.ingress.hostname) .Values.global.K8S_PUBLIC_IP }}
14+
1. Ingress is enabled, but hostname doesn't set, and it exposes the Grid Hub or Grid Router with the K8S_PUBLIC_IP you supplied.
15+
To access Selenium from outside of Kubernetes, simply open {{ include "seleniumGrid.url" .}}.
16+
{{- else }}
1417
1. Ingress is enabled, but hostname doesn't set. All inbound HTTP traffic will be routed to the Grid by matching any host.
1518
Please keep in mind that it is rarely necessary, and in most cases, you shall provide `ingress.hostname` in values.yaml.
1619
To access Selenium from outside of Kubernetes:
17-
- open IP of the any node with Ingress, or
20+
- open the IP of any node with Ingress, or
1821
- any hostname pointing to the node with Ingress
1922
{{- end}}
2023
{{- else}}
21-
1. Ingress is disabled. To access Selenium from outside of Kubernetes, simply run these commands:
2224
{{- if contains "NodePort" $serviceType }}
23-
export NODE_PORT=$(kubectl get -n {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" svc {{ $svcName }})
25+
{{- if .Values.global.K8S_PUBLIC_IP }}
26+
1. Ingress is disabled, and it exposes the Grid Hub or Grid Router with NodePort and the K8S_PUBLIC_IP you supplied
27+
To access Selenium from outside of Kubernetes with NodePort and K8S_PUBLIC_IP you supplied, simply open {{ include "seleniumGrid.url" .}}.
28+
{{- else }}
29+
1. Ingress is disabled. To access Selenium from outside of Kubernetes, simply run these commands:
2430
export NODE_IP=$(kubectl get nodes -n {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
25-
echo http://$NODE_IP:$NODE_PORT
31+
echo http://$NODE_IP:{{ include "seleniumGrid.url.port" .}}{{ include "seleniumGrid.url.subPath" .}}
32+
{{- end }}
2633
{{- else if contains "LoadBalancer" $serviceType }}
2734
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
2835
You can watch the status of by running 'kubectl get -n {{ .Release.Namespace }} svc -w {{ $svcName }}'

charts/selenium-grid/templates/_helpers.tpl

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -341,28 +341,87 @@ template:
341341
Get the url of the grid. If the external url can be figured out from the ingress use that, otherwise the cluster internal url
342342
*/}}
343343
{{- define "seleniumGrid.url" -}}
344-
{{- if and .Values.ingress.enabled .Values.ingress.hostname (ne .Values.ingress.hostname "selenium-grid.local") -}}
345-
http{{if .Values.ingress.tls}}s{{end}}://{{- if eq .Values.basicAuth.enabled true}}{{ .Values.basicAuth.username}}:{{ .Values.basicAuth.password}}@{{- end}}{{.Values.ingress.hostname}}
344+
{{- $url := printf "%s://%s%s%s%s" (include "seleniumGrid.url.schema" .) (include "seleniumGrid.url.basicAuth" .) (include "seleniumGrid.url.host" .) (include "seleniumGrid.url.port" .) (include "seleniumGrid.url.subPath" .) -}}
345+
{{- $url }}
346+
{{- end -}}
347+
348+
{{- define "seleniumGrid.url.schema" -}}
349+
{{- $schema := "http" -}}
350+
{{- if .Values.ingress.enabled -}}
351+
{{- if .Values.ingress.tls -}}
352+
{{- $schema = "https" -}}
353+
{{- end -}}
354+
{{- end -}}
355+
{{- $schema }}
356+
{{- end -}}
357+
358+
{{- define "seleniumGrid.url.basicAuth" -}}
359+
{{- $basicAuth := "" -}}
360+
{{- if eq .Values.basicAuth.enabled true -}}
361+
{{- $basicAuth = printf "%s:%s@" .Values.basicAuth.username (.Values.basicAuth.password | toString) -}}
362+
{{- end -}}
363+
{{- $basicAuth }}
364+
{{- end -}}
365+
366+
{{- define "seleniumGrid.url.host" -}}
367+
{{- $host := printf "%s.%s" (include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $ ) (.Release.Namespace) -}}
368+
{{- if .Values.ingress.enabled -}}
369+
{{- if and ( empty .Values.ingress.hostname) (not (empty .Values.global.K8S_PUBLIC_IP)) -}}
370+
{{- $host = .Values.global.K8S_PUBLIC_IP -}}
371+
{{- else if and .Values.ingress.hostname (ne .Values.ingress.hostname "selenium-grid.local") -}}
372+
{{- $host = .Values.ingress.hostname -}}
373+
{{- end -}}
374+
{{- else if not (empty .Values.global.K8S_PUBLIC_IP) -}}
375+
{{- $host = .Values.global.K8S_PUBLIC_IP -}}
376+
{{- end -}}
377+
{{- $host }}
378+
{{- end -}}
379+
380+
{{- define "seleniumGrid.url.port" -}}
381+
{{- $port := ":4444" -}}
382+
{{- if .Values.ingress.enabled -}}
383+
{{- if or (ne (.Values.ingress.ports.http | toString) "80") (ne (.Values.ingress.ports.https | toString) "443") -}}
384+
{{- $port = printf ":%s" (ternary (.Values.ingress.ports.http | toString) (.Values.ingress.ports.https | toString) (eq (include "seleniumGrid.url.schema" .) "http")) -}}
385+
{{- else -}}
386+
{{- $port = "" -}}
387+
{{- end -}}
346388
{{- else -}}
347-
http://{{- if eq .Values.basicAuth.enabled true}}{{ .Values.basicAuth.username}}:{{ .Values.basicAuth.password}}@{{- end}}{{ include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $ }}.{{ .Release.Namespace }}:{{ $.Values.components.router.port }}
348-
{{- end }}
389+
{{- if .Values.isolateComponents -}}
390+
{{- if and (eq .Values.components.router.serviceType "NodePort") .Values.components.router.nodePort -}}
391+
{{- $port = printf ":%s" (.Values.components.router.nodePort | toString) -}}
392+
{{- end -}}
393+
{{- else -}}
394+
{{- if and (eq .Values.hub.serviceType "NodePort") .Values.hub.nodePort -}}
395+
{{- $port = printf ":%s" (.Values.hub.nodePort | toString) -}}
396+
{{- end -}}
397+
{{- end -}}
398+
{{- end -}}
399+
{{- $port }}
349400
{{- end -}}
350401

351402
{{- define "seleniumGrid.url.subPath" -}}
352403
{{- $subPath := "/" -}}
353-
{{ if $.Values.isolateComponents }}
404+
{{- if $.Values.isolateComponents -}}
354405
{{- $subPath = default $subPath $.Values.components.subPath -}}
355406
{{- else -}}
356407
{{- $subPath = default $subPath $.Values.hub.subPath -}}
357408
{{- end -}}
358-
{{ $subPath }}
409+
{{- $subPath }}
359410
{{- end -}}
360411

361412
{{/*
362413
Graphql Url of the hub or the router
363414
*/}}
364415
{{- define "seleniumGrid.graphqlURL" -}}
365-
http://{{- if eq .Values.basicAuth.enabled true}}{{ .Values.basicAuth.username}}:{{ .Values.basicAuth.password}}@{{- end}}{{ include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $ }}.{{ .Release.Namespace }}:{{ $.Values.components.router.port }}/graphql
416+
{{- printf "http://%s%s%s/graphql" (include "seleniumGrid.url.basicAuth" .) (printf "%s.%s" (include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $) (.Release.Namespace)) (printf ":%s" ($.Values.isolateComponents | ternary ($.Values.components.router.port | toString) ($.Values.hub.port | toString))) -}}
417+
{{- end -}}
418+
419+
{{/*
420+
Graphql unsafeSsl of the hub or the router
421+
*/}}
422+
{{- define "seleniumGrid.graphqlURL.unsafeSsl" -}}
423+
{{- $unsafeSsl := printf "%s" (ternary "false" "true" (contains (include "seleniumGrid.graphqlURL" .) "https")) -}}
424+
{{- $unsafeSsl }}
366425
{{- end -}}
367426

368427
{{/*

charts/selenium-grid/templates/distributor-service.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,7 @@ spec:
2323
protocol: TCP
2424
port: {{ .Values.components.distributor.port }}
2525
targetPort: {{ .Values.components.distributor.port }}
26+
{{- if and (eq .Values.components.distributor.serviceType "NodePort") .Values.components.distributor.nodePort }}
27+
nodePort: {{ .Values.components.distributor.nodePort }}
28+
{{- end }}
2629
{{- end }}

charts/selenium-grid/templates/event-bus-service.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,21 @@ spec:
2323
protocol: TCP
2424
port: {{ .Values.components.eventBus.port }}
2525
targetPort: {{ .Values.components.eventBus.port }}
26+
{{- if and (eq .Values.components.eventBus.serviceType "NodePort") .Values.components.eventBus.nodePort }}
27+
nodePort: {{ .Values.components.eventBus.nodePort }}
28+
{{- end }}
2629
- name: tcp-evtbus-pub
2730
protocol: TCP
2831
port: {{ .Values.components.eventBus.publishPort }}
2932
targetPort: {{ .Values.components.eventBus.publishPort }}
33+
{{- if and (eq .Values.components.eventBus.serviceType "NodePort") .Values.components.eventBus.publishNodePort }}
34+
nodePort: {{ .Values.components.eventBus.publishNodePort }}
35+
{{- end }}
3036
- name: tcp-evtbus-sub
3137
protocol: TCP
3238
port: {{ .Values.components.eventBus.subscribePort }}
3339
targetPort: {{ .Values.components.eventBus.subscribePort }}
40+
{{- if and (eq .Values.components.eventBus.serviceType "NodePort") .Values.components.eventBus.subscribeNodePort }}
41+
nodePort: {{ .Values.components.eventBus.subscribeNodePort }}
42+
{{- end }}
3443
{{- end }}

charts/selenium-grid/templates/hub-service.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,21 @@ spec:
2626
protocol: TCP
2727
port: {{ .Values.hub.port }}
2828
targetPort: {{ .Values.hub.port }}
29+
{{- if and (eq .Values.hub.serviceType "NodePort") .Values.hub.nodePort }}
30+
nodePort: {{ .Values.hub.nodePort }}
31+
{{- end }}
2932
- name: tcp-hub-pub
3033
protocol: TCP
3134
port: {{ .Values.hub.publishPort }}
3235
targetPort: {{ .Values.hub.publishPort }}
36+
{{- if and (eq .Values.hub.serviceType "NodePort") .Values.hub.publishNodePort }}
37+
nodePort: {{ .Values.hub.publishNodePort }}
38+
{{- end }}
3339
- name: tcp-hub-sub
3440
protocol: TCP
3541
port: {{ .Values.hub.subscribePort }}
3642
targetPort: {{ .Values.hub.subscribePort }}
43+
{{- if and (eq .Values.hub.serviceType "NodePort") .Values.hub.subscribeNodePort }}
44+
nodePort: {{ .Values.hub.subscribeNodePort }}
45+
{{- end }}
3746
{{- end }}

charts/selenium-grid/templates/node-configmap.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ metadata:
1313
{{- end }}
1414
data:
1515
SE_DRAIN_AFTER_SESSION_COUNT: '{{- and (eq (include "seleniumGrid.useKEDA" .) "true") (eq .Values.autoscaling.scalingType "job") | ternary "1" "0" -}}'
16-
SE_NODE_GRID_URL: '{{ include "seleniumGrid.url" .}}{{ include "seleniumGrid.url.subPath" .}}'
16+
SE_NODE_GRID_URL: '{{ include "seleniumGrid.url" .}}'

charts/selenium-grid/templates/router-service.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ spec:
2626
protocol: TCP
2727
port: {{ .Values.components.router.port }}
2828
targetPort: {{ .Values.components.router.port }}
29+
{{- if and (eq $.Values.components.router.serviceType "NodePort") $.Values.components.router.nodePort }}
30+
nodePort: {{ $.Values.components.router.nodePort }}
31+
{{- end }}
2932
{{- end }}

charts/selenium-grid/templates/session-queuer-service.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,7 @@ spec:
2323
protocol: TCP
2424
port: {{ .Values.components.sessionQueue.port }}
2525
targetPort: {{ .Values.components.sessionQueue.port }}
26+
{{- if and (eq .Values.components.sessionQueue.serviceType "NodePort") .Values.components.sessionQueue.nodePort }}
27+
nodePort: {{ .Values.components.sessionQueue.nodePort }}
28+
{{- end }}
2629
{{- end }}

charts/selenium-grid/values.yaml

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
global:
2+
# Public IP of the host running Kubernetes cluster.
3+
# This is used to access the Selenium Grid from outside the cluster when ingress is disabled or enabled without a hostname is set.
4+
# This is part of constructing SE_NODE_GRID_URL and rewrite URL of `se:vnc`, `se:cdp` in the capabilities when `ingress.hostname` is unset
5+
K8S_PUBLIC_IP: ""
26
seleniumGrid:
37
# Image registry for all selenium components
48
imageRegistry: selenium
@@ -44,6 +48,9 @@ ingress:
4448
proxyBuffer:
4549
size: 512M
4650
number: 4
51+
ports:
52+
http: 80
53+
https: 443
4754
# Custom annotations for ingress resource
4855
annotations: {}
4956
# Default host for the ingress resource
@@ -96,6 +103,7 @@ components:
96103
annotations: {}
97104
# Router port
98105
port: 4444
106+
nodePort: 30444
99107
# Liveness probe settings
100108
livenessProbe:
101109
enabled: true
@@ -148,6 +156,7 @@ components:
148156
annotations: {}
149157
# Distributor port
150158
port: 5553
159+
nodePort: 30553
151160
# Resources for Distributor container
152161
resources: {}
153162
# SecurityContext for Distributor container
@@ -180,10 +189,13 @@ components:
180189
annotations: {}
181190
# Event Bus port
182191
port: 5557
192+
nodePort: 30557
183193
# Port where events are published
184194
publishPort: 4442
195+
publishNodePort: 30442
185196
# Port where to subscribe for events
186197
subscribePort: 4443
198+
subscribeNodePort: 30443
187199
# Resources for event-bus container
188200
resources: {}
189201
# SecurityContext for event-bus container
@@ -246,6 +258,7 @@ components:
246258
# Custom annotations for Session Queue pods
247259
annotations: {}
248260
port: 5559
261+
nodePort: 30559
249262
# Resources for Session Queue container
250263
resources: {}
251264
# SecurityContext for Session Queue container
@@ -299,10 +312,13 @@ hub:
299312
labels: {}
300313
# Port where events are published
301314
publishPort: 4442
315+
publishNodePort: 31442
302316
# Port where to subscribe for events
303317
subscribePort: 4443
318+
subscribeNodePort: 31443
304319
# Selenium Hub port
305320
port: 4444
321+
nodePort: 31444
306322
# Liveness probe settings
307323
livenessProbe:
308324
enabled: true
@@ -387,7 +403,8 @@ autoscaling:
387403
# see https://keda.sh/docs/latest/concepts/scaling-jobs/#scaledjob-spec
388404
scaledJobOptions:
389405
scalingStrategy:
390-
strategy: accurate
406+
# Change this to "accurate" when the calculation problem is fixed
407+
strategy: default
391408
# Number of Completed jobs should be kept
392409
successfulJobsHistoryLimit: 0
393410
# Number of Failed jobs should be kept (for troubleshooting purposes)
@@ -535,8 +552,9 @@ chromeNode:
535552
hpa:
536553
url: '{{ include "seleniumGrid.graphqlURL" . }}'
537554
browserName: chrome
555+
sessionBrowserName: 'chrome'
538556
# browserVersion: '91.0' # Optional. Only required when supporting multiple versions of browser in your Selenium Grid.
539-
unsafeSsl: 'true' # Optional
557+
unsafeSsl: '{{ include "seleniumGrid.graphqlURL.unsafeSsl" . }}' # Optional
540558

541559
# It is used to add a sidecars proxy in the same pod of the browser node.
542560
# It means it will add a new container to the deployment itself.
@@ -668,6 +686,8 @@ firefoxNode:
668686
hpa:
669687
url: '{{ include "seleniumGrid.graphqlURL" . }}'
670688
browserName: firefox
689+
sessionBrowserName: 'firefox'
690+
unsafeSsl: '{{ include "seleniumGrid.graphqlURL.unsafeSsl" . }}' # Optional
671691

672692
# It is used to add a sidecars proxy in the same pod of the browser node.
673693
# It means it will add a new container to the deployment itself.
@@ -798,6 +818,7 @@ edgeNode:
798818
url: '{{ include "seleniumGrid.graphqlURL" . }}'
799819
browserName: MicrosoftEdge
800820
sessionBrowserName: 'msedge'
821+
unsafeSsl: '{{ include "seleniumGrid.graphqlURL.unsafeSsl" . }}' # Optional
801822

802823
# It is used to add a sidecars proxy in the same pod of the browser node.
803824
# It means it will add a new container to the deployment itself.
@@ -918,3 +939,17 @@ videoRecorder:
918939

919940
# Custom labels for k8s resources
920941
customLabels: {}
942+
943+
# Configuration for dependency chart keda
944+
keda:
945+
http:
946+
timeout: 60000
947+
webhooks:
948+
enabled: false
949+
950+
# Configuration for dependency chart ingress-nginx
951+
ingress-nginx:
952+
enabled: false
953+
controller:
954+
admissionWebhooks:
955+
enabled: false

tests/charts/ci/ParallelAutoscaling-values.yaml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,3 @@ ingress:
3131
name: '{{ template "seleniumGrid.hub.fullname" $ }}'
3232
port:
3333
number: 4444
34-
- path: /(/?)(session/.*/se/vnc)
35-
pathType: ImplementationSpecific
36-
backend:
37-
service:
38-
name: '{{ template "seleniumGrid.hub.fullname" $ }}'
39-
port:
40-
number: 4444
Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
global:
2+
K8S_PUBLIC_IP: localhost
3+
14
ingress:
25
annotations:
6+
kubernetes.io/ingress.class: nginx
37
nginx.ingress.kubernetes.io/use-regex: "true"
48
nginx.ingress.kubernetes.io/rewrite-target: /$2
59
nginx.ingress.kubernetes.io/app-root: &gridAppRoot "/selenium"
610
nginx.ingress.kubernetes.io/proxy-connect-timeout: "360"
711
nginx.ingress.kubernetes.io/proxy-read-timeout: "360"
812
nginx.ingress.kubernetes.io/proxy-send-timeout: "360"
13+
ingressClassName: nginx
914
hostname: ""
1015
paths:
1116
- path: /selenium(/|$)(.*)
@@ -15,20 +20,22 @@ ingress:
1520
name: '{{ template "seleniumGrid.router.fullname" $ }}'
1621
port:
1722
number: 4444
18-
- path: /(/?)(session/.*/se/vnc)
19-
pathType: ImplementationSpecific
20-
backend:
21-
service:
22-
name: '{{ template "seleniumGrid.router.fullname" $ }}'
23-
port:
24-
number: 4444
2523

2624
basicAuth:
2725
enabled: false
26+
2827
isolateComponents: true
2928

3029
hub:
3130
subPath: *gridAppRoot
3231

3332
components:
3433
subPath: *gridAppRoot
34+
35+
ingress-nginx:
36+
enabled: true
37+
controller:
38+
hostNetwork: true
39+
kind: DaemonSet
40+
service:
41+
type: ClusterIP

0 commit comments

Comments
 (0)