You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by wa...@apache.org on 2022/06/02 06:37:24 UTC
[incubator-devlake] branch main updated: feat: support helm deployment
This is an automated email from the ASF dual-hosted git repository.
warren pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 4dfa4b1d feat: support helm deployment
4dfa4b1d is described below
commit 4dfa4b1d85d435ec5ad2dd0919bd9abfd0d9a419
Author: Ji Bin <ma...@live.com>
AuthorDate: Wed May 25 03:46:37 2022 -0400
feat: support helm deployment
issue: #1991
Signed-off-by: Ji Bin <ma...@live.com>
---
deployment/helm/.helmignore | 23 +++++
deployment/helm/Chart.yaml | 10 +++
deployment/helm/README.md | 50 +++++++++++
deployment/helm/templates/NOTES.txt | 15 ++++
deployment/helm/templates/_helpers.tpl | 63 ++++++++++++++
deployment/helm/templates/configmaps.yaml | 9 ++
deployment/helm/templates/deployments.yaml | 82 ++++++++++++++++++
deployment/helm/templates/services.yaml | 81 ++++++++++++++++++
deployment/helm/templates/statefulsets.yaml | 127 ++++++++++++++++++++++++++++
deployment/helm/values.yaml | 126 +++++++++++++++++++++++++++
10 files changed, 586 insertions(+)
diff --git a/deployment/helm/.helmignore b/deployment/helm/.helmignore
new file mode 100644
index 00000000..0e8a0eb3
--- /dev/null
+++ b/deployment/helm/.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/deployment/helm/Chart.yaml b/deployment/helm/Chart.yaml
new file mode 100644
index 00000000..3af0e999
--- /dev/null
+++ b/deployment/helm/Chart.yaml
@@ -0,0 +1,10 @@
+apiVersion: v2
+name: devlake
+description: A Helm chart for devlake
+type: application
+
+# Chart version
+version: 0.1.0
+
+# devlake version
+appVersion: "0.11.0"
diff --git a/deployment/helm/README.md b/deployment/helm/README.md
new file mode 100644
index 00000000..d6e62142
--- /dev/null
+++ b/deployment/helm/README.md
@@ -0,0 +1,50 @@
+# Deploy devlake with helm
+
+## Prerequest
+
+- Helm >= 3.6.0
+- Kubernetes >= 1.19.0
+
+## Quick Install
+
+clone the code, and enter the deployment/helm folder.
+```
+helm install devlake .
+```
+
+And visit your devlake from the node port (32001 by default).
+
+## Parameters
+
+Some useful parameter for the chart, you could also check them in values.yaml
+
+| Parameter | Description | Default |
+|-----------|-------------|---------|
+| replicaCount | Replica Count for devlake, currently not used | 1 |
+| mysql.useExternal | If use external mysql server, currently not used | false |
+| mysql.externalServer | External mysql server address | 127.0.0.1 |
+| mysql.externalPort | External mysql server port | 3306 |
+| mysql.username | username for mysql | merico |
+| mysql.password | password for mysql | merico |
+| mysql.database | database for mysql | lake |
+| mysql.rootPassword | root password for mysql | admin |
+| mysql.storage.class | storage class for mysql's volume | "" |
+| mysql.storage.size | volume size for mysql's data | 5Gi |
+| mysql.image.repository | repository for mysql's image | mysql |
+| mysql.image.tag | image tag for mysql's image | 8.0.26 |
+| mysql.image.pullPolicy | pullPolicy for mysql's image | IfNotPresent |
+| grafana.image.repository | repository for grafana's image | mericodev/grafana |
+| grafana.image.tag | image tag for grafana's image | latest |
+| grafana.image.pullPolicy | pullPolicy for grafana's image | Always |
+| lake.storage.class | storage class for lake's volume | "" |
+| lake.storage.size | volume size for lake's data | 100Mi |
+| lake.image.repository | repository for lake's image | mericodev/lake |
+| lake.image.tag | image tag for lake's image | latest |
+| lake.image.pullPolicy | pullPolicy for lake's image | Always |
+| ui.image.repository | repository for ui's image | mericodev/config-ui |
+| ui.image.tag | image tag for ui's image | latest |
+| ui.image.pullPolicy | pullPolicy for ui's image | Always |
+| service.type | Service type for exposed service | NodePort |
+| service.grafanaPort | Service port for grafana | 32000 |
+| service.uiPort | Service port for config ui | 32001 |
+| service.grafanaEndpoint | The external grafana endpoint, used when ingress not configured | http://127.0.0.1:32000 |
\ No newline at end of file
diff --git a/deployment/helm/templates/NOTES.txt b/deployment/helm/templates/NOTES.txt
new file mode 100644
index 00000000..5745506f
--- /dev/null
+++ b/deployment/helm/templates/NOTES.txt
@@ -0,0 +1,15 @@
+
+Welcome to use devlake.
+
+Now please get the 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 "devlake.fullname" . }}-ui)
+ export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
+ echo http://$NODE_IP:$NODE_PORT
+{{- end }}
\ No newline at end of file
diff --git a/deployment/helm/templates/_helpers.tpl b/deployment/helm/templates/_helpers.tpl
new file mode 100644
index 00000000..40d1c0b1
--- /dev/null
+++ b/deployment/helm/templates/_helpers.tpl
@@ -0,0 +1,63 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "devlake.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 "devlake.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 "devlake.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "devlake.labels" -}}
+helm.sh/chart: {{ include "devlake.chart" . }}
+{{ include "devlake.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "devlake.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "devlake.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "devlake.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "devlake.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
+
diff --git a/deployment/helm/templates/configmaps.yaml b/deployment/helm/templates/configmaps.yaml
new file mode 100644
index 00000000..0a7f1613
--- /dev/null
+++ b/deployment/helm/templates/configmaps.yaml
@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ include "devlake.fullname" . }}-config
+data:
+ MYSQL_USER: "{{ .Values.mysql.username }}"
+ MYSQL_PASSWORD: "{{ .Values.mysql.password }}"
+ MYSQL_DATABASE: "{{ .Values.mysql.database }}"
+ MYSQL_ROOT_PASSWORD: "{{ .Values.mysql.rootPassword }}"
diff --git a/deployment/helm/templates/deployments.yaml b/deployment/helm/templates/deployments.yaml
new file mode 100644
index 00000000..8f6d3013
--- /dev/null
+++ b/deployment/helm/templates/deployments.yaml
@@ -0,0 +1,82 @@
+---
+# grafana
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "devlake.fullname" . }}-grafana
+ labels:
+ {{- include "devlake.labels" . | nindent 4 }}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ {{- include "devlake.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ labels:
+ {{- include "devlake.selectorLabels" . | nindent 8 }}
+ devlakeComponent: grafana
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}-grafana
+ image: "{{ .Values.grafana.image.repository }}:{{ .Values.grafana.image.tag }}"
+ imagePullPolicy: {{ .Values.grafana.image.pullPolicy }}
+ ports:
+ - containerPort: 3000
+ livenessProbe:
+ httpGet:
+ path: /api/health
+ port: 3000
+ initialDelaySeconds: 30
+ timeoutSeconds: 30
+ envFrom:
+ - configMapRef:
+ name: {{ include "devlake.fullname" . }}-config
+ env:
+ - name: GF_USERS_ALLOW_SIGN_UP
+ value: 'false'
+ - name: GF_DASHBOARDS_JSON_ENABLED
+ value: 'true'
+ - name: GF_LIVE_ALLOWED_ORIGINS
+ value: '*'
+ - name: MYSQL_URL
+ value: {{ include "devlake.fullname" . }}-mysql:3306
+
+---
+# devlake-ui
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "devlake.fullname" . }}-ui
+ labels:
+ {{- include "devlake.labels" . | nindent 4 }}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ {{- include "devlake.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ labels:
+ {{- include "devlake.selectorLabels" . | nindent 8 }}
+ devlakeComponent: ui
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}-ui
+ image: "{{ .Values.ui.image.repository }}:{{ .Values.ui.image.tag }}"
+ imagePullPolicy: {{ .Values.ui.image.pullPolicy }}
+ ports:
+ - containerPort: 80
+ envFrom:
+ - configMapRef:
+ name: {{ include "devlake.fullname" . }}-config
+ env:
+ - name: DEVLAKE_ENDPOINT
+ # TODO: remove hardcoded `cluster.local`
+ value: {{ include "devlake.fullname" . }}-lake.{{ .Release.Namespace }}.svc.cluster.local:8080
+ - name: GRAFANA_ENDPOINT
+ value: "{{ .Values.service.grafanaEndpoint }}"
+ # - name: ADMIN_USER
+ # value: "admin"
+ # - name: ADMIN_PASS
+ # value: "admin"
\ No newline at end of file
diff --git a/deployment/helm/templates/services.yaml b/deployment/helm/templates/services.yaml
new file mode 100644
index 00000000..dc9e60b1
--- /dev/null
+++ b/deployment/helm/templates/services.yaml
@@ -0,0 +1,81 @@
+# mysql services
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "devlake.fullname" . }}-mysql
+ labels:
+ {{- include "devlake.labels" . | nindent 4 }}
+spec:
+ selector:
+ {{- include "devlake.selectorLabels" . | nindent 4 }}
+ devlakeComponent: mysql
+ ports:
+ - protocol: TCP
+ name: mysql
+ port: 3306
+ targetPort: 3306
+
+# grafana services
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "devlake.fullname" . }}-grafana
+ labels:
+ {{- include "devlake.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ selector:
+ {{- include "devlake.selectorLabels" . | nindent 4 }}
+ devlakeComponent: grafana
+ ports:
+ - protocol: TCP
+ name: grafana
+ port: {{ .Values.service.grafanaPort }}
+ targetPort: 3000
+ {{- if eq .Values.service.type "NodePort" }}
+ nodePort: {{ .Values.service.grafanaPort }}
+ {{- end }}
+
+
+
+# devlake services
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "devlake.fullname" . }}-lake
+ labels:
+ {{- include "devlake.labels" . | nindent 4 }}
+spec:
+ selector:
+ {{- include "devlake.selectorLabels" . | nindent 4 }}
+ devlakeComponent: lake
+ ports:
+ - protocol: TCP
+ name: devlake
+ port: 8080
+ targetPort: 8080
+
+---
+# ui
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "devlake.fullname" . }}-ui
+ labels:
+ {{- include "devlake.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ selector:
+ {{- include "devlake.selectorLabels" . | nindent 4 }}
+ devlakeComponent: ui
+ ports:
+ - protocol: TCP
+ name: ui
+ port: {{ .Values.service.uiPort }}
+ targetPort: 80
+ {{- if eq .Values.service.type "NodePort" }}
+ nodePort: {{ .Values.service.uiPort }}
+ {{- end }}
diff --git a/deployment/helm/templates/statefulsets.yaml b/deployment/helm/templates/statefulsets.yaml
new file mode 100644
index 00000000..2fb44ceb
--- /dev/null
+++ b/deployment/helm/templates/statefulsets.yaml
@@ -0,0 +1,127 @@
+---
+# mysql statefulset
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ include "devlake.fullname" . }}-mysql
+ labels:
+ {{- include "devlake.labels" . | nindent 4 }}
+spec:
+ replicas: 1
+ serviceName: {{ include "devlake.fullname" . }}-mysql
+ selector:
+ matchLabels:
+ {{- include "devlake.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ labels:
+ {{- include "devlake.selectorLabels" . | nindent 8 }}
+ devlakeComponent: mysql
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}-mysql
+ image: "{{ .Values.mysql.image.repository }}:{{ .Values.mysql.image.tag }}"
+ imagePullPolicy: {{ .Values.mysql.image.pullPolicy }}
+ ports:
+ - name: mysql
+ containerPort: 3306
+ protocol: TCP
+ livenessProbe:
+ exec:
+ command:
+ - "sh"
+ - "-c"
+ - "mysqladmin ping -u root -p{{ .Values.mysql.rootPassword }}"
+ initialDelaySeconds: 60
+ timeoutSeconds: 30
+ {{- with .Values.mysql.resources }}
+ resources:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ envFrom:
+ - configMapRef:
+ name: {{ include "devlake.fullname" . }}-config
+ volumeMounts:
+ - mountPath: /var/lib/mysql
+ name: {{ include "devlake.fullname" . }}-mysql-data
+ {{- with .Values.mysql.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.mysql.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.mysql.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ volumeClaimTemplates:
+ - metadata:
+ name: {{ include "devlake.fullname" . }}-mysql-data
+ spec:
+ accessModes: [ "ReadWriteOnce" ]
+ {{- with .Values.mysql.storage.class }}
+ storageClassName: "{{ . }}"
+ {{- end }}
+ resources:
+ requests:
+ storage: "{{ .Values.mysql.storage.size }}"
+
+
+---
+# devlake
+# TODO: graceful startup: init container for waiting mysql ready
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ include "devlake.fullname" . }}-lake
+ labels:
+ {{- include "devlake.labels" . | nindent 4 }}
+spec:
+ replicas: 1
+ serviceName: {{ include "devlake.fullname" . }}-lake
+ selector:
+ matchLabels:
+ {{- include "devlake.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ labels:
+ {{- include "devlake.selectorLabels" . | nindent 8 }}
+ devlakeComponent: lake
+ spec:
+ containers:
+ - name: {{ .Chart.Name }}-lake
+ image: "{{ .Values.lake.image.repository }}:{{ .Values.lake.image.tag }}"
+ imagePullPolicy: {{ .Values.lake.image.pullPolicy }}
+ ports:
+ - containerPort: 8080
+ livenessProbe:
+ httpGet:
+ path: /blueprints
+ port: 8080
+ scheme: HTTP
+ initialDelaySeconds: 60
+ timeoutSeconds: 30
+ envFrom:
+ - configMapRef:
+ name: {{ include "devlake.fullname" . }}-config
+ env:
+ - name: DB_URL
+ value: mysql://{{ .Values.mysql.username }}:{{ .Values.mysql.password }}@{{ include "devlake.fullname" . }}-mysql:3306/{{ .Values.mysql.database }}?charset=utf8mb4&parseTime=True
+ - name: ENV_PATH
+ value: /app/config/.env
+ volumeMounts:
+ - mountPath: /app/config
+ name: {{ include "devlake.fullname" . }}-lake-config
+ volumeClaimTemplates:
+ - metadata:
+ name: {{ include "devlake.fullname" . }}-lake-config
+ spec:
+ accessModes: [ "ReadWriteOnce" ]
+ {{- with .Values.lake.storage.class }}
+ storageClassName: "{{ . }}"
+ {{- end }}
+ resources:
+ requests:
+ storage: "{{ .Values.lake.storage.size }}"
diff --git a/deployment/helm/values.yaml b/deployment/helm/values.yaml
new file mode 100644
index 00000000..276d5989
--- /dev/null
+++ b/deployment/helm/values.yaml
@@ -0,0 +1,126 @@
+# replica count for dev
+replicaCount: 1
+
+mysql:
+ # if use external mysql server, please set true
+ # by default using false, chart will create a single mysql instance
+ # TODO(matrixji): add support external mysql server
+ useExternal: false
+
+ # the external mysql server address
+ externalServer: 127.0.0.1
+
+ # external mysql port
+ externalPort: 3306
+
+ # the username for devlake database
+ username: merico
+
+ # the password for devlake database
+ password: merico
+
+ # the database for devlake
+ database: lake
+
+ # root password for mysql, only used when use_external=true
+ rootPassword: admin
+
+ # storage for mysql
+ storage:
+ # the storage class for pv, leave empty will using default
+ class: ""
+ size: 5Gi
+
+ # image for mysql
+ image:
+ repository: mysql
+ tag: 8.0.26
+ pullPolicy: IfNotPresent
+
+ # resources config for mysql if have
+ resources: {}
+
+ # nodeSelector config for mysql if have
+ nodeSelector: {}
+
+ # tolerations config for mysql if have
+ tolerations: []
+
+ # affinity config for mysql if have
+ affinity: {}
+
+
+grafana:
+ # image for grafana
+ image:
+ repository: mericodev/grafana
+ tag: latest
+ pullPolicy: Always
+
+ resources: {}
+
+ nodeSelector: {}
+
+ tolerations: []
+
+ affinity: {}
+
+
+lake:
+ image:
+ repository: mericodev/lake
+ tag: latest
+ pullPolicy: Always
+ # storage for config
+ storage:
+ # the storage class for pv, leave empty will using default
+ class: ""
+ size: 100Mi
+
+ resources: {}
+
+ nodeSelector: {}
+
+ tolerations: []
+
+ affinity: {}
+
+ui:
+ image:
+ repository: mericodev/config-ui
+ tag: latest
+ pullPolicy: Always
+
+ resources: {}
+
+ nodeSelector: {}
+
+ tolerations: []
+
+ affinity: {}
+
+service:
+ type: NodePort
+ # service port for grafana
+ grafanaPort: 32000
+ # service port for devlake-ui
+ uiPort: 32001
+ # the external endpoint for grafana, only used when ingress not enabled
+ grafanaEndpoint: http://127.0.0.1:32000
+
+# TODO(matrixji) support ingress.
+ingress:
+ 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
\ No newline at end of file