Deploying WordPress and MySQL with durable storage in a K8S cluster (Terraform/Minikube/AWS/MySQL/Wordpress)

ashima chopra
3 min readFeb 4, 2021

Deploying a WordPress site and a MySQL database using Minikube. Both applications use PersistentVolumes and PersistentVolumeClaims to store data.

Minikube is a tool that lets you run Kubernetes locally, it runs a single-node Kubernetes cluster on your personal computer (including Windows, macOS and Linux PCs) so that you can try out Kubernetes, or for daily development work.

A PersistentVolume (PV) is a piece of storage in the cluster that has been manually provisioned by an administrator, or dynamically provisioned by Kubernetes using a StorageClass.

A PersistentVolumeClaim (PVC) is a request for storage by a user that can be fulfilled by a PV. PersistentVolumes and PersistentVolumeClaims are independent from Pod life cycles and preserve data through restarting, rescheduling, and even deleting Pods.

FOLLOWING ARE THE STEPS TO ACHIEVE THE TARGET:

  1. Create a yaml file (pvc.yml) for pvc with ReadWriteOnce as the access mode and 10Gi as permanent storage space from the central storage
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysqlpvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests: 10Gi

2. Create a yaml file (wp.yml) for the replica set so as when the system crashes and pods get deleted another replica of the same pod is launched automatically for wordpress.

apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: wprs1
spec:
replicas: 1
selector:
matchLabels:
env: dev
app: wp
template:
metadata:
name: wppod1
labels:
env: dev
app: wp
spec:
containers:
- name: "wpcon1"

3. Create a yaml file (mysql.yml) for the replica set so as when the system crashes and pods get deleted another replica of the same pod is launched automatically for mysql.

apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: mysqlrs1
spec:
replicas: 1
selector:
matchLabels:
env: dev
template:
metadata:
name: mysqlpod1
labels:
env: dev
spec:
containers:
- name: "mysqlcon1"
image: "mysql:5.6"
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysqlsecret
key: rpass
- name: MYSQL_DATABASE
value: mylwdb
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mysqlsecret
key: username
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysqlsecret
key: vpass
volumeMounts:
- name: web-vol1
mountPath: /var/lib/mysql
volumes:
- name: web-vol1
persistentVolumeClaim:

4. Create a yaml file for the deployment of mysql with no connectivity with outside world.

apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim

5. Create a yaml file for the deployment of wordpress with load balancer as service

apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim

6. A secret file to save key-value pairs.

apiVersion: v1
kind: Secret
metadata:
name: mysqlsecret
data:
username: ##
vpass: ##

7. A kustomization file to be created for the complete deployment and run with the command

>kubectl create -k .apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: mysql-pass
literals:
- password=redhat
resources:
- mysql_deployment.yaml
- wordpress_deployment.yaml

We can get the url of our site by running the following command:

minikube service wordpress --url

The end result should somewhat look like this

--

--