Wednesday, 15 October 2025

Deploy MySQL on Kubernetes: Persistent Storage, Secrets & NodePort Access

Our course you can check :-   Udemy course  


Ques:-  

A new MySQL server needs to be deployed on Kubernetes cluster. DevOps team was working on to gather the requirements. Recently they were able to finalize the requirements and shared them with the team members to start working on it. Below you can find the details:

1.) Create a PersistentVolume mysql-pv, its capacity should be 250Mi, set other parameters as per your preference.

2.) Create a PersistentVolumeClaim to request this PersistentVolume storage. Name it as mysql-pv-claim and request a 250Mi of storage. Set other parameters as per your preference.

3.) Create a deployment named mysql-deployment, use any mysql image as per your preference. Mount the PersistentVolume at mount path /var/lib/mysql.

4.) Create a NodePort type service named mysql and set nodePort to 30007.

5.) Create a secret named mysql-root-pass having a key pair value, where key is password and its value is YUIidhb667, create another secret named mysql-user-pass having some key pair values, where frist key is username and its value is kodekloud_pop, second key is password and value is 8FmzjvFU6S, create one more secret named mysql-db-url, key name is database and value is kodekloud_db3

6.) Define some Environment variables within the container:

a) name: MYSQL_ROOT_PASSWORD, should pick value from secretKeyRef name: mysql-root-pass and key: password

b) name: MYSQL_DATABASE, should pick value from secretKeyRef name: mysql-db-url and key: database

c) name: MYSQL_USER, should pick value from secretKeyRef name: mysql-user-pass key key: username

d) name: MYSQL_PASSWORD, should pick value from secretKeyRef name: mysql-user-pass and key: password


Ans:-

Here’s the complete set of Kubernetes YAML manifests to fulfill the MySQL deployment requirements you described:


raj@jumphost ~$ cat pod.yaml


---

#PersistentVolume (PV)

apiVersion: v1

kind: PersistentVolume

metadata:

  name: mysql-pv

spec:

  capacity:

    storage: 250Mi

  accessModes:

    - ReadWriteOnce

  persistentVolumeReclaimPolicy: Retain

  hostPath:

    path: /mnt/data/MySQL


---

#PersistentVolumeClaim (PVC)

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: mysql-pv-claim

spec:

  accessModes:

    - ReadWriteOnce

  resources:

    requests:

      storage: 250Mi


---

#Secrets

apiVersion: v1

kind: Secret

metadata:

  name: mysql-root-pass

type: Opaque

data:

  password: WVVJaWRoYjY2Nw==  # Base64 encoded value of YUIidhb667


---

apiVersion: v1

kind: Secret

metadata:

  name: mysql-user-pass

type: Opaque

data:

  username: a29kZWtsb3VkX3BvcA==  # Base64 encoded value of kodekloud_pop

  password: OEZtenp2RlU2Uw==      # Base64 encoded value of 8FmzjvFU6S


---

apiVersion: v1

kind: Secret

metadata:

  name: mysql-db-url

type: Opaque

data:

  database: a29kZWtsb3VkX2RiMw==  # Base64 encoded value of kodekloud_db3


---

#MySQL Deployment

apiVersion: apps/v1

kind: Deployment

metadata:

  name: mysql-deployment

spec:

  replicas: 1

  selector:

    matchLabels:

      app: mysql

  template:

    metadata:

      labels:

        app: mysql

    spec:

      containers:

      - name: mysql

        image: mysql:5.7

        ports:

        - containerPort: 3306

        env:

        - name: MYSQL_ROOT_PASSWORD

          valueFrom:

            secretKeyRef:

              name: mysql-root-pass

              key: password

        - name: MYSQL_DATABASE

          valueFrom:

            secretKeyRef:

              name: mysql-db-url

              key: database

        - name: MYSQL_USER

          valueFrom:

            secretKeyRef:

              name: mysql-user-pass

              key: username

        - name: MYSQL_PASSWORD

          valueFrom:

            secretKeyRef:

              name: mysql-user-pass

              key: password

        volumeMounts:

        - name: mysql-storage

          mountPath: /var/lib/mysql

      volumes:

      - name: mysql-storage

        persistentVolumeClaim:

          claimName: mysql-pv-claim


---

#MySQL NodePort Service

apiVersion: v1

kind: Service

metadata:

  name: mysql

spec:

  type: NodePort

  selector:

    app: mysql

  ports:

  - port: 3306

    targetPort: 3306

    nodePort: 30007


raj@jumphost ~$ kubectl apply -f pod.yaml 

persistentvolume/mysql-pv created

persistentvolumeclaim/mysql-pv-claim created

secret/mysql-root-pass created

secret/mysql-user-pass created

secret/mysql-db-url created

deployment.apps/mysql-deployment created

service/mysql created


raj@jumphost ~$ kubectl get all

NAME                                    READY   STATUS    RESTARTS   AGE

pod/mysql-deployment-6fb8c46c45-mcs74   1/1     Running   0          3m10s


NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE

service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          28m

service/mysql        NodePort    10.96.142.199   <none>        3306:30007/TCP   3m10s


NAME                               READY   UP-TO-DATE   AVAILABLE   AGE

deployment.apps/mysql-deployment   1/1     1            1           3m10s


NAME                                          DESIRED   CURRENT   READY   AGE

replicaset.apps/mysql-deployment-6fb8c46c45   1         1         1       3m10s


raj@jumphost ~$ kubectl get secret

NAME              TYPE     DATA   AGE

mysql-db-url      Opaque   1      32s

mysql-root-pass   Opaque   1      32s

mysql-user-pass   Opaque   2      32s


raj@jumphost ~$ kubectl get pvc

NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE

mysql-pv-claim   Bound    pvc-ef9dcc3e-94d0-4403-a3c8-a0714974acfe   250Mi      RWO            standard       38s


raj@jumphost ~$ kubectl get pv

NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                    STORAGECLASS   REASON   AGE

mysql-pv                                   250Mi      RWO            Retain           Available                                                    59s

pvc-ef9dcc3e-94d0-4403-a3c8-a0714974acfe   250Mi      RWO            Delete           Bound       default/mysql-pv-claim   standard                56s

raj@jumphost ~$ 


Conclusion:-

In this practical Kubernetes tutorial, you'll learn how to deploy a MySQL server with secure credentials, persistent storage, and external access via NodePort. This video is ideal for DevOps engineers, cloud architects, and developers who want to understand how to manage stateful applications in Kubernetes.

What you'll learn:

  • Creating a PersistentVolume and PersistentVolumeClaim for MySQL data
  • Using Kubernetes Secrets to securely manage MySQL credentials
  • Deploying MySQL with environment variables sourced from secrets
  • Mounting volumes for data persistence
  • Exposing MySQL using a NodePort service for external access

By the end of this video, you'll have a fully functional MySQL deployment running in your Kubernetes cluster, ready for development or testing environments.

No comments:

Post a Comment