Introduction:
WordPress is a popular Content Management System (CMS) that allows you to create and manage websites easily. Kubernetes is a powerful container orchestration platform that can help you deploy and manage WordPress with high availability and scalability.
This guide will walk you through setting up WordPress on a Kubernetes cluster using a MySQL StatefulSet for database storage. We will provide you with the necessary deployment files, secret files, Persistent Volume (PV) and Persistent Volume Claim (PVC) files, and service files to get you started.
Prerequisites:
Before we dive into setting up WordPress on Kubernetes, you’ll need the following prerequisites:
- A running Kubernetes cluster.
kubectl
command-line tool configured to interact with your Kubernetes cluster.- Helm, a package manager for Kubernetes. You can install Helm by following the official documentation: https://helm.sh/docs/intro/install/ — Optional (for this example not needed)
Step 1: Create MySQL StatefulSet
We will begin by creating a MySQL StatefulSet. Save the following content to a file named mysql-statefulset.yaml
:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
labels:
app: mysql
spec:
replicas: 1
serviceName: mysql
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: database
image: mysql:5.7
args:
- "--ignore-db-dir=lost+found"
envFrom:
- secretRef:
name: mysql-secret
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumes:
- name: mysql-data
persistentVolumeClaim:
claimName: mysql-pvc
This YAML file defines a MySQL StatefulSet with a single replica, using a Persistent Volume Claim (PVC) for data storage. The MySQL root password is fetched from a secret named mysql-secret
.
Step2: Create Mysql Service
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
ports:
- port: 3306
protocol: TCP
selector:
app: mysql
Mysql service file is the type of “ClusterIP” because this is for internal communication between MySQL and WordPress
Step 3: Create WordPress Deployment and Service
Now, create a WordPress Deployment YAML file. Save the following content to a file named wordpress-deployment.yaml
: Here you have deployment and service files
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
spec:
replicas: 2
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress:5.8.3-php7.4-apache
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-data
mountPath: /var/www/html
env:
- name: WORDPRESS_DB_HOST
value: mysql-service.default.svc.cluster.local
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: MYSQL_ROOT_PASSWORD
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_NAME
value: mysql
volumes:
- name: wordpress-data
persistentVolumeClaim:
claimName: wordpress-pvc
---
kind: Service
apiVersion: v1
metadata:
name: wordpress-service
spec:
type: NodePort
selector:
app: wordpress
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 30007
In this YAML file, we define a WordPress Deployment with two replicas and a corresponding Service to expose WordPress to the outside world with NodePort. You can use the Service type as “LoadBalancer” as well. It uses the MySQL StatefulSet as the database host.
Step 4: Create a Secret for MySQL Password
Create a Secret to securely store the MySQL root password. Save the following content to a file named mysql-secret.yaml
:
- First, you have to encode your password with BASE64. Example command is
#echo "mypassword" | base64
- To decode the password you can run the following command:
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
MYSQL_ROOT_PASSWORD: bXlwYXNzd29yZAo=
Step 5: Create Persistent Volume and Persistent Volume Claim for MySQL and WordPress
To ensure data persistence for both MySQL and WordPress, create Persistent Volumes and Persistent Volume Claims. Create a file named mysql-pv-pvc.yaml
with the following content:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data/mysql
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
selector:
matchLabels:
app: mysql
This YAML file defines a Persistent Volume and a Persistent Volume Claim for MySQL. Ensure the hostPath
in the Persistent Volume definition points to a suitable directory on your Kubernetes nodes.
apiVersion: v1
kind: PersistentVolume
metadata:
name: wordpress-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /home/ubuntu/project/wp-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: manual
For this YAML file, we have defined the “/home/ubuntu/project/wp-data” directory to mount with volume
Step 6: Apply the Configurations
Apply the configurations to your Kubernetes cluster using the following commands:
kubectl apply -f mysql-secret.yaml
kubectl apply -f mysql-pv-pvc.yaml
kubectl apply -f mysql-statefulset.yaml
kubectl apply -f mysql-service.yaml
kubectl apply -f wordpress-pv-pvc.yaml
kubectl apply -f wordpress-deployment.yaml
If can apply your all configuration files at a time as well by calling your directory like:
# kubectl apply -f directory_name
Step 6: Access Your WordPress Site
To access your WordPress site, obtain the external IP address of the WordPress Service with the following command:
kubectl get svc wordpress-service
Once you have the external IP address, you can access your WordPress site by navigating to that IP address in your web browser.