Skip to content

Commit 4d65c1e

Browse files
authored
k8s: add helm chart to deploy OBA server and database
* k8s: add helm chart to deploy OBA server and database
1 parent b69af93 commit 4d65c1e

File tree

17 files changed

+505
-1
lines changed

17 files changed

+505
-1
lines changed

.github/workflows/lint-test.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Lint and Test Charts
2+
3+
on: pull_request
4+
5+
jobs:
6+
lint-test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- name: Checkout
10+
uses: actions/checkout@v2
11+
with:
12+
fetch-depth: 0
13+
14+
- name: Install Helm
15+
uses: azure/[email protected]
16+
17+
- uses: actions/setup-python@v5
18+
with:
19+
python-version: 3.7
20+
21+
- name: Install chart-testing
22+
uses: helm/[email protected]
23+
24+
- name: Run chart-testing (list-changed)
25+
id: list-changed
26+
run: |
27+
changed=$(ct list-changed --target-branch main)
28+
if [[ -n "$changed" ]]; then
29+
echo "changed=true" >> $GITHUB_OUTPUT
30+
fi
31+
32+
- name: Run chart-testing (lint)
33+
run: ct lint --validate-maintainers=false --target-branch main
34+
35+
- name: Create kind cluster
36+
uses: helm/[email protected]
37+
if: steps.list-changed.outputs.changed == 'true'
38+
39+
- name: Run chart-testing (install)
40+
run: ct install --target-branch main

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ The following icons are used to represent the status of support for each platfor
2020
- 🔲: not started
2121

