Skip to content

Commit 80fb686

Browse files
authored
Merge pull request #381 from YaSuenag/pr/helm
Add Helm chart and workflow
2 parents ff355f3 + ec06dc7 commit 80fb686

File tree

16 files changed

+305
-307
lines changed

16 files changed

+305
-307
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: 5-Publish Helm chart
2+
3+
on:
4+
workflow_dispatch:
5+
6+
concurrency:
7+
group: publish-helm-chart
8+
cancel-in-progress: true
9+
10+
jobs:
11+
push-helm-charts:
12+
if: github.repository == 'Green-Software-Foundation/carbon-aware-sdk' || vars.ENABLE_HELM_WORKFLOW == 'true'
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
packages: write
17+
18+
steps:
19+
- name: Checkout Code
20+
uses: actions/checkout@v3
21+
22+
- name: Detect Helm chart version
23+
run: |
24+
CHART_VERSION=`yq .version helm-chart/Chart.yaml`
25+
echo "CHART_VERSION=$CHART_VERSION" >> "$GITHUB_ENV"
26+
27+
- name: Packaging
28+
run: helm package helm-chart
29+
30+
- name: Log in to the Container registry
31+
uses: docker/[email protected]
32+
with:
33+
registry: ghcr.io
34+
username: ${{ github.actor }}
35+
password: ${{ github.token }}
36+
37+
- name: Push charts to GHCR
38+
run: |
39+
OWNER_LOWER=${GITHUB_REPOSITORY_OWNER,,}
40+
helm push carbon-aware-sdk-${{ env.CHART_VERSION }}.tgz "oci://ghcr.io/$OWNER_LOWER/charts"
41+
shell: bash

