Cloud Native 6 min read

Deploying MySQL with ConfigMap, Service, and StatefulSet on Kubernetes (NFS Persistent Storage)

This guide demonstrates how to deploy a MySQL cluster on Kubernetes using NFS persistent storage, ConfigMap for configuration, Service for access, and a StatefulSet to manage multiple replicas with init containers and volume claims.

Practical DevOps Architecture
Practical DevOps Architecture
Practical DevOps Architecture
Deploying MySQL with ConfigMap, Service, and StatefulSet on Kubernetes (NFS Persistent Storage)

This guide shows how to deploy a MySQL cluster on Kubernetes using NFS for persistent storage, with ConfigMap, Service, and StatefulSet resources.

First, create a ConfigMap (mysql-configmap.yaml) containing master.cnf and slave.cnf:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  master.cnf: |
    [mysqld]
    log-bin
  slave.cnf: |
    [mysqld]
    super-read-only

Next, define two Services (mysql and mysql-read) to expose the primary and read‑only endpoints:

apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
    clusterIP: None
  selector:
    app: mysql
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-read
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  selector:
    app: mysql

Then create a StatefulSet (mysql-statefulset.yaml) that runs three MySQL replicas, mounts the ConfigMap and NFS volume, and includes init containers for configuration and data cloning:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql
  replicas: 3
  template:
    metadata:
      labels:
        app: mysql
    spec:
      initContainers:
      - name: init-mysql
        image: mysql:5.7
        command:
        - bash
        - "-c"
        - |
          set -ex
          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
          ordinal=${BASH_REMATCH[1]}
          echo [mysqld] > /mnt/conf.d/server-id.cnf
          echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
          if [[ $ordinal -eq 0 ]]; then
            cp /mnt/config-map/master.cnf /mnt/conf.d/
          else
            cp /mnt/config-map/slave.cnf /mnt/conf.d/
          fi
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ALLOW_EMPTY_PASSWORD
          value: "1"
        ports:
        - name: mysql
          containerPort: 3306
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
        livenessProbe:
          exec:
            command: ["mysqladmin","ping"]
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command: ["mysql","-h","127.0.0.1","-e","SELECT 1"]
          initialDelaySeconds: 5
          periodSeconds: 2
          timeoutSeconds: 1
      volumes:
      - name: conf
        emptyDir: {}
      - name: config-map
        configMap:
          name: mysql
      volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          storageClassName: "managed-nfs-storage"
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 10Gi

Apply all manifests with kubectl apply -f . and verify the pods are running using kubectl get pods -l app=mysql --watch .

Cloud NativeKubernetesMySQLStatefulSetNFSConfigMap
Practical DevOps Architecture
Written by

Practical DevOps Architecture

Hands‑on DevOps operations using Docker, K8s, Jenkins, and Ansible—empowering ops professionals to grow together through sharing, discussion, knowledge consolidation, and continuous improvement.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.