DEV Community

Cover image for Deploying MariaDB on Kubernetes
Sanskriti Harmukh for Vultr

Posted on with Aashish Chaurasiya • Originally published at docs.vultr.com

Deploying MariaDB on Kubernetes

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 kubectl configured against it.


Create Persistent Volume and Claim

1. Define a PersistentVolume:

$ nano mariadb-pv.yaml
Enter fullscreen mode Exit fullscreen mode
apiVersion: v1
kind: PersistentVolume
metadata:
    name: mariadb-pv
spec:
    capacity:
        storage: 10Gi
    accessModes:
        - ReadWriteOnce
    persistentVolumeReclaimPolicy: Retain
    hostPath:
        path: /mnt/data/mariadb
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

2. Define a matching PersistentVolumeClaim:

$ nano mariadb-pvc.yaml
Enter fullscreen mode Exit fullscreen mode
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: mariadb-pvc
spec:
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 10Gi
Enter fullscreen mode Exit fullscreen mode
$ kubectl apply -f mariadb-pvc.yaml
$ kubectl get pvc mariadb-pvc
Enter fullscreen mode Exit fullscreen mode

Confirm status is Bound before continuing.


Deploy the MariaDB StatefulSet

1. Create a ConfigMap for my.cnf:

$ nano mariadb-config.yaml
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
$ kubectl apply -f mariadb-config.yaml
Enter fullscreen mode Exit fullscreen mode

2. Create the StatefulSet. Replace strong_password:

$ nano mariadb-statefulset.yaml
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
$ kubectl apply -f mariadb-statefulset.yaml
$ kubectl get statefulset mariadb
$ kubectl get pods -l app=mariadb
Enter fullscreen mode Exit fullscreen mode

Access MariaDB

1. Expose it internally:

$ nano mariadb-service.yaml
Enter fullscreen mode Exit fullscreen mode
apiVersion: v1
kind: Service
metadata:
    name: mariadb
spec:
    ports:
    - port: 3306
      targetPort: 3306
    selector:
        app: mariadb
Enter fullscreen mode Exit fullscreen mode
$ kubectl apply -f mariadb-service.yaml
$ kubectl get svc mariadb
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
mysql> show databases;
mysql> exit;
Enter fullscreen mode Exit fullscreen mode

Scale the Deployment

$ kubectl scale statefulset mariadb --replicas=3
$ kubectl get statefulset mariadb
$ kubectl get pods -l app=mariadb
Enter fullscreen mode Exit fullscreen mode

Scale back down:

$ kubectl scale statefulset mariadb --replicas=2
Enter fullscreen mode Exit fullscreen mode

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 hostPath PV 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)