MariaDB is a popular open-source relational database. Running it on Kubernetes gets you portability across environments, CI/CD integration, and automated backup/recovery alongside the usual scalability and high-availability benefits. This guide sets up persistent storage, deploys MariaDB as a StatefulSet, exposes it via a Service, and covers scaling.
Prerequisites: a Kubernetes cluster with at least 3 nodes and
kubectlconfigured against it.
Create Persistent Volume and Claim
1. Define a PersistentVolume:
$ nano mariadb-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mariadb-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /mnt/data/mariadb
Retain keeps the data if the PV is deleted; hostPath backs it with a directory on the node.
$ kubectl apply -f mariadb-pv.yaml
$ kubectl get pv mariadb-pv
2. Define a matching PersistentVolumeClaim:
$ nano mariadb-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
$ kubectl apply -f mariadb-pvc.yaml
$ kubectl get pvc mariadb-pvc
Confirm status is Bound before continuing.
Deploy the MariaDB StatefulSet
1. Create a ConfigMap for my.cnf:
$ nano mariadb-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mariadb-config
data:
my.cnf: |
[mysqld]
bind-address=0.0.0.0
default_storage_engine=InnoDB
innodb_file_per_table=1
max_connections=1000
$ kubectl apply -f mariadb-config.yaml
2. Create the StatefulSet. Replace strong_password:
$ nano mariadb-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mariadb
spec:
serviceName: "mariadb"
replicas: 1
selector:
matchLabels:
app: mariadb
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb
image: mariadb:latest
ports:
- containerPort: 3306
name: mariadb
env:
- name: MYSQL_ROOT_PASSWORD
value: "strong_password"
volumeMounts:
- name: mariadb-storage
mountPath: /var/lib/mysql
- name: config-volume
mountPath: /etc/mysql/conf.d
volumes:
- name: config-volume
configMap:
name: mariadb-config
volumeClaimTemplates:
- metadata:
name: mariadb-storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
$ kubectl apply -f mariadb-statefulset.yaml
$ kubectl get statefulset mariadb
$ kubectl get pods -l app=mariadb
Access MariaDB
1. Expose it internally:
$ nano mariadb-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mariadb
spec:
ports:
- port: 3306
targetPort: 3306
selector:
app: mariadb
$ kubectl apply -f mariadb-service.yaml
$ kubectl get svc mariadb
2. Connect with a throwaway client pod:
$ kubectl run -it --rm --image=mysql:latest --restart=Never mysql-client -- mysql -h mariadb -u root -pstrong_password
mysql> show databases;
mysql> exit;
Scale the Deployment
$ kubectl scale statefulset mariadb --replicas=3
$ kubectl get statefulset mariadb
$ kubectl get pods -l app=mariadb
Scale back down:
$ kubectl scale statefulset mariadb --replicas=2
Each replica in this setup is an independent MariaDB instance with its own PVC — for real multi-node replication, layer in MariaDB Galera or MaxScale rather than relying on StatefulSet scaling alone.
Next Steps
MariaDB is running on Kubernetes with persistent storage and a scalable StatefulSet. From here:
- Swap the
hostPathPV for a CSI-backed StorageClass in production so pods can reschedule across nodes - Add readiness/liveness probes on port 3306 for better failure detection
- Front the service with an external LoadBalancer or Ingress if clients outside the cluster need access
For the full guide, visit the original article on Vultr Docs.
Top comments (0)