diff --git a/assets/codership/mysql-galera-0.3.0.tgz b/assets/codership/mysql-galera-0.3.0.tgz new file mode 100644 index 000000000..e97972ec7 Binary files /dev/null and b/assets/codership/mysql-galera-0.3.0.tgz differ diff --git a/assets/icons/mysql-galera.png b/assets/icons/mysql-galera.png new file mode 100644 index 000000000..033e641d4 Binary files /dev/null and b/assets/icons/mysql-galera.png differ diff --git a/charts/codership/mysql-galera/0.3.0/Chart.yaml b/charts/codership/mysql-galera/0.3.0/Chart.yaml new file mode 100644 index 000000000..b2c461b01 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/Chart.yaml @@ -0,0 +1,20 @@ +annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: MySQL Galera Cluster + catalog.cattle.io/kube-version: '>=1.21-0' + catalog.cattle.io/release-name: "" +apiVersion: v2 +appVersion: 8.0.40 +description: A Helm chart for deploying MySQL/Galera cluster in Kubernetes +home: https://galeracluster.com +icon: file://assets/icons/mysql-galera.png +keywords: +- mysql +- galera +- cluster +kubeVersion: '>=1.21-0' +name: mysql-galera +sources: +- https://github.com/codership/containers +type: application +version: 0.3.0 diff --git a/charts/codership/mysql-galera/0.3.0/README.md b/charts/codership/mysql-galera/0.3.0/README.md new file mode 100644 index 000000000..23a49cd41 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/README.md @@ -0,0 +1,92 @@ +# HELM charts for MySQL/Galera cluster + +## Common usage: +``` +helm install [set values] . +``` +see values.yaml for supported/required oprtions. + +### Setting values for Docker image +On `helm install` you will need to set some environmet variables for the image, e.g. +``` +--set env.MYSQL_ROOT_PASSWORD= --set env.MYSQL_USER= --set env.MYSQL_PASSWORD= +``` +For all variables see https://hub.docker.com/_/mysql. Not all of them are supported, e.g. datadir mount point is fixed. + +These variables will be used to initialize the database if not yet initialized. Otherwise MYSQL_USER and MYSQL_PASSWORD will be used for the readiness probe so they must be specified on all chart installs. MYSQL_ROOT_PASSWORD is used only once for database initialization. + +### Requesting kubernetes resources for pods +The usual kubernetes stuff: +``` +--set resorces.requests.memory=4Gi --set resources.requests.storage=16Gi --set resources.requests.cpu=4 +``` + +### Connecting to cluster +By default MySQL client service is open through load balancer on port 30006. It can be changed (if supported by k8s cluster) by: +``` +--set service.port=NNNN +``` +*NOTE:* in Scaleway Kubernetes cluster load balancer opens port 3306 regardless of the `service.port` setting. + +### Graceful cluster shutdown +Graceful cluster shutdown requires scaling the cluster to one node before `helm uninstall`: +``` +helm upgrade --reuse-values --set replicas=1 . +mysql -e "shutdown;" +helm uninistall +``` +This will leave the last pod in the stateful set (0) safe to automatically bootstrap the cluster from. + +### Force bootstrap from a particular pod +In case the cluster need to be recovered from scratch (e.g. `helm uninstall` was called), it can be forced to bootstrap from a particular pod. To find which pod to use the cluster can be started in "recover-only" mode: +``` +$ helm install --set env.WSREP_RECOVER_ONLY . +``` +Then +``` +$ kubectl logs | grep 'Recovered position' +``` +shall print diagnostic output showing pod position in replication history. Most updated pod should be chosen as a bootstrap node. +`find_most_updated.sh` script can help to identify the right pod. It will look like: +``` +$ ./find_most_updated.sh +Candidates (NB: if there is more than one, choose carefully): +UUID count: 3 bf6bd3e5-020e-11ef-ae7a-ceb1e82e2567:425 -mysql-galera-2 +``` +Where bf6bd3e5-020e-11ef-ae7a-ceb1e82e2567 is the cluster/dataset UUID and 425 is the sequence number of the last data change. + +After the most updated pod has been identified, check its `grastate.dat` file: +``` +$ kubectl exec -mysql-galera-2 -- cat /var/lib/mysql/grastate.dat +# GALERA saved state +version: 2.1 +uuid: bf6bd3e5-020e-11ef-ae7a-ceb1e82e2567 +seqno: -1 +safe_to_bootstrap: 0 +``` +Then run the followwing command: +``` +$ kubectl exec -mysql-galera-2 -- sed -i "s/safe_to_bootstrap:[[:blank:]]*[0-9]/safe_to_bootstrap: 1/" /var/lib/mysql/grastate.dat +``` +And if the `uuid:` field above is `00000000-0000-0000-0000-000000000000` run the follwowing: +``` +$ kubectl exec -mysql-galera-2 -- sed -i "s/uuid:[[:blank:]]*00000000-0000-0000-0000-000000000000/uuid: /" /var/lib/mysql/grastate.dat +``` +Verify that resulting `grastate.dat` makes sense: +``` +$ kubectl exec -mysql-galera-2 -- cat /var/lib/mysql/grastate.dat +... +``` +Now uninstall the cluster: +``` +$ helm uninstall +``` +Wait for the pods to be deleted and install with the production options: +``` +$ helm install --set env.MYSQL_USER=... --set env.MYSQL_PASSWORD=... . +``` +The cluster should be up and running after nodes synchronization. The progress can be monitored through +``` +$ kubectl logs +``` +Once the nodes reach `SYNCED` state they will be available through the Kubernetes load balancer. diff --git a/charts/codership/mysql-galera/0.3.0/VARIABLES b/charts/codership/mysql-galera/0.3.0/VARIABLES new file mode 100644 index 000000000..361656894 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/VARIABLES @@ -0,0 +1,14 @@ +####################################### +# TEST VARIABLES. NOT FOR PRODUCTION! # +####################################### +# +REPOSITORY="codership/mysql-galera" +TAG="8.0.40" +# +DBUSER="admin" +USER_PW="LohP4upho0oephah" +MYSQL_ROOT_PASSWORD="Oohiechohr8xooTh" +# +DOCKER_USER="${DOCKERHUBCREDS_USR:-}" +DOCKER_PASSWORD="${DOCKERHUBCREDS_PSW:-}" +# diff --git a/charts/codership/mysql-galera/0.3.0/app-readme.md b/charts/codership/mysql-galera/0.3.0/app-readme.md new file mode 100644 index 000000000..bea42f640 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/app-readme.md @@ -0,0 +1,20 @@ +# MySQL Galera from Codership + +This is a Helm chart for MySQL Galera from Codership. + +Galera Cluster for MySQL is a true Multi-Master Cluster based on synchronous replication. It’s an easy-to-use, high-availability solution, which provides high system up-time, no data loss and scalability for future growth. + +For documentation, Knowledge Base and Support please visit https://galeracluster.com/ + +* Galera Cluster for MySQL Helm Chart: https://galeracluster.com/2024/10/galera-cluster-for-mysql-helm-chart-for-kubernetes/ +* MySQL Galera Cluster documentation: https://galeracluster.com/library/documentation/index.html + +## Installation +* Plan your cluster capacity. Default is 3 nodes, each with 1 vCPU and 4GB of RAM, the storage is 2GB. It is minimal requirement for Galera to work. +* Consider separate namespace for the MySQL Galera cluster, like `mysql-galera`. +* Install the MySQL Galera chart with desired capacity. + +## Configuration +Sometimes you may want to configure the MySQL Galera cluster with custom values. You can do this by setting the customConfig multiline in values.yaml. + +See the values.yaml file for the full list of configurable parameters. diff --git a/charts/codership/mysql-galera/0.3.0/find_most_updated.sh b/charts/codership/mysql-galera/0.3.0/find_most_updated.sh new file mode 100644 index 000000000..9068b2dcb --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/find_most_updated.sh @@ -0,0 +1,53 @@ +if [ -z "$1" ] +then + echo "Usage:" + echo " $0 " + exit 1 +fi + +set -eu + +declare -A seqno_map # highest seqno for an UUID +declare -A count_map # number of nodes with that UUID +declare -A pod_map # pod candidate for UUID + +get_gtid() +{ + kubectl logs $1 2>&1 |\ + grep "WSREP: Recovered position" |\ + cut -d ' ' -f4 |\ + cut -d '/' -f1 +} + +get_pods() +{ + kubectl get pods |\ + grep $1 |\ + cut -d ' ' -f1 +} + +list_most_updated() +{ + for pod in $(get_pods $1) + do + gtid=$(get_gtid $pod) + uuid=${gtid%%:*}; seqno=${gtid##*:} + + count_map[$uuid]=$(( ${count_map[$uuid]:-0} + 1 )) + + has_seqno=${seqno_map[$uuid]:-"-1"} + if [ $has_seqno -lt $seqno ] + then + seqno_map[$uuid]=$seqno + pod_map[$uuid]="$gtid $pod" + fi + done + + echo "Candidates (NB: if there is more than one, choose carefully):" + (for entry in "${!pod_map[@]}" + do + echo "UUID count: ${count_map[$entry]} ${pod_map[$entry]}" + done) | sort -rn # sort in order of max count +} + +list_most_updated $1 diff --git a/charts/codership/mysql-galera/0.3.0/questions.yaml b/charts/codership/mysql-galera/0.3.0/questions.yaml new file mode 100644 index 000000000..fe68541ff --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/questions.yaml @@ -0,0 +1,57 @@ +questions: + +- variable: mysql.rootpw + default: "" + required: true + type: password + label: MySQL root Password + group: "Global Cluster Settings" + +- variable: mysql.user.name + default: "" + required: true + type: string + label: MySQL User Name + group: "Global Cluster Settings" + +- variable: mysql.user.passwd + default: "" + required: true + type: password + label: MySQL Password for User + group: "Global Cluster Settings" + +- variable: customConfig + default: "[mysqld]" + required: true + type: multiline + label: Additional custom config for MySQL + group: "Global Cluster Settings" + +- variable: replicas + default: 3 + required: true + type: int + label: The number of replicas + group: "Global Cluster Settings" + +- variable: resources.requests.cpu + default: 1 + required: true + type: int + label: The number of CPU + group: "Global Cluster Settings" + +- variable: resources.requests.memory + default: "4Gi" + required: true + type: string + label: The memory amount for instance + group: "Global Cluster Settings" + +- variable: resources.requests.storage + default: "2Gi" + required: true + type: string + label: The storage space for instance + group: "Global Cluster Settings" diff --git a/charts/codership/mysql-galera/0.3.0/set_values.sh b/charts/codership/mysql-galera/0.3.0/set_values.sh new file mode 100644 index 000000000..74c08e44b --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/set_values.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# +set -x +# +cd $(dirname $0) +# + +if ! test -f values.tmpl; then + echo "No values template found, exiting" + exit 1 +fi + +if [[ -f VARIABLES ]]; then + . VARIABLES +fi + +while [[ $# -gt 0 ]]; do + case $1 in + --repo ) + REPOSITORY=$2 + shift 2 + ;; + --tag) + TAG=$2 + shift 2 + ;; + --rootpw) + MYSQL_ROOT_PASSWORD=$2 + shift 2 + ;; + --dbuser) + DBUSER=$2 + shift 2 + ;; + --userpw) + USER_PW=$2 + shift 2 + ;; + --docker-user) + DOCKER_USER=$2 + shift 2 + ;; + --docker-pw) + DOCKER_PASSWORD=$2 + shift 2 + ;; + *) + echo "Error! Unknown parameter: $1" + exit 1 + ;; + esac +done + +sed \ + -e "s:@@REPOSITORY@@:${REPOSITORY}:g" \ + -e "s:@@IMAGE_TAG@@:${TAG}:g" \ + -e "s:@@MYSQL_ROOT_PASSWORD@@:${MYSQL_ROOT_PASSWORD}:g" \ + -e "s:@@MYSQL_USER@@:${DBUSER}:g" \ + -e "s:@@MYSQL_USER_PASSWORD@@:${USER_PW}:g" \ + -e "s:@@USERNAME@@:${DOCKER_USER}:g" \ + -e "s:@@PASSWORD@@:${DOCKER_PASSWORD}:g" \ + values.tmpl > values.yaml diff --git a/charts/codership/mysql-galera/0.3.0/templates/NOTES.txt b/charts/codership/mysql-galera/0.3.0/templates/NOTES.txt new file mode 100644 index 000000000..f0ca94c86 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/templates/NOTES.txt @@ -0,0 +1 @@ +NOTE: It may take a few minutes for the LoadBalancer IP to be available. diff --git a/charts/codership/mysql-galera/0.3.0/templates/_helpers.tpl b/charts/codership/mysql-galera/0.3.0/templates/_helpers.tpl new file mode 100644 index 000000000..ea5f2fbeb --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/templates/_helpers.tpl @@ -0,0 +1,90 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "mysql-galera.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Specify image pull secrets +*/}} +{{- define "imagePullSecret" }} +{{- with .Values.imageCredentials }} +{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} +{{- end }} +{{- end }} + +{{/* +Create full image string from values yaml +*/}} +{{- define "mysql-galera.image" -}} +{{- $registryName := .Values.image.registry -}} +{{- $repositoryName := .Values.image.repository -}} +{{- $separator := ":" -}} +{{- $termination := .Values.image.tag | toString -}} +{{- if .Values.image.digest }} + {{- $separator = "@" -}} + {{- $termination = .Values.image.digest | toString -}} +{{- end -}} +{{- if $registryName }} + {{- printf "%s/%s%s%s" $registryName $repositoryName $separator $termination -}} +{{- else -}} + {{- printf "%s%s%s" $repositoryName $separator $termination -}} +{{- end -}} +{{- 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 "mysql-galera.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 "mysql-galera.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "mysql-galera.labels" -}} +helm.sh/chart: {{ include "mysql-galera.chart" . }} +{{ include "mysql-galera.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "mysql-galera.selectorLabels" -}} +app.kubernetes.io/name: {{ include "mysql-galera.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "mysql-galera.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "mysql-galera.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/codership/mysql-galera/0.3.0/templates/configmap.yaml b/charts/codership/mysql-galera/0.3.0/templates/configmap.yaml new file mode 100644 index 000000000..b79b40eb4 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/templates/configmap.yaml @@ -0,0 +1,10 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + namespace: {{ .Release.Namespace }} + name: {{ include "mysql-galera.fullname" . }}-v1 +# Override these on command line with: +# --set env.NAME=VALUE +# when starting a cluster from scratch +data: + WSREP_BOOTSTRAP_FROM: '' # to bootstrap from a specific node set it to actual node index diff --git a/charts/codership/mysql-galera/0.3.0/templates/custom-cnf.yaml b/charts/codership/mysql-galera/0.3.0/templates/custom-cnf.yaml new file mode 100644 index 000000000..2ecf135e5 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/templates/custom-cnf.yaml @@ -0,0 +1,8 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + namespace: {{ .Release.Namespace }} + name: custom-cnf +data: + 50-custom.cnf: {{- .Values.customConfig | toYaml | indent 1 }} + \ No newline at end of file diff --git a/charts/codership/mysql-galera/0.3.0/templates/regcred.yaml b/charts/codership/mysql-galera/0.3.0/templates/regcred.yaml new file mode 100644 index 000000000..27e1afda8 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/templates/regcred.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + namespace: {{ .Release.Namespace }} + name: regcred +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ template "imagePullSecret" . }} diff --git a/charts/codership/mysql-galera/0.3.0/templates/secrets.yaml b/charts/codership/mysql-galera/0.3.0/templates/secrets.yaml new file mode 100644 index 000000000..bdf43bb59 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/templates/secrets.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: mysql-galera + namespace: {{ .Release.Namespace }} +type: Opaque +data: + MYSQL_USER: {{ .Values.mysql.user.name | b64enc | quote }} + MYSQL_PASSWORD: {{ .Values.mysql.user.passwd | b64enc | quote }} + MYSQL_ROOT_PASSWORD: {{ .Values.mysql.rootpw | b64enc | quote }} diff --git a/charts/codership/mysql-galera/0.3.0/templates/services.yaml b/charts/codership/mysql-galera/0.3.0/templates/services.yaml new file mode 100644 index 000000000..b033205e2 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/templates/services.yaml @@ -0,0 +1,43 @@ +# Main MySQL client service +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ include "mysql-galera.fullname" . }}-client +spec: + type: LoadBalancer + ports: + - port: 3306 + protocol: TCP + nodePort: {{ .Values.service.port }} # external port + name: client + selector: + app: mysql-galera-node + #tier: dbms +--- +# Headless replication service +apiVersion: v1 +kind: Service +metadata: + namespace: {{ .Release.Namespace }} + name: {{ include "mysql-galera.fullname" . }} +spec: + type: ClusterIP + clusterIP: None + ports: + - port: 4567 + targetPort: 4567 + protocol: TCP + name: replication + - port: 4568 + targetPort: 4568 + protocol: TCP + name: ist + - port: 4444 # remove when switch from rsync to clone + targetPort: 4444 + protocol: TCP + name: sst + selector: + app: mysql-galera-node + #tier: dbms + publishNotReadyAddresses: True diff --git a/charts/codership/mysql-galera/0.3.0/templates/statefulset.yaml b/charts/codership/mysql-galera/0.3.0/templates/statefulset.yaml new file mode 100644 index 000000000..75922129f --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/templates/statefulset.yaml @@ -0,0 +1,121 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "mysql-galera.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: mysql-galera-app + #tier: dbms +spec: + # replication controller + serviceName: {{ include "mysql-galera.fullname" . }} # must match the headless service name for pod hostname resolution + replicas: {{ .Values.replicas | default 3 }} + podManagementPolicy: Parallel + selector: + matchLabels: + app: mysql-galera-node + #tier: dbms + # pod template + template: + metadata: + labels: + app: mysql-galera-node + #tier: dbms + spec: # Pod spec + {{- if and (.Values.imageCredentials.username) (.Values.imageCredentials.password) }} + imagePullSecrets: + - name: regcred + {{- end }} + initContainers: # this might be minikube/hostpath-specific + - name: chown-datadir + image: busybox:latest + command: + - /bin/chown + - -R + - "1000" # or whatever the mysqld UID is, use string "1000" not 1000 due to yaml + - /var/lib/mysql + volumeMounts: + - name: datadir # same as in containers and volumes + mountPath: /var/lib/mysql + readOnly: false + containers: + - name: mysql-galera-node + image: {{ template "mysql-galera.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + requests: + memory: {{ .Values.resources.requests.memory }} + cpu: {{ .Values.resources.requests.cpu }} + # Setting environment variables for the image + # 1. First get them from ConfigMap + envFrom: + - configMapRef: + name: {{ include "mysql-galera.fullname" . }}-v1 + # 2. Override from command line + env: + {{- range $key, $value := .Values.env }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + # 3. make some internal k8s parameters available to the image + - name: MEM_REQUEST + valueFrom: + resourceFieldRef: + containerName: mysql-galera-node + resource: requests.memory + - name: MEM_LIMIT + valueFrom: + resourceFieldRef: + containerName: mysql-galera-node + resource: limits.memory + - name: MYSQL_USER + valueFrom: + secretKeyRef: + name: mysql-galera + key: MYSQL_USER + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: mysql-galera + key: MYSQL_PASSWORD + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: mysql-galera + key: MYSQL_ROOT_PASSWORD + ports: + - containerPort: 3306 + name: client + - containerPort: 4567 + name: replication + - containerPort: 4568 + name: ist + - containerPort: 4444 + name: sst + volumeMounts: + - name: custom-cnf + mountPath: /etc/mysql/conf.d/50-custom.cnf + subPath: 50-custom.cnf + readOnly: true + - name: datadir + mountPath: /var/lib/mysql # inside container + readOnly: false + readinessProbe: + exec: + command: [ sh, /var/lib/mysql/k8s_readiness_probe ] + initialDelaySeconds: 15 + periodSeconds: 2 + timeoutSeconds: 1 + volumes: + - name: custom-cnf + configMap: + name: custom-cnf + volumeClaimTemplates: + - metadata: + name: datadir + spec: + accessModes: [ ReadWriteOnce ] +# storageClassName: {{ include "mysql-galera.fullname" . }}-{{ .Values.storageClass }}-sc + resources: + requests: + storage: {{ .Values.resources.requests.storage }} diff --git a/charts/codership/mysql-galera/0.3.0/templates/tests/test-connection.yaml b/charts/codership/mysql-galera/0.3.0/templates/tests/test-connection.yaml new file mode 100644 index 000000000..7ffe8766c --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "mysql-galera.fullname" . }}-test-connection" + labels: + {{- include "mysql-galera.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "mysql-galera.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/charts/codership/mysql-galera/0.3.0/values.tmpl b/charts/codership/mysql-galera/0.3.0/values.tmpl new file mode 100644 index 000000000..0d2b24627 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/values.tmpl @@ -0,0 +1,63 @@ +# Default values for mysql-galera. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Environment for the image (to be set at command line, overrides settings in config map) +# e.g. --set env.MYSQL_USER="ggg" +env: {} + +# Never go below 3 +replicas: 3 + +image: + registry: docker.io + repository: "@@REPOSITORY@@" + pullPolicy: Always + tag: "@@IMAGE_TAG@@" + digest: "" + +imageCredentials: + registry: docker.io + username: "@@USERNAME@@" + password: "@@PASSWORD@@" + email: info@galeracluster.com + +mysql: + rootpw: "@@MYSQL_ROOT_PASSWORD@@" # will be used only in the case of database initialization + user: + name: "@@MYSQL_USER@@" # this account will be used for read-only liveness checks + passwd: "@@MYSQL_USER_PASSWORD@@" # and a password for that account + +customConfig: | + # This is an additional configuration that will be added to the MySQL main configuration + # It may be changed in the values.yaml file + [mysqld] + character-set-server=utf8mb4 + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +# Minimum required resources per pod +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. + # Below are bare minimums, anything less is not guaranteed to work. + # NOTE: make sure that your worker k8s nodes have more RAM than requested here + requests: + memory: 4Gi # 4G is the minimum for MySQL 8.0 to properly function + cpu: 1 + storage: 2Gi + +# Where to expose MySQL client service to outside world +service: + port: 30006 + +# Autoscaling should be used with caution as persistent volume claims will +# linger after scale down +autoscaling: + enabled: false + minReplicas: 3 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 diff --git a/charts/codership/mysql-galera/0.3.0/values.yaml b/charts/codership/mysql-galera/0.3.0/values.yaml new file mode 100644 index 000000000..cce8d1579 --- /dev/null +++ b/charts/codership/mysql-galera/0.3.0/values.yaml @@ -0,0 +1,63 @@ +# Default values for mysql-galera. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Environment for the image (to be set at command line, overrides settings in config map) +# e.g. --set env.MYSQL_USER="ggg" +env: {} + +# Never go below 3 +replicas: 3 + +image: + registry: docker.io + repository: "codership/mysql-galera" + pullPolicy: Always + tag: "8.0.40" + digest: "" + +imageCredentials: + registry: docker.io + username: "" + password: "" + email: info@galeracluster.com + +mysql: + rootpw: "" # will be used only in the case of database initialization + user: + name: "admin" # this account will be used for read-only liveness checks + passwd: "" # and a password for that account + +customConfig: | + # This is an additional configuration that will be added to the MySQL main configuration + # It may be changed in the values.yaml file + [mysqld] + character-set-server=utf8mb4 + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +# Minimum required resources per pod +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. + # Below are bare minimums, anything less is not guaranteed to work. + # NOTE: make sure that your worker k8s nodes have more RAM than requested here + requests: + memory: 4Gi # 4G is the minimum for MySQL 8.0 to properly function + cpu: 1 + storage: 2Gi + +# Where to expose MySQL client service to outside world +service: + port: 30006 + +# Autoscaling should be used with caution as persistent volume claims will +# linger after scale down +autoscaling: + enabled: false + minReplicas: 3 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 diff --git a/index.yaml b/index.yaml index 4450ef40d..ce2ccba77 100644 --- a/index.yaml +++ b/index.yaml @@ -28885,6 +28885,31 @@ entries: urls: - assets/minio/minio-operator-5.0.6.tgz version: 5.0.6 + mysql-galera: + - annotations: + catalog.cattle.io/certified: partner + catalog.cattle.io/display-name: MySQL Galera Cluster + catalog.cattle.io/kube-version: '>=1.21-0' + catalog.cattle.io/release-name: "" + apiVersion: v2 + appVersion: 8.0.40 + created: "2025-01-28T17:57:58.86749+07:00" + description: A Helm chart for deploying MySQL/Galera cluster in Kubernetes + digest: f635569ce1cad22e3c02ce2f01054bbdb9d2e9b1e519c20df98fea3e77fd0544 + home: https://galeracluster.com + icon: file://assets/icons/mysql-galera.png + keywords: + - mysql + - galera + - cluster + kubeVersion: '>=1.21-0' + name: mysql-galera + sources: + - https://github.com/codership/containers + type: application + urls: + - assets/codership/mysql-galera-0.3.0.tgz + version: 0.3.0 nats: - annotations: catalog.cattle.io/certified: partner diff --git a/packages/codership/mysql-galera/overlay/app-readme.md b/packages/codership/mysql-galera/overlay/app-readme.md new file mode 100644 index 000000000..bea42f640 --- /dev/null +++ b/packages/codership/mysql-galera/overlay/app-readme.md @@ -0,0 +1,20 @@ +# MySQL Galera from Codership + +This is a Helm chart for MySQL Galera from Codership. + +Galera Cluster for MySQL is a true Multi-Master Cluster based on synchronous replication. It’s an easy-to-use, high-availability solution, which provides high system up-time, no data loss and scalability for future growth. + +For documentation, Knowledge Base and Support please visit https://galeracluster.com/ + +* Galera Cluster for MySQL Helm Chart: https://galeracluster.com/2024/10/galera-cluster-for-mysql-helm-chart-for-kubernetes/ +* MySQL Galera Cluster documentation: https://galeracluster.com/library/documentation/index.html + +## Installation +* Plan your cluster capacity. Default is 3 nodes, each with 1 vCPU and 4GB of RAM, the storage is 2GB. It is minimal requirement for Galera to work. +* Consider separate namespace for the MySQL Galera cluster, like `mysql-galera`. +* Install the MySQL Galera chart with desired capacity. + +## Configuration +Sometimes you may want to configure the MySQL Galera cluster with custom values. You can do this by setting the customConfig multiline in values.yaml. + +See the values.yaml file for the full list of configurable parameters. diff --git a/packages/codership/mysql-galera/overlay/questions.yaml b/packages/codership/mysql-galera/overlay/questions.yaml new file mode 100644 index 000000000..fe68541ff --- /dev/null +++ b/packages/codership/mysql-galera/overlay/questions.yaml @@ -0,0 +1,57 @@ +questions: + +- variable: mysql.rootpw + default: "" + required: true + type: password + label: MySQL root Password + group: "Global Cluster Settings" + +- variable: mysql.user.name + default: "" + required: true + type: string + label: MySQL User Name + group: "Global Cluster Settings" + +- variable: mysql.user.passwd + default: "" + required: true + type: password + label: MySQL Password for User + group: "Global Cluster Settings" + +- variable: customConfig + default: "[mysqld]" + required: true + type: multiline + label: Additional custom config for MySQL + group: "Global Cluster Settings" + +- variable: replicas + default: 3 + required: true + type: int + label: The number of replicas + group: "Global Cluster Settings" + +- variable: resources.requests.cpu + default: 1 + required: true + type: int + label: The number of CPU + group: "Global Cluster Settings" + +- variable: resources.requests.memory + default: "4Gi" + required: true + type: string + label: The memory amount for instance + group: "Global Cluster Settings" + +- variable: resources.requests.storage + default: "2Gi" + required: true + type: string + label: The storage space for instance + group: "Global Cluster Settings" diff --git a/packages/codership/mysql-galera/upstream.yaml b/packages/codership/mysql-galera/upstream.yaml new file mode 100644 index 000000000..021a33324 --- /dev/null +++ b/packages/codership/mysql-galera/upstream.yaml @@ -0,0 +1,7 @@ +GitRepo: https://github.com/codership/charts.git +GitBranch: main +GitSubdirectory: mysql-galera +Vendor: Codership Oy +DisplayName: MySQL Galera Cluster +ChartMetadata: + kubeVersion: '>=1.21-0'