Skip to content

Commit

Permalink
ci: add helm deployment manifest (#181)
Browse files Browse the repository at this point in the history
  • Loading branch information
gwenall committed Feb 17, 2023
1 parent 5af0c3a commit a3c5232
Show file tree
Hide file tree
Showing 9 changed files with 411 additions and 0 deletions.
11 changes: 11 additions & 0 deletions deploy/helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v2
name: ruthenium-service
# pipelines override this chart version and appVersion with the container tag
version: 0.0.0

description: Ruthenium Service
icon: https://repository-images.githubusercontent.com/536569894/47d35fd4-bce0-48b8-91bb-30fb08c6583e
maintainers:
- name: Gwenall Pansier
email: gwenall.pansier@my-cloud.me

87 changes: 87 additions & 0 deletions deploy/helm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Ruthenium [helm](https://helm.sh/docs/intro/using_helm/) chart

Helm chart to deploy [Ruthenium](https://github.com/my-cloud/ruthenium) cryptocurrency node




## Prerequisites

* Kubernetes: `>= 1.24.0-0`
* Helm: `>= 3.0`

## Getting Started

For a quick install with the default configuration:

```bash
$ helm install ruthenium --set secrets[0].data.privateKey=<MyPrivateKey>
```

## Source Code

* [Ruthenium](https://github.com/my-cloud/ruthenium)

## Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| app.containers[0].annotations | map | {} | any relevant annotation |
| app.containers[0].args | list | [] | any application argument |
| app.containers[0].autoReload | string | "true" | specifies if the container should be restarted on each update |
| app.containers[0].command[0] | string | "/app/node" | application binary path |
| app.containers[0].env | map | {} | any environment variable `ENV_NAME: value` |
| app.containers[0].health.liveness.initialDelaySeconds | int | 40 | kubernetes liveness initialDelaySeconds |
| app.containers[0].health.liveness.periodSeconds | int | 5 | kubernetes liveness periodSeconds |
| app.containers[0].health.readiness.initialDelaySeconds | int | 30 | kubernetes readiness initialDelaySeconds |
| app.containers[0].health.readiness.periodSeconds | int | 1 | kubernetes readiness periodSeconds |
| app.containers[0].health.type | string | "grpc" | kubernetes healthcheck type |
| app.containers[0].image.name | string | "ghcr.io/my-cloud/ruthenium" | container image |
| app.containers[0].image.pullPolicy | string | "IfNotPresent" | container pull policy |
| app.containers[0].image.tagOverride | string | "latest" | container tag |
| app.containers[0].name | string | "node" | container name |
| app.containers[0].resources.limits.memory | string | "512Mi" | kubernetes resources limits memory |
| app.containers[0].resources.requests.memory | string | "128Mi" | kubernetes resources requests memory |
| app.containers[0].secret.ruthenium.PRIVATE_KEY | string | "privateKey" | Gets the `privateKey` key of the `ruthenium` secret and populate a container environment variable `PRIVATE_KEY` with the secret value |
| app.containers[0].service[0].port | string | "8106" | kubernetes service port |
| app.containers[0].service[0].protocol | string | "TCP" | kubernetes service protocol |
| app.containers[0].service[0].targetPort | string | "8106" | kubernetes service container listening port |
| app.containers[0].storage.data | string | "/tmp" | will mount the `data` volume in the specified path |
| app.containers[1].annotations | map | {} | any relevant annotation |
| app.containers[1].autoReload | string | "true" | specifies if the container should be restarted on each update |
| app.containers[1].command[0] | string | "/app/ui" | any application argument |
| app.containers[1].env | map | {} | any environment variable ENV_NAME: value |
| app.containers[1].env.HOST_IP | string | "127.0.0.1" | specifies the `HOST_IP` environment variable with the node IP address |
| app.containers[1].health.liveness.initialDelaySeconds | int | 120 | kubernetes liveness initialDelaySeconds |
| app.containers[1].health.liveness.path | string | "/health/liveness" | kubernetes liveness path |
| app.containers[1].health.liveness.periodSeconds | int | 5 | kubernetes readiness periodSeconds |
| app.containers[1].health.readiness.initialDelaySeconds | int | 30 | kubernetes readiness initialDelaySeconds |
| app.containers[1].health.readiness.path | string | "/health/readiness" | kubernetes readiness path |
| app.containers[1].health.readiness.periodSeconds | int | 1 | kubernetes readiness periodSeconds |
| app.containers[1].health.type | string | "httpGet" | kubernetes healthcheck type |
| app.containers[1].image.name | string | "ghcr.io/my-cloud/ruthenium" | container image |
| app.containers[1].image.pullPolicy | string | "IfNotPresent" | container pull policy |
| app.containers[1].image.tagOverride | string | "latest" | container tag override |
| app.containers[1].name | string | "ui" | container name |
| app.containers[1].resources.limits.memory | string | "512Mi" | kubernetes resources limits memory |
| app.containers[1].resources.requests.memory | string | "128Mi" | kubernetes resources requests memory |
| app.containers[1].secret.ruthenium.PRIVATE_KEY | string | "privateKey" | Gets the privateKey key of the ruthenium secret and populate a container environment variable PRIVATE_KEY with the secret value |
| app.containers[1].service[0].port | string | "80" | service port |
| app.containers[1].service[0].protocol | string | "TCP" | service protocol |
| app.containers[1].service[0].targetPort | string | "8080" | kubernetes service container listening port |
| app.containers[1].storage.data | string | "/data" | will mount the `data` volume in the specified path |
| app.replicas | int | 1 | Number of replicas. it is useless to set over `1` due to Ruthenium fundamental mechanism |
| app.storage.data.accessModes[0] | string | "ReadWriteMany" | storage access mode |
| app.storage.data.size | string | "128M" | storage size |
| app.storage.data.storageClass | string | "kube-data" | storage class |
| app.type | string | "statefulset" | kubernetes kind (only `statefulset` is available for now) |
| app.volumes[0].emptyDir | map | {} | volume type |
| app.volumes[0].name | string | "shared-data" | volume name |
| global.autoReload | string | "true" | auto reload set globally (useful in meta deployments) |
| global.image.pullPolicy | string | "Always" | image pull policies set globally (useful in meta deployments) |
| global.registries | list | [] | list of registries (useful with private registries) |
| secrets[0].annotations | map | {} | secret annotation |
| secrets[0].data.privateKey | string | null | secret private key |
| secrets[0].name | string | "ruthenium" | secret name |
| url.domains[0] | string | "ruthenium.example.com" | domain name on which ruthenium would be available |

Empty file added deploy/helm/charts/.empty
Empty file.
40 changes: 40 additions & 0 deletions deploy/helm/templates/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{{ if not ( eq .Values.app.type "job" ) }}
---
{{- $chartName := .Chart.Name -}}
{{- $app := .Values.app -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $chartName }}
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0
nginx.org/location-snippets: |
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
spec:
rules:
{{- range .Values.url.domains }}
{{- $domain := . }}
{{- range $containerName, $container := $app.containers }}
{{- range $container.service }}
{{- if gt ( len $container | int) 1 }}
- host: {{ $container.name }}.{{ $domain }}
{{- else }}
- host: {{ $domain }}
{{- end }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ $chartName }}
port:
number: {{ .port }}
{{- end }}
{{- end }}
{{- end }}

{{ end }}
23 changes: 23 additions & 0 deletions deploy/helm/templates/secrets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{{- $values := .Values -}}
{{- range $secret := .Values.secrets -}}
apiVersion: v1
kind: Secret

metadata:
name: {{ $secret.name }}
annotations:
{{- range $k, $v := $secret.annotations }}
{{ $k }}: {{ $v |quote}}
{{- end }}
{{- if hasKey $secret "data" }}
data:
{{- range $k, $v := $secret.data }}
{{ $k }}: {{ $v }}
{{- end }}
{{- end }}
{{- if hasKey $secret "stringData" }}
stringData:
{{- toYaml $secret.stringData | nindent 2 }}
{{- end }}
type: {{ $secret.type |default "Opaque" | quote}}
{{- end -}}
9 changes: 9 additions & 0 deletions deploy/helm/templates/service-account.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
{{- $chartName := .Chart.Name -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ $chartName }}
labels:
app: {{ $chartName }}
group: {{ $chartName }}
24 changes: 24 additions & 0 deletions deploy/helm/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{{- if not ( eq .Values.app.type "job" ) }}
---
kind: Service
apiVersion: v1
metadata:
name: {{ .Chart.Name }}
labels:
app: {{ .Chart.Name }}
group: {{ .Chart.Name }}
spec:
type: LoadBalancer
selector:
app: {{ .Chart.Name }}
group: {{ .Chart.Name }}
ports:
{{- range $containerName, $container := .Values.app.containers }}
{{- range $container.service }}
- name: {{ $container.name }}-{{ .port }}
port: {{ .port }}
protocol: {{ .protocol }}
targetPort: {{ .targetPort }}
{{- end }}
{{- end }}
{{- end }}
121 changes: 121 additions & 0 deletions deploy/helm/templates/statefulset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
{{ if eq .Values.app.type "statefulset" }}
---
{{- $chartName := .Chart.Name -}}
{{- $appVersion := .Values.AppVersion | default .Chart.Version -}}
{{- $global := .Values.global }}

apiVersion: apps/v1
kind: StatefulSet
metadata:
annotations:
reloader.stakater.com/auto: {{ .Values.app.AutoReload | default .Values.global.autoReload | quote }}
role: {{ $chartName }}
{{- if .Values.app.annotations -}}
{{ .Values.app.annotations | nindent 4 -}}
{{- end }}
labels:
group: {{ $chartName }}
app: {{ $chartName }}
version: "{{ $appVersion }}"
name: {{ $chartName }}
spec:
selector:
matchLabels:
app: {{ $chartName }} # has to match .spec.template.metadata.labels
serviceName: {{ $chartName }}
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
replicas: {{ .Values.app.replicas }}
template:
metadata:
annotations:
rollme: {{ randAlphaNum 5 | quote }}
labels:
group: {{ $chartName }}
app: {{ $chartName }}
version: "{{ $appVersion }}"
spec:
serviceAccountName: {{ $chartName }}
imagePullSecrets: {{- range $global.registries }}
- name: {{ .name }}
{{- end }}
containers:
{{- range $container := .Values.app.containers }}
- env: {{- range $key, $value := $container.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- range $secretName, $rawValue := $container.secret }}
{{- range $envName, $secretKey := $rawValue }}
- name: {{ $envName }}
valueFrom:
secretKeyRef:
name: {{ $secretName }}
key: {{ $secretKey }}
{{- end }}
{{- end }}
image: {{ $container.image.name }}:{{ $container.image.tagOverride | default $appVersion }}
imagePullPolicy: {{ $container.image.pullPolicy | default $global.image.pullPolicy }}
name: {{ $chartName }}-{{ $container.name }}
command: {{ $container.command }}
args: {{ $container.args }}
resources:
requests:
memory: {{ $container.resources.requests.memory }}
limits:
memory: {{ $container.resources.limits.memory }}
ports:
{{- range $container.service }}
- name: {{ $container.name }}
containerPort: {{ .targetPort }}
protocol: {{ .protocol }}
{{- end }}
{{- if $container.health }}
{{- range $probe := list "liveness" "readiness" }}
{{$probe}}Probe:
{{- $probePath := (index $container.health $probe) }}
initialDelaySeconds: {{ $probePath.initialDelaySeconds }}
periodSeconds: {{ $probePath.periodSeconds }}
timeoutSeconds: {{ $probePath.timeoutSeconds }}
{{ $container.health.type |default "httpGet" }}:
{{- with (first $container.service) }}
port: {{ .targetPort }}
{{- end }}
{{- if eq $container.health.type "httpGet" }}
path: {{ $probePath.path }}
{{- if $probePath.httpHeaders }}
httpHeaders:
{{- range $headerName, $header := $probePath.httpHeaders }}
- name: {{ $headerName }}
value: {{ $header }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
volumeMounts:
{{- range $storageName, $mountPath := $container.storage }}
- name: {{ $chartName }}-{{ $storageName }}
mountPath: {{ $mountPath }}
{{- end }}
{{- end }}
securityContext:
fsGroup: 1000
restartPolicy: Always
volumeClaimTemplates:
{{- range $storageName, $storage := .Values.app.storage }}
- metadata:
name: {{ $chartName }}-{{$storageName}}
spec:
accessModes:
{{- range $storage.accessModes }}
- {{ . }}
{{- end }}
storageClassName: {{ $storage.storageClass | quote }}
resources:
requests:
storage: {{ $storage.size | quote }}
{{end}}
{{ end }}
Loading

0 comments on commit a3c5232

Please sign in to comment.