2222
1. Completed by Aaron, you can find Render deployment file here: [onebusaway-docker](https://github.com/OneBusAway/onebusaway-docker), has been integrated into this repo.
23-
2. Completed by Neo2308, you can find `oba.yaml` here: [onebusaway-docker](https://github.com/OneBusAway/onebusaway-docker), will be rewrite in [Kustomize](https://github.com/kubernetes-sigs/kustomize).
23+
2. Completed by Neo2308, you can find `oba.yaml` here: [onebusaway-docker](https://github.com/OneBusAway/onebusaway-docker), has been rewritten in [Helm Charts](https://helm.sh/docs/topics/charts/).
2424
3. DigitalOcean app engine's gVisor is conflicting with supervisor, they already know this issue and will fix it in the future.

charts/onebusaway/.helmignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/

charts/onebusaway/Chart.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apiVersion: v2
2+
name: onebusaway
3+
description: A Helm chart for OneBusAway
4+
5+
# A chart can be either an 'application' or a 'library' chart.
6+
#
7+
# Application charts are a collection of templates that can be packaged into versioned archives
8+
# to be deployed.
9+
#
10+
# Library charts provide useful utilities or functions for the chart developer. They're included as
11+
# a dependency of application charts to inject those utilities and functions into the rendering
12+
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
13+
type: application
14+
15+
# This is the chart version. This version number should be incremented each time you make changes
16+
# to the chart and its templates, including the app version.
17+
# Versions are expected to follow Semantic Versioning (https://semver.org/)
18+
version: 0.1.0
19+
20+
# This is the version number of the application being deployed. This version number should be
21+
# incremented each time you make changes to the application. Versions are not expected to
22+
# follow Semantic Versioning. They should reflect the version the application is using.
23+
# It is recommended to use it with quotes.
24+
appVersion: "1.16.0"

charts/onebusaway/readme.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Kubernetes deployment guide
2+
3+
1. Install Kubernetes components
4+
5+
* Install Kubectl by following the instructions [here](https://kubernetes.io/docs/tasks/tools/). </br>
6+
* Install Helm by following the instructions [here](https://helm.sh/docs/intro/install/).</br>
7+
You should have the following output on your terminal:
8+
```bash
9+
$ kubectl version --client
10+
Client Version: v1.29.1
11+
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
12+
13+
$ helm version
14+
version.BuildInfo{Version:"v3.14.3", GitCommit:"f03cc04caaa8f6d7c3e67cf918929150cf6f3f12", GitTreeState:"clean", GoVersion:"go1.21.7"}
15+
```
16+
(Optional) Install k8s [lens](https://k8slens.dev/) to manage your kubernetes cluster.
17+
18+
2. Install Ingress Nginx
19+
20+
RUN the following command to install Ingress Nginx:
21+
```bash
22+
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
23+
24+
helm repo update
25+
26+
helm install nginx-ingress ingress-nginx/ingress-nginx
27+
```
28+
29+
3. Configure your domain
30+
31+
You should add a DNS record to your domain to point to the IP address of the Ingress Nginx controller. You can find the IP address by running:
32+
```bash
33+
kubectl get svc -n ingress-nginx
34+
```
35+
36+
4. Configure the application
37+
38+
Modify the `charts/values.yaml` file to configure the application. You can find the parameters meaning in [onebusaway-docker](https://github.com/OneBusAway/onebusaway-docker/#deployment-parameters).
39+
40+
5. Deploy the application
41+
42+
You can use this command to deploy the application:
43+
```bash
44+
helm install onebusaway charts/
45+
```
46+
Then you can check the status of the deployment by running:
47+
```bash
48+
kubectl get pods -n oba
49+
```

charts/onebusaway/templates/NOTES.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
1. Get the application URL by running these commands:
2+
{{- if .Values.ingress.enabled }}
3+
{{- $host := .Values.ingress.host }}
4+
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host }}
5+
{{- else if contains "NodePort" .Values.service.type }}
6+
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "charts.fullname" . }})
7+
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
8+
echo http://$NODE_IP:$NODE_PORT
9+
{{- else if contains "LoadBalancer" .Values.service.type }}
10+
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
11+
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "charts.fullname" . }}'
12+
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "charts.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
13+
echo http://$SERVICE_IP:{{ .Values.service.port }}
14+
{{- else if contains "ClusterIP" .Values.service.type }}
15+
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "charts.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
16+
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
17+
echo "Visit http://127.0.0.1:8080 to use your application"
18+
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
19+
{{- end }}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "charts.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
8+
{{/*
9+
Create a default fully qualified app name.
10+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
11+
If release name contains chart name it will be used as a full name.
12+
*/}}
13+
{{- define "charts.fullname" -}}
14+
{{- if .Values.fullnameOverride }}
15+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
16+
{{- else }}
17+
{{- $name := default .Chart.Name .Values.nameOverride }}
18+
{{- if contains $name .Release.Name }}
19+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
20+
{{- else }}
21+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
22+
{{- end }}
23+
{{- end }}
24+
{{- end }}
25+
26+
{{/*
27+
Create chart name and version as used by the chart label.
28+
*/}}
29+
{{- define "charts.chart" -}}
30+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
31+
{{- end }}
32+
33+
{{/*
34+
Common labels
35+
*/}}
36+
{{- define "charts.labels" -}}
37+
helm.sh/chart: {{ include "charts.chart" . }}
38+
{{ include "charts.selectorLabels" . }}
39+
{{- if .Chart.AppVersion }}
40+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
41+
{{- end }}
42+
app.kubernetes.io/managed-by: {{ .Release.Service }}
43+
{{- end }}
44+
45+
{{/*
46+
Selector labels
47+
*/}}
48+
{{- define "charts.selectorLabels" -}}
49+
app.kubernetes.io/name: {{ include "charts.name" . }}
50+
app.kubernetes.io/instance: {{ .Release.Name }}
51+
{{- end }}
52+
53+
{{/*
54+
Create the name of the service account to use
55+
*/}}
56+
{{- define "charts.serviceAccountName" -}}
57+
{{- if .Values.serviceAccount.create }}
58+
{{- default (include "charts.fullname" .) .Values.serviceAccount.name }}
59+
{{- else }}
60+
{{- default "default" .Values.serviceAccount.name }}
61+
{{- end }}
62+
{{- end }}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: oba-configs
5+
namespace: {{ .Values.namespace }}
6+
data:
7+
GTFS_URL: "{{ .Values.config.GTFS_URL}}"
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
apiVersion: apps/v1
2+
kind: StatefulSet
3+
metadata:
4+
name: oba-database
5+
namespace: {{ .Values.namespace }}
6+
spec:
7+
serviceName: "oba-database"
8+
replicas: {{ .Values.replicas.database }}
9+
selector:
10+
matchLabels:
11+
app: oba-database
12+
template:
13+
metadata:
14+
labels:
15+
app: oba-database
16+
spec:
17+
containers:
18+
- name: oba-database
19+
image: {{ .Values.image.mysql.repository }}:{{ .Values.image.mysql.tag }}
20+
env:
21+
- name: MYSQL_ROOT_PASSWORD
22+
valueFrom:
23+
secretKeyRef:
24+
name: oba-secrets
25+
key: MYSQL_ROOT_PASSWORD
26+
- name: MYSQL_DATABASE
27+
value: oba_database
28+
- name: MYSQL_USER
29+
value: oba_user
30+
- name: MYSQL_PASSWORD
31+
valueFrom:
32+
secretKeyRef:
33+
name: oba-secrets
34+
key: MYSQL_PASSWORD
35+
ports:
36+
- containerPort: 3306
37+
volumeMounts:
38+
- name: mysql-data
39+
mountPath: /var/lib/mysql
40+
livenessProbe:
41+
exec:
42+
command:
43+
- mysqladmin
44+
- ping
45+
- "-h"
46+
- "127.0.0.1"
47+
initialDelaySeconds: 30
48+
periodSeconds: 10
49+
readinessProbe:
50+
exec:
51+
command:
52+
- mysqladmin
53+
- ping
54+
- "-h"
55+
- "127.0.0.1"
56+
initialDelaySeconds: 30
57+
periodSeconds: 10
58+
volumeClaimTemplates:
59+
- metadata:
60+
name: mysql-data
61+
spec:
62+
accessModes: [ "ReadWriteOnce" ]
63+
resources:
64+
requests:
65+
storage: 1Gi
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
apiVersion: apps/v1
3+
kind: Deployment
4+
metadata:
5+
name: oba-app-deployment
6+
namespace: {{ .Values.namespace }}
7+
spec:
8+
replicas: {{ .Values.replicas.app }}
9+
selector:
10+
matchLabels:
11+
app: oba-app
12+
template:
13+
metadata:
14+
labels:
15+
app: oba-app
16+
spec:
17+
initContainers:
18+
- name: oba-bundler
19+
image: {{ .Values.image.oba.bundler.repository }}:{{ .Values.image.oba.bundler.tag }}
20+
env:
21+
- name: GTFS_URL
22+
valueFrom:
23+
configMapKeyRef:
24+
name: oba-configs
25+
key: GTFS_URL
26+
volumeMounts:
27+
- mountPath: /bundle
28+
name: bundle-volume
29+
containers:
30+
- name: oba-app
31+
image: {{ .Values.image.oba.app.repository }}:{{ .Values.image.oba.app.tag }}
32+
env:
33+
- name: JDBC_URL
34+
value: jdbc:mysql://oba-database.{{ .Values.namespace }}.svc.cluster.local:3306/oba_database
35+
- name: JDBC_USER
36+
value: oba_user
37+
- name: JDBC_PASSWORD
38+
valueFrom:
39+
secretKeyRef:
40+
name: oba-secrets
41+
key: JDBC_PASSWORD
42+
- name: GTFS_URL
43+
value: {{ .Values.env.GTFS_URL }}
44+
- name: TEST_API_KEY
45+
value: {{ .Values.env.TEST_API_KEY }}
46+
- name: VEHICLE_POSITIONS_URL
47+
value: {{ .Values.env.VEHICLE_POSITIONS_URL }}
48+
- name: TRIP_UPDATES_URL
49+
value: {{ .Values.env.TRIP_UPDATES_URL }}
50+
- name: ALERTS_URL
51+
value: {{ .Values.env.ALERTS_URL }}
52+
- name: REFRESH_INTERVAL
53+
value: "{{ .Values.env.REFRESH_INTERVAL }}"
54+
- name: AGENCY_ID
55+
value: {{ .Values.env.AGENCY_ID }}
56+
- name: TZ
57+
value: {{ .Values.env.TZ }}
58+
- name: GOOGLE_MAPS_API_KEY
59+
valueFrom:
60+
secretKeyRef:
61+
name: oba-secrets
62+
key: GOOGLE_MAPS_API_KEY
63+
- name: GOOGLE_MAPS_CHANNEL_ID
64+
value: {{ .Values.env.GOOGLE_MAPS_CHANNEL_ID }}
65+
- name: GOOGLE_MAPS_CLIENT_ID
66+
value: {{ .Values.env.GOOGLE_MAPS_CLIENT_ID }}
67+
ports:
68+
- containerPort: 8080
69+
volumeMounts:
70+
- mountPath: /bundle
71+
name: bundle-volume
72+
livenessProbe:
73+
httpGet:
74+
path: /onebusaway-api-webapp/api/where/current-time.json?key=org.onebusaway.iphone
75+
port: 8080
76+
initialDelaySeconds: 30
77+
periodSeconds: 10
78+
failureThreshold: 3
79+
readinessProbe:
80+
httpGet:
81+
path: /onebusaway-api-webapp/api/where/current-time.json?key=org.onebusaway.iphone
82+
port: 8080
83+
initialDelaySeconds: 30
84+
periodSeconds: 10
85+
failureThreshold: 3
86+
volumes:
87+
- name: bundle-volume
88+
emptyDir: {}

0 commit comments

Comments
 (0)