docs/overview.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,144 @@ $ curl -s http://localhost:8080/emissions/forecasts/current?location=westus2 | j
219219
220220
For more information on containerization, refer to the markdown in
221221
[containerization.md](./containerization.md).
222+
223+
### Deploy Web API on Kubernetes with Helm
224+
225+
You can deploy Web API as a Kubernetes application via Helm. GSF provides a chart as an OCI container, so you have to use Helm v3.8.0 or later.
226+
227+
Following command creates `carbon-aware-sdk` namespace and deploys Web API into it with specified `values.yaml`.
228+
229+
```bash
230+
$ helm install casdk -n carbon-aware-sdk --create-namespace oci://ghcr.io/green-software-foundation/charts/carbon-aware-sdk --values values.yaml
231+
```
232+
233+
`values.yaml` should contain `appsettings.json` which would be used in Web API at least. It should include data source definitions and their credentials. It would be stored as `Secret` resource.
234+
235+
```yaml
236+
appsettings: |-
237+
{
238+
"DataSources": {
239+
"EmissionsDataSource": "WattTime",
240+
"ForecastDataSource": "WattTime",
241+
"Configurations": {
242+
"WattTime": {
243+
"Type": "WattTime",
244+
"Username": "username",
245+
"Password": "password",
246+
"BaseURL": "https://api2.watttime.org/v2/"
247+
}
248+
}
249+
}
250+
}
251+
```
252+
253+
Also you can include following configuration into `values.yaml`.
254+
255+
```yaml
256+
# Number of replicas
257+
replicaCount: 1
258+
259+
image:
260+
repository: ghcr.io/green-software-foundation/carbon-aware-sdk
261+
pullPolicy: IfNotPresent
262+
# You can set specified tag (equivalent with the SDK version in here)
263+
tag: latest
264+
265+
# Set the value if you want to override the name.
266+
nameOverride: ""
267+
fullnameOverride: ""
268+
269+
serviceAccount:
270+
# Specifies whether a service account should be created
271+
create: true
272+
# Annotations to add to the service account
273+
annotations: {}
274+
# The name of the service account to use.
275+
# If not set and create is true, a name is generated using the fullname template
276+
name: ""
277+
278+
podAnnotations: {}
279+
280+
podSecurityContext: {}
281+
# fsGroup: 2000
282+
283+
securityContext: {}
284+
# capabilities:
285+
# drop:
286+
# - ALL
287+
# readOnlyRootFilesystem: true
288+
# runAsNonRoot: true
289+
# runAsUser: 1000
290+
291+
service:
292+
type: ClusterIP
293+
port: 80
294+
295+
ingress:
296+
enabled: false
297+
className: ""
298+
annotations: {}
299+
hosts:
300+
- host: carbon-aware-sdk.local
301+
paths:
302+
- path: /
303+
pathType: ImplementationSpecific
304+
tls: []
305+
# - secretName: carbon-aware-sdk-tls
306+
# hosts:
307+
# - carbon-aware-sdk.local
308+
309+
resources: {}
310+
# limits:
311+
# cpu: 100m
312+
# memory: 128Mi
313+
# requests:
314+
# cpu: 100m
315+
# memory: 128Mi
316+
317+
autoscaling:
318+
enabled: false
319+
minReplicas: 1
320+
maxReplicas: 100
321+
targetCPUUtilizationPercentage: 80
322+
# targetMemoryUtilizationPercentage: 80
323+
324+
nodeSelector: {}
325+
326+
tolerations: []
327+
328+
affinity: {}
329+
330+
# appsettings.json
331+
appsettings: |-
332+
{
333+
"DataSources": {
334+
"EmissionsDataSource": "ElectricityMaps",
335+
"ForecastDataSource": "WattTime",
336+
"Configurations": {
337+
"WattTime": {
338+
"Type": "WattTime",
339+
"Username": "username",
340+
"Password": "password",
341+
"BaseURL": "https://api2.watttime.org/v2/",
342+
"Proxy": {
343+
"useProxy": true,
344+
"url": "http://10.10.10.1",
345+
"username": "proxyUsername",
346+
"password": "proxyPassword"
347+
}
348+
},
349+
"ElectricityMaps": {
350+
"Type": "ElectricityMaps",
351+
"APITokenHeader": "auth-token",
352+
"APIToken": "myAwesomeToken",
353+
"BaseURL": "https://api.electricitymap.org/v3/"
354+
}
355+
}
356+
}
357+
}
358+
```
359+
360+
The video in below is demonstration to install Carbon Aware SDK via Helm. Note that installing the SDK from local directory ( ~/github-forked/carbon-aware-sdk/helm-chart ), not an OCI container.
361+
362+
[!Demonstration to intall Carbon Aware SDK from local with Helm](https://github.com/Green-Software-Foundation/carbon-aware-sdk/assets/7421132/b09d8ab1-642b-442a-882f-abc802153070)
File renamed without changes.

samples/helmexample/Chart.yaml renamed to helm-chart/Chart.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
apiVersion: v2
2-
name: helmexample
3-
description: A Helm chart for Kubernetes
2+
name: carbon-aware-sdk
3+
description: A Helm chart for Carbon Aware SDK
44

55
# A chart can be either an 'application' or a 'library' chart.
66
#
@@ -15,10 +15,10 @@ type: application
1515
# This is the chart version. This version number should be incremented each time you make changes
1616
# to the chart and its templates, including the app version.
1717
# Versions are expected to follow Semantic Versioning (https://semver.org/)
18-
version: 0.1.0
18+
version: 1.0.0
1919

2020
# This is the version number of the application being deployed. This version number should be
2121
# incremented each time you make changes to the application. Versions are not expected to
2222
# follow Semantic Versioning. They should reflect the version the application is using.
2323
# It is recommended to use it with quotes.
24-
appVersion: "1.16.0"
24+
appVersion: "v1.1.0"

samples/helmexample/templates/NOTES.txt renamed to helm-chart/templates/NOTES.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@
66
{{- end }}
77
{{- end }}
88
{{- else if contains "NodePort" .Values.service.type }}
9-
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helmexample.fullname" . }})
9+
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services webapi
1010
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
1111
echo http://$NODE_IP:$NODE_PORT
1212
{{- else if contains "LoadBalancer" .Values.service.type }}
1313
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
14-
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helmexample.fullname" . }}'
15-
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helmexample.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
14+
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w webapi
15+
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "carbon-aware-sdk.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
1616
echo http://$SERVICE_IP:{{ .Values.service.port }}
1717
{{- else if contains "ClusterIP" .Values.service.type }}
18-
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helmexample.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
18+
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "carbon-aware-sdk.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
1919
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
2020
echo "Visit http://127.0.0.1:8080 to use your application"
2121
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT

samples/helmexample/templates/_helpers.tpl renamed to helm-chart/templates/_helpers.tpl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{{/*
22
Expand the name of the chart.
33
*/}}
4-
{{- define "helmexample.name" -}}
4+
{{- define "carbon-aware-sdk.name" -}}
55
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
66
{{- end }}
77

@@ -10,7 +10,7 @@ Create a default fully qualified app name.
1010
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
1111
If release name contains chart name it will be used as a full name.
1212
*/}}
13-
{{- define "helmexample.fullname" -}}
13+
{{- define "carbon-aware-sdk.fullname" -}}
1414
{{- if .Values.fullnameOverride }}
1515
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
1616
{{- else }}
@@ -26,16 +26,16 @@ If release name contains chart name it will be used as a full name.
2626
{{/*
2727
Create chart name and version as used by the chart label.
2828
*/}}
29-
{{- define "helmexample.chart" -}}
29+
{{- define "carbon-aware-sdk.chart" -}}
3030
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
3131
{{- end }}
3232

3333
{{/*
3434
Common labels
3535
*/}}
36-
{{- define "helmexample.labels" -}}
37-
helm.sh/chart: {{ include "helmexample.chart" . }}
38-
{{ include "helmexample.selectorLabels" . }}
36+
{{- define "carbon-aware-sdk.labels" -}}
37+
helm.sh/chart: {{ include "carbon-aware-sdk.chart" . }}
38+
{{ include "carbon-aware-sdk.selectorLabels" . }}
3939
{{- if .Chart.AppVersion }}
4040
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
4141
{{- end }}
@@ -45,17 +45,17 @@ app.kubernetes.io/managed-by: {{ .Release.Service }}
4545
{{/*
4646
Selector labels
4747
*/}}
48-
{{- define "helmexample.selectorLabels" -}}
49-
app.kubernetes.io/name: {{ include "helmexample.name" . }}
48+
{{- define "carbon-aware-sdk.selectorLabels" -}}
49+
app.kubernetes.io/name: {{ include "carbon-aware-sdk.name" . }}
5050
app.kubernetes.io/instance: {{ .Release.Name }}
5151
{{- end }}
5252

