Skip to content

Commit

Permalink
Feature/add helm chart (#800)
Browse files Browse the repository at this point in the history
* Initialized `helm create` (version.BuildInfo{Version:"v3.7.2", GitCommit:"663a896f4a815053445eec4153677ddc24a0a361", GitTreeState:"clean", GoVersion:"go1.17.3"})

* Pointing probes to use the default nuts port and the `/status` endpoint

* Modified the chart to point to the latest nuts image and setting the default internal port

* Added the nuts config file as a mounted volume, so the config file is present inside the containers

* Moved the original NUTS config to `values.yaml` and injecting it onto the nuts-configmap.

* Added a PersistedVolume to persist the NUTS data in a mounted volume.

* Embedding the certificates as a Secret into Kubhernetes. Also mounting the keys onto the filesystem. Enabling ssl to verify test the functionality. Also clarified the config path for the nuts data PV and made the nuts config file read-only.

* Exposing post 5555 as a containerPort for gRPC traffic

* Adding the base version of the chart README.md

* Adding a link to the NUTS "Configuring for Production" documentation.

* Adding installation information to the README.

* Attempting to link to a specific header in the main README, doesn't work in local IDE but hoping it does in GitHub

* Setting NUTS-specific values in the Chart.yaml. There are no NUTS versions yet, once this is present this will need to be set, and we can publish the releases to the NUTS Helm repo once added.

* Removing unwanted character

* Moved files from `./chart` to `./charts` to align with https://github.com/marketplace/actions/helm-chart-releaser defaults.

* Building the `master` branch by default as `latest` is quite old

* Attempting to build a Helm Chart on push / tag creation

* Moving the chart data into the advised format of `./charts/<chart-name>/*`

* Update Chart.yaml

Upping the chart version. Testing if the CI pushes the new release

* Removing the `CR_TOKEN` env as the repo is publicly available. Upping version to create a new helm chart

* The `CR_TOKEN` env seems to be required by the plugin. Adding it back.

* Changed the README Chart repo URLs with the expected endpoints when the PR is done.

* Keeping the PV and PVC on the `helm uninstall` command as it can contain crucial data.

* Attempting to skip helm package upload if tag exists

* Update Chart.yaml

Mimicking an appVersion update

* Update Chart.yaml

Mimicking another appVersion update, the previous version was pushed to the helm repo index.yaml already with the testing of a "tag" publish

* Update Chart.yaml

testing new chart push

* Testing if the `gh-pages` branch for the push of new helm charts can be changed

* Setting the "default" value in the `chart-releaser-action` config to clarify where it's pushed to

* Chaging the ci to only trigger on pushes to the master branch. Removed the tags as this is already processed by a push to the master branch.

* Only building on created version tags. Not "skipping" existing Helm charts as this'd be unexpected.

* Adding the default property for the https://github.com/helm/chart-releaser-action#inputs action as we might want to change this in the future

* Update Chart.yaml

upping the version to test a CI build from a tag

* Update Chart.yaml

Mimicking release v1.16.5

* CI doesn't seem to find changes in chart, testing if the problem lies in adding the config property or with releasing via tags

* Defaulting `enabletls: false` to align with nuts project defaults. Also upping the appVersion to see if this affects how chart version differences are calculated.

* Reverting the chart push trigger to changes in the build. Apparently there are issues with building from tags (helm/chart-releaser-action#96). Adding this feature branch for testing purposes. Also added back the `CR_CHARTS_DIR` prop as it was unrelated to the bug in the CI action.

Reverting the chart push trigger to changes in the build. Apparently there are issues with building from tags (helm/chart-releaser-action#96). Adding this feature branch for testing purposes.

* Update Chart.yaml

Upping version to test chart release via branch change instead of tag

* Changing the version numbers to 0.0.1 so people know it's not a production-ready package.

* Removing the feature branch as a CI action trigger

* Extracting nuts-node and gRPC ports from the config file. Added information on these properties being "special" in the context of k8s.

* Chaging default service http port to 1323 and changed the service to a multi-port service for gRPC

Co-authored-by: Joris Scharp <[email protected]>
  • Loading branch information
JorisHeadease and JorisHeadease authored Feb 21, 2022
1 parent 03afa1f commit 7b07124
Show file tree
Hide file tree
Showing 16 changed files with 656 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/helm-chart-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Release Charts

on:
push:
branches:
- 'master'

jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "[email protected]"
- name: Install Helm
uses: azure/setup-helm@v1
with:
version: v3.8.0

- name: Run chart-releaser
uses: helm/[email protected]
env:
CR_CHARTS_DIR: charts
CR_PAGES_BRANCH: gh-pages
CR_SKIP_EXISTING: true
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
23 changes: 23 additions & 0 deletions charts/nuts-node/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
24 changes: 24 additions & 0 deletions charts/nuts-node/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: nuts-node-chart
description: A NUTS node Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.0.1

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.0.1"
79 changes: 79 additions & 0 deletions charts/nuts-node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Helm Chart for NUTS
This chart allows the ease of running NUTS on a Kubernetes cluster.
All the NUTS node information is persisted on [Persisted Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/).

## Configure your NUTS node
All the configurable properties can be found at [./values.yaml](./values.yaml).

When configuring the NUTS node for production purposes, please consult [this](https://nuts-node.readthedocs.io/en/latest/pages/production-configuration.html)
NUTS guide.

The configuration contains default Helm properties. In addition to these values,
there are `nuts` config properties. This contains 3 sections:

| Section | Description |
|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `nuts.config` | Represents the `nuts.yaml` file. All configurable properties can be found in the main [README](../../README.rst#server-options). The properties are loaded into a `ConfigMap` and mounted as `/opt/nuts/nuts.yaml` inside the Pod(s). |
| `nuts.data` | Contains configurable properties for the `PersistedVolume` that will be created. This will be used to write all NUTS data to. |
| `nuts.ssl` | Can be used to load the ssl `certfile`, `certkeyfile` and `truststorefile` as a `Secret` and mount them as files at `/opt/nuts/ssl` inside the Pod(s) |

### Special properties
NUTS allows binding to specific interfaces on the host machines. In the case of Kubernetes, this is already taken care
of. However, we do need to expose the `http` and `gRPC` ports. This is extracted from the following properties:

| Property | Value (default) |
|-----------------------------------------------------------------|-----------------|
| `http.default.address` (must align with `service.internalPort`) | :1323 |
| `network.grpcaddr` | :5555 |

For the `nuts-node` port, the `service.internalPort` can simply be used. For gRPC, the Helm chart filters out all digits
after the last `:` character. If not set, defaults will be used.

### Overriding values
#### From Source
The properties can be manually changed in the [./values.yaml](./values.yaml), or they can be overwritten whilst running
`helm install` via the `--set x=y` parameter.

#### From the NUTS Helm Repo

The default values can be viewed with the following command:
```shell
helm show values nuts-repo/nuts-node-chart
```

You can then override any of these settings in a YAML formatted file, and then pass that file during [installation](#from-the-nuts-helm-repo-1).

## Installing NUTS
### From Source

Execute the following command from the root of the chart folder. Replace `<NAME>` with the name you
wish to give this Helm installation.
```
helm install <NAME> .
```
### From the NUTS Helm Repo

Add the NUTS helm Repo with the following command:
```shell
helm repo add nuts-repo https://nuts-foundation.github.io/nuts-node/
```
This should list available releases with the following command:
```shell
helm search repo nuts-repo
```

After this, the desired version can be installed with the following command:
```shell
helm repo update # Make sure we get the latest list of charts
helm install -f values.yaml <NAME> nuts-repo/nuts-node-chart
```

Note that the `values.yaml` in the above command is the result from the [configuration step](#from-the-nuts-helm-repo).

## Uninstalling NUTS
As the `PersistedVolume` can contain crucial data (like the private keys), by default, the uninstall command will not remove it and its
`PersistedVolumeClaim`. If you're sure it can be deleted, this can be done with the following command:
```shell
kubectl delete pvc nuts-data-pvc
kubectl delete pv nuts-data-pv
```
22 changes: 22 additions & 0 deletions charts/nuts-node/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "chart.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "chart.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "chart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "chart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:{{ .Values.service.internalPort }}/status to view the node status"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME {{ .Values.service.internalPort }}:$CONTAINER_PORT
{{- end }}
73 changes: 73 additions & 0 deletions charts/nuts-node/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "chart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "chart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "chart.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "chart.labels" -}}
helm.sh/chart: {{ include "chart.chart" . }}
{{ include "chart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "chart.selectorLabels" -}}
app.kubernetes.io/name: {{ include "chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "chart.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "chart.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

{{/*
NUTS Port helpers
*/}}
{{- define "grpcPort" -}}
{{- if .Values.nuts.config.network.grpcaddr }}
{{- regexReplaceAll ".*:([0-9]+)" .Values.nuts.config.network.grpcaddr "${1}" }}
{{- else }}
{{- default 5555}}
{{- end }}
{{- end }}
87 changes: 87 additions & 0 deletions charts/nuts-node/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "chart.fullname" . }}
labels:
{{- include "chart.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "chart.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "chart.selectorLabels" . | nindent 8 }}
spec:
volumes:
- name: nuts-config
configMap:
name: nuts-config
- name: nuts-ssl-secret
secret:
secretName: nuts-ssl-secret
- name: nuts-data-pv
persistentVolumeClaim:
claimName: nuts-data-pvc
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "chart.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: NUTS_CONFIGFILE
value: "/opt/nuts/nuts.yaml"
volumeMounts:
- name: nuts-config
mountPath: /opt/nuts/nuts.yaml
subPath: nuts.yaml
readOnly: true
- name: nuts-ssl-secret
mountPath: /opt/nuts/ssl
readOnly: true
- name: nuts-data-pv
mountPath: /opt/nuts/data
ports:
- name: http
containerPort: {{ .Values.service.internalPort | default 1323 }}
protocol: TCP
- name: grpc
containerPort: {{ template "grpcPort" . }}
protocol: TCP
livenessProbe:
httpGet:
path: /status
port: http
readinessProbe:
httpGet:
path: /status
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
28 changes: 28 additions & 0 deletions charts/nuts-node/templates/hpa.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "chart.fullname" . }}
labels:
{{- include "chart.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "chart.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}
Loading

0 comments on commit 7b07124

Please sign in to comment.