How to deploy MySQL on Kubernetes Cluster ?

Pre-Requisite

  1. kubernetes cluster is ready if not Follow this blog.
kubectl get nodes -o wide

OUTPUT

NAME        STATUS   ROLES           AGE     VERSION    INTERNAL-IP    EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION         CONTAINER-RUNTIME
kubmaster   Ready    control-plane   5h26m   v1.28.15   192.168.10.6   <none>        Debian GNU/Linux 12 (bookworm)   6.1.0-32-cloud-amd64   containerd://1.7.27
kubnode1    Ready    <none>          5h3m    v1.28.15   192.168.10.5   <none>        Debian GNU/Linux 12 (bookworm)   6.1.0-35-cloud-amd64   containerd://1.7.27
kubnode2    Ready    <none>          5h2m    v1.28.15   192.168.10.7   <none>        Debian GNU/Linux 12 (bookworm)   6.1.0-35-cloud-amd64   containerd://1.7.27

Create Namespace (Optoinal)

Create file kamailio-namespace.yaml

vim kamailio-namespace.yaml

paste the following content

# kamailio-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: kamailio

Apply It

kubectl apply -f kamailio-namespace.yaml

Create Physical Volume for MySQL Database

create file mysql-pv.yaml

vim mysql-pv.yaml

paste the following content in the file

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
  namespace: kamailio
spec:
  storageClassName: manual
  capacity:
    storage: 3Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data/mysql"

apply it

kubectl apply -f mysql-pv.yaml

confirmation command

kubectl get pv -A
NAME       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
mysql-pv   3Gi        RWO            Retain           Available    kamailio/mysql-pvc   manual                  5h16m

Important

Status must be Available

Create ConfigMap

create file mysql-configmap.yaml

vim mysql-configmap.yaml

paste the following content in the file

# mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-config
  namespace: kamailio
data:
  my.cnf: |
    [mysqld]
    default-authentication-plugin=mysql_native_password
    skip-name-resolve
    max_connections=1000

Create Secret File

create file mysql-secret.yaml

vim mysql-secret.yaml

copy and paste the following content in the file

# mysql-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secrets
  namespace: kamailio
type: Opaque
data:
  mysql-root-password: MTIzNDU2Nw==
  mysql-password: MTIzNDU2Nw==

password must be base64 encrypted

echo -n 1234567 | base64 

OUTPUT

MTIzNDU2Nw==

Create a PersistentVolumeClaim for MySQL Data

create file mysql-pvc.yaml

vim mysql-pvc.yaml

copy and paste the following content in the file

# mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  namespace: kamailio
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi

create the MySQL Deployment

create file mysql-deployment.yaml

vim mysql-deployment.yaml

copy and paste the following content in the file

# mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: kamailio
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: mysql-root-password
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secrets
              key: mysql-password
        - name: MYSQL_USER
          value: "kamailio"
        - name: MYSQL_DATABASE
          value: "kamailio"
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
        - name: mysql-config
          mountPath: /etc/mysql/conf.d
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pvc
      - name: mysql-config
        configMap:
          name: mysql-config

Create MySQL Service

create file mysql-service.yaml

vim mysql-service.yaml

copy and paste the following content in the file

apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: kamailio
spec:
  type: NodePort
  ports:
  - port: 3306
    targetPort: 3306
    nodePort: 30306
  selector:
    app: mysql

Apply all of the files

kubectl apply -f mysql-configmap.yaml -f mysql-secret.yaml -f mysql-pvc.yaml -f mysql-deployment.yaml -f mysql-service.yaml

Check the pod

kubectl get pods -n kamailio

OUTPUT

NAMESPACE         NAME                                       READY   STATUS    RESTARTS   AGE
kamailio          mysql-d4b767577-58v2n                      1/1     Running   0          5h15m

Check PV Status

kubectl get pv -A

OUTPUT

NAME       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
mysql-pv   3Gi        RWO            Retain           Bound    kamailio/mysql-pvc   manual                  8m42s

Confirm nameserver IP

kubectl -n kamailio exec -it mysql-5448dbc87f-5gm97 -- cat /etc/resolv.conf

OUTPUT

search kamailio.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5

Add Port Forwarding

kubectl port-forward --address 192.168.10.6 pod/mysql-d4b767577-58v2n -n kamailio 3306:3306

This command will start listening on master node IP 192.168.10.6:3306 and forward all traffic to mysql pod port 3306.

Enjoy 😉

How to deploy MySQL on Kubernetes Cluster ?

Pre-Requisite kubernetes cluster is ready if not Follow  this  blog. kubectl get nodes -o wide OUTPUT NAME STATUS ROLES A...