Deploy MySQL Primary‑Replica on Kubernetes with Helm and Persistent Volumes
This guide walks through deploying a MySQL primary‑replica cluster on Kubernetes using Helm charts, configuring persistent volumes, exposing services, and adding Prometheus and Grafana monitoring, while also covering installation, testing, and clean‑up steps.
Overview
MySQL is a widely used relational database system. Deploying MySQL on Kubernetes provides resource isolation, dynamic scaling, environment consistency, and easier operations.
Advantages of MySQL on Kubernetes
Resource isolation
Dynamic elastic scaling
Environment consistency
Operational convenience
Step‑by‑Step Deployment (One Primary, Two Replicas)
1) Add Helm Repository
helm repo add bitnami https://charts.bitnami.com/bitnami
helm pull bitnami/mysql
tar -xf mysql-9.3.3.tgz2) Modify Configuration
Edit mysql/values.yaml to set the image registry, repository, tag, and replication architecture. Example snippets:
image:
registry: myharbor.com
repository: bigdata/mysql
tag: 8.0.30-debian-11-r15
architecture: replication
primary:
persistence:
enabled: true
size: 10Gi
storageClass: "mysql-local-storage"
local:
- name: mysql-0
host: "local-168-182-110"
path: "/opt/bigdata/servers/mysql/data/data1"
service:
type: NodePort
nodePorts:
mysql: "30306"
secondary:
replicaCount: 2
persistence:
enabled: true
size: 10Gi
storageClass: "mysql-local-storage"
local:
- name: mysql-1
host: "local-168-182-111"
path: "/opt/bigdata/servers/mysql/data/data1"
- name: mysql-2
host: "local-168-182-112"
path: "/opt/bigdata/servers/mysql/data/data1"
service:
type: NodePort
nodePorts:
mysql: "30307"
metrics:
enabled: true
image:
registry: myharbor.com
repository: bigdata/mysqld-exporter
tag: 0.14.0-debian-11-r333) Create PersistentVolume Definitions
{{- range .Values.primary.persistence.local }}
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: {{ .name }}
labels:
name: {{ .name }}
spec:
storageClassName: {{ $.Values.primary.persistence.storageClass }}
capacity:
storage: {{ $.Values.primary.persistence.size }}
accessModes:
- ReadWriteOnce
local:
path: {{ .path }}
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- {{ .host }}
{{- end }}
{{- range .Values.secondary.persistence.local }}
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: {{ .name }}
labels:
name: {{ .name }}
spec:
storageClassName: {{ $.Values.secondary.persistence.storageClass }}
capacity:
storage: {{ $.Values.secondary.persistence.size }}
accessModes:
- ReadWriteOnce
local:
path: {{ .path }}
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- {{ .host }}
{{- end }}4) Define StorageClass
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: {{ .Values.primary.persistence.storageClass }}
provisioner: kubernetes.io/no-provisioner5) Install the Chart
# Create persistent directories on the host
mkdir -p /opt/bigdata/servers/mysql/data/data1
# Pull and push custom images to the private registry
docker pull docker.io/bitnami/mysql:8.0.30-debian-11-r15
docker tag docker.io/bitnami/mysql:8.0.30-debian-11-r15 myharbor.com/bigdata/mysql:8.0.30-debian-11-r15
docker push myharbor.com/bigdata/mysql:8.0.30-debian-11-r15
docker pull docker.io/bitnami/mysqld-exporter:0.14.0-debian-11-r33
docker tag docker.io/bitnami/mysqld-exporter:0.14.0-debian-11-r33 myharbor.com/bigdata/mysqld-exporter:0.14.0-debian-11-r33
docker push myharbor.com/bigdata/mysqld-exporter:0.14.0-debian-11-r33
# Install the Helm chart
helm install mysql ./mysql -n mysql --create-namespaceInstallation Notes
NAME: mysql
LAST DEPLOYED: Mon Sep 19 23:57:18 2022
NAMESPACE: mysql
STATUS: deployed
REVISION: 1
CHART: mysql
CHART VERSION: 9.3.3
APP VERSION: 8.0.30
# Watch deployment status
kubectl get pods -w --namespace mysql
# Service endpoints
Primary: mysql-primary.mysql.svc.cluster.local:3306
Secondary: mysql-secondary.mysql.svc.cluster.local:3306
# Retrieve root password
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace mysql mysql -o jsonpath="{.data.mysql-root-password}" | base64 -d)
# Connect using a temporary client pod
kubectl run mysql-client --rm -it --restart='Never' \
--image=myharbor.com/bigdata/mysql:8.0.30-debian-11-r15 \
--namespace mysql \
--env MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD -- bash
# Primary (read/write)
mysql -h mysql-primary.mysql.svc.cluster.local -uroot -p"$MYSQL_ROOT_PASSWORD"
# Secondary (read‑only)
mysql -h mysql-secondary.mysql.svc.cluster.local -uroot -p"$MYSQL_ROOT_PASSWORD"6) Prometheus Monitoring
Expose the MySQL exporter service and scrape metrics:
# Port‑forward the metrics endpoint
kubectl port-forward --namespace mysql svc/mysql-metrics 9104:9104 &
curl http://127.0.0.1:9104/metricsGrafana can be configured to import a MySQL dashboard (e.g., ID 7362) from https://grafana.com/grafana/dashboards/ . Admin credentials are admin and the password can be obtained with:
kubectl get secret --namespace grafana grafana -o jsonpath="{.data.admin-password}" | base64 --decode7) Uninstall
helm uninstall mysql -n mysql
kubectl delete pod -n mysql $(kubectl get pod -n mysql -o name | cut -d'/' -f2) --force
kubectl patch ns mysql -p '{"metadata":{"finalizers":null}}'
kubectl delete ns mysql --forceConclusion
The guide demonstrates a basic MySQL primary‑replica deployment on Kubernetes without high‑availability features. While production‑grade HA solutions exist, they are not covered here. The setup is suitable for metadata storage in big‑data environments where occasional primary failures have limited impact. Future work may explore true HA implementations for MySQL on Kubernetes.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
