aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchemicstry <chemicstry@gmail.com>2022-06-20 15:52:43 +0300
committerMaximilien R <maximilien@deuxfleurs.fr>2022-09-30 18:46:57 +0200
commita93dcce84196bb8ffc8cef091d1343597b15b9a6 (patch)
treed14aad0abde74d453f590fe2ac0556a66ee8c6e4
parentb17d59cfabbe92c509f4888cae83f6053a8cab1e (diff)
downloadgarage-a93dcce84196bb8ffc8cef091d1343597b15b9a6.tar.gz
garage-a93dcce84196bb8ffc8cef091d1343597b15b9a6.zip
Add helm chart
-rw-r--r--script/helm/README.md63
-rw-r--r--script/helm/garage/.helmignore23
-rw-r--r--script/helm/garage/Chart.yaml24
-rw-r--r--script/helm/garage/templates/_helpers.tpl62
-rw-r--r--script/helm/garage/templates/configmap.yaml29
-rw-r--r--script/helm/garage/templates/ingress.yaml123
-rw-r--r--script/helm/garage/templates/service.yaml19
-rw-r--r--script/helm/garage/templates/serviceaccount.yaml12
-rw-r--r--script/helm/garage/templates/statefulset.yaml97
-rw-r--r--script/helm/garage/values.yaml124
10 files changed, 576 insertions, 0 deletions
diff --git a/script/helm/README.md b/script/helm/README.md
new file mode 100644
index 00000000..715cbab1
--- /dev/null
+++ b/script/helm/README.md
@@ -0,0 +1,63 @@
+# Garage helm3 chart
+
+This chart deploys garage on a kubernetes cluster.
+
+## Deploying
+
+With default options:
+
+```bash
+helm install --create-namespace --namespace garage garage ./garage
+```
+
+With custom values:
+
+```bash
+helm install --create-namespace --namespace garage garage ./garage -f values.override.yaml
+```
+
+## Overriding default values
+
+All possible configuration values can be found in [values.yaml](garage/values.yaml).
+
+This is an example `values.overrride.yaml` for deploying in a microk8s cluster with a https s3 api ingress route:
+
+```yaml
+# Start 4 instances (StatefulSets) of garage
+replicaCount: 4
+
+# Override default storage class and size
+persistence:
+ meta:
+ storageClass: "openebs-hostpath"
+ size: 100Mi
+ data:
+ storageClass: "openebs-hostpath"
+ size: 1Gi
+
+ingress:
+ s3:
+ api:
+ enabled: true
+ className: "public"
+ annotations:
+ cert-manager.io/cluster-issuer: "letsencrypt-prod"
+ nginx.ingress.kubernetes.io/proxy-body-size: 500m
+ hosts:
+ - host: s3-api.my-domain.com
+ paths:
+ - path: /
+ pathType: Prefix
+ tls:
+ - secretName: garage-ingress-cert
+ hosts:
+ - s3-api.my-domain.com
+```
+
+## Removing
+
+```bash
+helm delete --namespace garage garage
+```
+
+Note that this will leave behind custom CRD `garagenodes.deuxfleurs.fr`, which must be removed manually if desired.
diff --git a/script/helm/garage/.helmignore b/script/helm/garage/.helmignore
new file mode 100644
index 00000000..0e8a0eb3
--- /dev/null
+++ b/script/helm/garage/.helmignore
@@ -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/
diff --git a/script/helm/garage/Chart.yaml b/script/helm/garage/Chart.yaml
new file mode 100644
index 00000000..9455488a
--- /dev/null
+++ b/script/helm/garage/Chart.yaml
@@ -0,0 +1,24 @@
+apiVersion: v2
+name: garage
+description: S3-compatible object store for small self-hosted geo-distributed deployments
+
+# 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.1.0
+
+# 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: "v0.7.2"
diff --git a/script/helm/garage/templates/_helpers.tpl b/script/helm/garage/templates/_helpers.tpl
new file mode 100644
index 00000000..1a651f47
--- /dev/null
+++ b/script/helm/garage/templates/_helpers.tpl
@@ -0,0 +1,62 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "garage.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 "garage.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 "garage.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "garage.labels" -}}
+helm.sh/chart: {{ include "garage.chart" . }}
+{{ include "garage.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "garage.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "garage.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "garage.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "garage.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/script/helm/garage/templates/configmap.yaml b/script/helm/garage/templates/configmap.yaml
new file mode 100644
index 00000000..587746f6
--- /dev/null
+++ b/script/helm/garage/templates/configmap.yaml
@@ -0,0 +1,29 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "garage.fullname" . }}-config
+data:
+ garage.toml: |-
+ metadata_dir = "{{ .Values.garage.metadataDir }}"
+ data_dir = "{{ .Values.garage.dataDir }}"
+
+ replication_mode = "{{ .Values.garage.replicationMode }}"
+
+ rpc_bind_addr = "{{ .Values.garage.rpcBindAddr }}"
+ rpc_secret = "{{ .Values.garage.rpcSecret }}"
+
+ bootstrap_peers = {{ .Values.garage.bootstrapPeers }}
+
+ kubernetes_namespace = "{{ .Release.Namespace }}"
+ kubernetes_service_name = "{{ include "garage.fullname" . }}"
+ kubernetes_skip_crd = {{ .Values.garage.kubernetesSkipCrd }}
+
+ [s3_api]
+ s3_region = "{{ .Values.garage.s3.api.region }}"
+ api_bind_addr = "[::]:3900"
+ root_domain = "{{ .Values.garage.s3.api.rootDomain }}"
+
+ [s3_web]
+ bind_addr = "[::]:3902"
+ root_domain = "{{ .Values.garage.s3.web.rootDomain }}"
+ index = "{{ .Values.garage.s3.web.index }}" \ No newline at end of file
diff --git a/script/helm/garage/templates/ingress.yaml b/script/helm/garage/templates/ingress.yaml
new file mode 100644
index 00000000..c4ee5a3f
--- /dev/null
+++ b/script/helm/garage/templates/ingress.yaml
@@ -0,0 +1,123 @@
+{{- if .Values.ingress.s3.api.enabled -}}
+{{- $fullName := include "garage.fullname" . -}}
+{{- $svcPort := .Values.service.s3.api.port -}}
+{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
+ {{- if not (hasKey .Values.ingress.s3.api.annotations "kubernetes.io/ingress.class") }}
+ {{- $_ := set .Values.ingress.s3.api.annotations "kubernetes.io/ingress.class" .Values.ingress.s3.api.className}}
+ {{- end }}
+{{- end }}
+{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1
+{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+ name: {{ $fullName }}-s3-api
+ labels:
+ {{- include "garage.labels" . | nindent 4 }}
+ {{- with .Values.ingress.s3.api.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- if and .Values.ingress.s3.api.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
+ ingressClassName: {{ .Values.ingress.s3.api.className }}
+ {{- end }}
+ {{- if .Values.ingress.s3.api.tls }}
+ tls:
+ {{- range .Values.ingress.s3.api.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
+ {{- end }}
+ {{- end }}
+ rules:
+ {{- range .Values.ingress.s3.api.hosts }}
+ - host: {{ .host | quote }}
+ http:
+ paths:
+ {{- range .paths }}
+ - path: {{ .path }}
+ {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
+ pathType: {{ .pathType }}
+ {{- end }}
+ backend:
+ {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
+ service:
+ name: {{ $fullName }}
+ port:
+ number: {{ $svcPort }}
+ {{- else }}
+ serviceName: {{ $fullName }}
+ servicePort: {{ $svcPort }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end }}
+---
+{{- if .Values.ingress.s3.web.enabled -}}
+{{- $fullName := include "garage.fullname" . -}}
+{{- $svcPort := .Values.service.s3.web.port -}}
+{{- if and .Values.ingress.s3.web.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
+ {{- if not (hasKey .Values.ingress.s3.web.annotations "kubernetes.io/ingress.class") }}
+ {{- $_ := set .Values.ingress.s3.web.annotations "kubernetes.io/ingress.class" .Values.ingress.s3.web.className}}
+ {{- end }}
+{{- end }}
+{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1
+{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+apiVersion: networking.k8s.io/v1beta1
+{{- else -}}
+apiVersion: extensions/v1beta1
+{{- end }}
+kind: Ingress
+metadata:
+ name: {{ $fullName }}-s3-web
+ labels:
+ {{- include "garage.labels" . | nindent 4 }}
+ {{- with .Values.ingress.s3.web.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- if and .Values.ingress.s3.web.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
+ ingressClassName: {{ .Values.ingress.s3.web.className }}
+ {{- end }}
+ {{- if .Values.ingress.s3.web.tls }}
+ tls:
+ {{- range .Values.ingress.s3.web.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
+ {{- end }}
+ {{- end }}
+ rules:
+ {{- range .Values.ingress.s3.web.hosts }}
+ - host: {{ .host | quote }}
+ http:
+ paths:
+ {{- range .paths }}
+ - path: {{ .path }}
+ {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
+ pathType: {{ .pathType }}
+ {{- end }}
+ backend:
+ {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
+ service:
+ name: {{ $fullName }}
+ port:
+ number: {{ $svcPort }}
+ {{- else }}
+ serviceName: {{ $fullName }}
+ servicePort: {{ $svcPort }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/script/helm/garage/templates/service.yaml b/script/helm/garage/templates/service.yaml
new file mode 100644
index 00000000..2bfff99d
--- /dev/null
+++ b/script/helm/garage/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "garage.fullname" . }}
+ labels:
+ {{- include "garage.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.s3.api.port }}
+ targetPort: 3900
+ protocol: TCP
+ name: s3-api
+ - port: {{ .Values.service.s3.web.port }}
+ targetPort: 3902
+ protocol: TCP
+ name: s3-web
+ selector:
+ {{- include "garage.selectorLabels" . | nindent 4 }}
diff --git a/script/helm/garage/templates/serviceaccount.yaml b/script/helm/garage/templates/serviceaccount.yaml
new file mode 100644
index 00000000..a0a89a33
--- /dev/null
+++ b/script/helm/garage/templates/serviceaccount.yaml
@@ -0,0 +1,12 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "garage.serviceAccountName" . }}
+ labels:
+ {{- include "garage.labels" . | nindent 4 }}
+ {{- with .Values.serviceAccount.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+{{- end }}
diff --git a/script/helm/garage/templates/statefulset.yaml b/script/helm/garage/templates/statefulset.yaml
new file mode 100644
index 00000000..82fe89a9
--- /dev/null
+++ b/script/helm/garage/templates/statefulset.yaml
@@ -0,0 +1,97 @@
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ include "garage.fullname" . }}
+ labels:
+ {{- include "garage.labels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ {{- include "garage.selectorLabels" . | nindent 6 }}
+ serviceName: {{ include "garage.fullname" . }}
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "garage.selectorLabels" . | nindent 8 }}
+ spec:
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ include "garage.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 }}
+ ports:
+ - containerPort: 3900
+ name: s3-api
+ - containerPort: 3902
+ name: web-api
+ volumeMounts:
+ - name: meta
+ mountPath: /mnt/meta
+ - name: data
+ mountPath: /mnt/data
+ - name: etc
+ mountPath: /etc/garage.toml
+ subPath: garage.toml
+ # TODO
+ # livenessProbe:
+ # httpGet:
+ # path: /
+ # port: 3900
+ # readinessProbe:
+ # httpGet:
+ # path: /
+ # port: 3900
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ volumes:
+ - name: etc
+ configMap:
+ name: {{ include "garage.fullname" . }}-config
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- if .Values.persistence.enabled }}
+ volumeClaimTemplates:
+ - metadata:
+ name: meta
+ spec:
+ accessModes: [ "ReadWriteOnce" ]
+ {{- if hasKey .Values.persistence.meta "storageClass" }}
+ storageClassName: {{ .Values.persistence.meta.storageClass | quote }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ .Values.persistence.meta.size | quote }}
+ - metadata:
+ name: data
+ spec:
+ accessModes: [ "ReadWriteOnce" ]
+ {{- if hasKey .Values.persistence.data "storageClass" }}
+ storageClassName: {{ .Values.persistence.data.storageClass | quote }}
+ {{- end }}
+ resources:
+ requests:
+ storage: {{ .Values.persistence.data.size | quote }}
+ {{- end }}
diff --git a/script/helm/garage/values.yaml b/script/helm/garage/values.yaml
new file mode 100644
index 00000000..dd1c99f0
--- /dev/null
+++ b/script/helm/garage/values.yaml
@@ -0,0 +1,124 @@
+# Default values for garage.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+# Garage configuration. These values go to garage.toml
+garage:
+ metadataDir: "/mnt/meta"
+ dataDir: "/mnt/data"
+ replicationMode: "3"
+ rpcBindAddr: "[::]:3901"
+ rpcSecret: "1799bccfd7411eddcf9ebd316bc1f5287ad12a68094e1c6ac6abde7e6feae1ec"
+ bootstrapPeers: []
+ # kubernetes_namespace: "default"
+ # kubernetes_service_name: "garage-daemon"
+ kubernetesSkipCrd: false
+ s3:
+ api:
+ region: "garage"
+ rootDomain: ".s3.garage.tld"
+ web:
+ rootDomain: ".web.garage.tld"
+ index: "index.html"
+
+# Data persistence
+persistence:
+ enabled: true
+ meta:
+ # storageClass: ""
+ size: 100Mi
+ data:
+ # storageClass: ""
+ size: 100Mi
+
+# Number of StatefulSet replicas to start
+replicaCount: 3
+
+image:
+ repository: dxflrs/amd64_garage
+ pullPolicy: IfNotPresent
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+ # Specifies whether a service account should be created
+ create: true
+ # Annotations to add to the service account
+ annotations: {}
+ # The name of the service account to use.
+ # If not set and create is true, a name is generated using the fullname template
+ name: ""
+
+podAnnotations: {}
+
+podSecurityContext: {}
+ # fsGroup: 2000
+
+securityContext: {}
+ # capabilities:
+ # drop:
+ # - ALL
+ # readOnlyRootFilesystem: true
+ # runAsNonRoot: true
+ # runAsUser: 1000
+
+service:
+ type: ClusterIP
+ s3:
+ api:
+ port: 3900
+ web:
+ port: 3902
+
+ingress:
+ s3:
+ api:
+ enabled: false
+ className: ""
+ annotations: {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ hosts:
+ - host: chart-example.local
+ paths:
+ - path: /
+ pathType: ImplementationSpecific
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # - chart-example.local
+ web:
+ enabled: false
+ className: ""
+ annotations: {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ hosts:
+ - host: chart-example.local
+ paths:
+ - path: /
+ pathType: ImplementationSpecific
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # - chart-example.local
+
+resources: {}
+ # We usually recommend not to specify default resources and to leave this as a conscious
+ # choice for the user. This also increases chances charts run on environments with little
+ # resources, such as Minikube. If you do want to specify resources, uncomment the following
+ # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+ # limits:
+ # cpu: 100m
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}