Skip to content

Commit

Permalink
feat(k8s): Adds a helm chart
Browse files Browse the repository at this point in the history
This commit includes a helm chart or Meli.  I created it based on the
k8s manifest contributed by @Berndinox.  Hopefully that `values.yaml`
file I provided sufficiently explains the various knobs to turn.  One
potential area of improvement would be allowing existing PVCs to
be used.

Note that this includes the feature I mentioned in getmeli#233 but which
also applies to getmeli#238 which is the ability to explicitly list all sites
so that the ingress configuration can fetch SSL certificates
_for branch host names_.

Ideally, this helm chart would be packaged up and shared...somewhere.
I'm actually not that well versed in how to host helm charts for
open source software.  I know there used to be a public registry
hosted by Google but then they withdrew support and the
landscape got very fragmented.  If there _is_ a place to host such
a chart, it would be good to publish this there so that an ordinary
helm installation could reference it.

Not that the `values.yaml` file include the image and tag.  This
can be customized to run a custom Meli image instead of the
official Docker hub image.

This closes getmeli#246.
  • Loading branch information
mt35-rs committed Feb 2, 2022
1 parent 69891cf commit b8acdee
Show file tree
Hide file tree
Showing 11 changed files with 483 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ data
*.iml
*.env
*.tgz

values.yaml
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
deployment/helm/meli-chart/**/*.yaml
14 changes: 14 additions & 0 deletions deployment/helm/meli-chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v2
name: meli
description: A server for deploying static web sites

# This is a chart for an application
type: application

# The version of this chart is automatically filled in by rsci. It will
# be a semantic version compatible with (https://semver.org/)
version: 1.0.0-beta.24

# Our application version will mirror the chart version except we will
# leave off the semantic version if it is a work in progress.
appVersion: 1.0.0-beta.24
17 changes: 17 additions & 0 deletions deployment/helm/meli-chart/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
This will configure the Meli admin server to run at:

https://{{ .Values.ingress.domain }}

It will also direct `cert-manager` to issue certificates for:

https://*.{{ .Values.ingress.domain }}
{{ range $index, $site := .Values.ingress.sites }}
https://*.{{ $site }}.{{ $.Values.ingress.domain }}
{{ end }}

The Meli deployment will pick up any additional environment variables
from the secret `deployment-env`. This is where you should put any
"secrets" like authentication client secrets, passwords, etc. You are
also free to put any other less confidential information in there as well.
But, at a minimum, it is where you should put authentication related
configuration variables like `MELI_PASSWORD`, or `MELI_GITLAB_*`.
63 changes: 63 additions & 0 deletions deployment/helm/meli-chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