5353
{{/*
5454
Create the name of the service account to use
5555
*/}}
56-
{{- define "helmexample.serviceAccountName" -}}
56+
{{- define "carbon-aware-sdk.serviceAccountName" -}}
5757
{{- if .Values.serviceAccount.create }}
58-
{{- default (include "helmexample.fullname" .) .Values.serviceAccount.name }}
58+
{{- default (include "carbon-aware-sdk.fullname" .) .Values.serviceAccount.name }}
5959
{{- else }}
6060
{{- default "default" .Values.serviceAccount.name }}
6161
{{- end }}

samples/helmexample/templates/deployment.yaml renamed to helm-chart/templates/deployment.yaml

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,65 @@
11
apiVersion: apps/v1
22
kind: Deployment
33
metadata:
4-
name: {{ include "helmexample.fullname" . }}
4+
name: webapi
5+
namespace: {{ $.Release.Namespace }}
56
labels:
6-
{{- include "helmexample.labels" . | nindent 4 }}
7+
{{- include "carbon-aware-sdk.labels" . | nindent 4 }}
78
spec:
89
{{- if not .Values.autoscaling.enabled }}
910
replicas: {{ .Values.replicaCount }}
1011
{{- end }}
1112
selector:
1213
matchLabels:
13-
{{- include "helmexample.selectorLabels" . | nindent 6 }}
14+
{{- include "carbon-aware-sdk.selectorLabels" . | nindent 6 }}
1415
template:
1516
metadata:
1617
{{- with .Values.podAnnotations }}
1718
annotations:
1819
{{- toYaml . | nindent 8 }}
1920
{{- end }}
2021
labels:
21-
{{- include "helmexample.selectorLabels" . | nindent 8 }}
22+
{{- include "carbon-aware-sdk.selectorLabels" . | nindent 8 }}
2223
spec:
2324
{{- with .Values.imagePullSecrets }}
2425
imagePullSecrets:
2526
{{- toYaml . | nindent 8 }}
2627
{{- end }}
27-
serviceAccountName: {{ include "helmexample.serviceAccountName" . }}
28+
serviceAccountName: {{ include "carbon-aware-sdk.serviceAccountName" . }}
2829
securityContext:
2930
{{- toYaml .Values.podSecurityContext | nindent 8 }}
31+
enableServiceLinks: false
3032
containers:
3133
- name: {{ .Chart.Name }}
3234
securityContext:
3335
{{- toYaml .Values.securityContext | nindent 12 }}
3436
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
35-
imagePullPolicy: {{ .Values.image.pullPolicy }}
37+
{{- with .Values.image.pullPolicy }}
38+
imagePullPolicy: {{ . }}
39+
{{- end }}
3640
ports:
3741
- name: http
3842
containerPort: 80
3943
protocol: TCP
44+
volumeMounts:
45+
- name: appsettings
46+
mountPath: /app/appsettings.json
47+
subPath: appsettings.json
48+
readOnly: true
4049
livenessProbe:
41-
{{ .Values.monitorConfig.liveness | toYaml | indent 12 | trim }}
50+
httpGet:
51+
path: /health
52+
port: http
4253
readinessProbe:
43-
{{ .Values.monitorConfig.readiness | toYaml | indent 12 | trim }}
54+
httpGet:
55+
path: /health
56+
port: http
4457
resources:
4558
{{- toYaml .Values.resources | nindent 12 }}
59+
volumes:
60+
- name: appsettings
61+
secret:
62+
secretName: appsettings
4663
{{- with .Values.nodeSelector }}
4764
nodeSelector:
4865
{{- toYaml . | nindent 8 }}

samples/helmexample/templates/hpa.yaml renamed to helm-chart/templates/hpa.yaml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
{{- if .Values.autoscaling.enabled }}
2-
apiVersion: autoscaling/v2beta1
2+
apiVersion: autoscaling/v2
33
kind: HorizontalPodAutoscaler
44
metadata:
5-
name: {{ include "helmexample.fullname" . }}
5+
name: webapi
6+
namespace: {{ $.Release.Namespace }}
67
labels:
7-
{{- include "helmexample.labels" . | nindent 4 }}
8+
{{- include "carbon-aware-sdk.labels" . | nindent 4 }}
89
spec:
910
scaleTargetRef:
1011
apiVersion: apps/v1
1112
kind: Deployment
12-
name: {{ include "helmexample.fullname" . }}
13+
name: webapi
1314
minReplicas: {{ .Values.autoscaling.minReplicas }}
1415
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
1516
metrics:

0 commit comments

Comments
 (0)