{{/*
Expand the name of the chart.
*/}}
{{- define "helper.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 "helper.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 "helper.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

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

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

{{/*
Create the name of the service account to use
*/}}
{{- define "helper.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "helper.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
118 changes: 118 additions & 0 deletions deployment/helm/meli-chart/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: meli-app
labels:
{{- include "helper.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: {{ include "helper.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "helper.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
containers:
- name: meli
image: "{{ .Values.image }}:{{ .Values.tag}}"
envFrom:
- secretRef:
name: deployment-env
env:
- name: MELI_URL
value: {{ printf "https://%s" .Values.ingress.domain | quote }}
- name: MELI_USER
value: {{ .Values.user | quote }}
- name: MELI_HTTPS_AUTO
value: "false"
- name: MELI_MONGO_HOST
value: {{ .Values.mongo.host | quote }}
- name: MELI_MONGO_PORT
value: {{ .Values.mongo.port | quote }}
- name: MELI_MAX_ORGS
value: {{ .Values.maxorgs | quote }}
- name: MELI_MONGO_USER
value: {{ .Values.mongo.user | quote }}
- name: MELI_MONGO_DB
value: {{ .Values.mongo.db | quote }}
imagePullPolicy: {{ .Values.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
- name: api
containerPort: 3001
protocol: TCP
- name: admin
containerPort: 2019
protocol: TCP
# In Work - Docker File needs to be updated
#securityContext:
# runAsUser: 1001
volumes: null
resources:
requests:
cpu: 200m
memory: 256Mi
#limits:
# cpu500m
volumeMounts:
- name: data
mountPath: /data
subPath: data
- name: config
mountPath: /config
subPath: config
- name: sites
mountPath: /sites
subPath: sites
livenessProbe:
httpGet:
path: /
port: http
scheme: HTTP
httpHeaders:
- name: Host
value: {{ .Values.ingress.domain }}
initialDelaySeconds: 60
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 6
readinessProbe:
httpGet:
path: /
port: http
scheme: HTTP
httpHeaders:
- name: Host
value: {{ .Values.ingress.domain }}
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 6
volumes:
- name: data
persistentVolumeClaim:
claimName: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-data
- name: config
persistentVolumeClaim:
claimName: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-config
- name: sites
persistentVolumeClaim:
claimName: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-sites
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
serviceAccountName: default
serviceAccount: default
#securityContext:
# fsGroup: 1001
68 changes: 68 additions & 0 deletions deployment/helm/meli-chart/templates/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
labels:
run: meli-svc
annotations:
cert-manager.io/cluster-issuer: {{ .Values.ingress.certificateIssuer | quote }}
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive"
# This is useful if we every want to map hosts outside the domain to the meli server
# nginx.ingress.kubernetes.io/upstream-vhost: {{ printf "%s" .Values.ingress.domain | quote }}
nginx.ingress.kubernetes.io/send-timeout: "36000"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "36000"
nginx.ingress.kubernetes.io/proxy-read-timeout: "36000"
# This value should match the value in the deployment
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
spec:
ingressClassName: nginx

# NB - The order of these rules MATTERS
rules:
# First, check if this is the bare domain. If so, it will
# be interpreted by Meli as a request for the admin pages
- host: {{ .Values.ingress.domain | quote }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: meli-svc
port:
number: 80
# Now check the wildcard matches. Ultimately, they get routed
# the same, but the host pattern is different.
- host: "*.{{ .Values.ingress.domain }}"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: meli-svc
port:
number: 80
# Now check the wildcard matches. Ultimately, they get routed
# the same, but the host pattern is different.
{{- range $index, $site := .Values.ingress.sites }}
- host: "*.{{ $site }}.{{ $.Values.ingress.domain }}"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: meli-svc
port:
number: 80
{{- end }}
tls:
- hosts:
- {{ .Values.ingress.domain | quote }}
- "*.{{ .Values.ingress.domain }}"
{{- range $index, $site := .Values.ingress.sites }}
- "*.{{ $site }}.{{ $.Values.ingress.domain }}"
{{- end }}
secretName: {{ .Values.ingress.tlsSecret }}
97 changes: 97 additions & 0 deletions deployment/helm/meli-chart/templates/mongo-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{{- if .Values.mongo.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo
labels:
{{- include "helper.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: {{ include "helper.name" . }}-mongo
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "helper.name" . }}-mongo
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
containers:
- image: bitnami/mongodb
imagePullPolicy: IfNotPresent
name: mongo
securityContext:
runAsUser: 1001
runAsNonRoot: true
ports:
- name: mongo-port
containerPort: {{ .Values.mongo.port }}
protocol: TCP
env:
- name: MONGODB_USERNAME
value: {{ .Values.mongo.user | quote }}
- name: MONGODB_PASSWORD
valueFrom:
secretKeyRef:
name: deployment-env
key: MELI_MONGO_PASSWORD
- name: MONGODB_DATABASE
value: {{ .Values.mongo.db | quote }}
- name: MONGODB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: deployment-env
key: MELI_ROOT_MONGO_PASSWORD
- name: BITNAMI_DEBUG
value: "false"
resources:
requests:
cpu: {{ .Values.resources.mongo.cpu }}
memory: {{ .Values.resources.mongo.memory }}
#limits:
# cpu500m
volumeMounts:
- name: data-db
mountPath: /bitnami/mongodb
subPath: mongodb
livenessProbe:
exec:
command:
- mongo
- '--disableImplicitSessions'
- '--eval'
- db.adminCommand('ping')
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 6
readinessProbe:
exec:
command:
- bash
- '-ec'
- >
mongo --disableImplicitSessions $TLS_OPTIONS --eval
'db.hello().isWritablePrimary || db.hello().secondary' | grep
-q 'true'
initialDelaySeconds: 5
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 6
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
serviceAccountName: default
serviceAccount: default
securityContext:
fsGroup: 1001
volumes:
- name: data-db
persistentVolumeClaim:
claimName: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-data-db
{{ end }}
Loading

0 comments on commit b8acdee

Please sign in to comment.