Introduction
As the most popular content management system globally, WordPress runs websites of various sizes, both in terms of the amount of content and web traffic. Deploying WordPress on Kubernetes is an efficient way to enable horizontal scaling of a website and successfully handle website traffic surges.
This tutorial explains two methods of deploying WordPress on Kubernetes - using Helm charts and creating your deployment from scratch.
Prerequisites
Deploying WordPress on Kubernetes with a Helm Chart
Helm charts come with pre-configured app installations that can be deployed with a few simple commands.
- Add the repository containing the WordPress Helm chart you want to deploy:
helm repo add [repo-name] [repo-address]
The system confirms the successful addition of the repository. The example uses the Bitnami chart.
2. Update local Helm repositories:
helm repo update
3. Install the chart using the helm install command.
helm install [release-name] [repo-address]
Wait for the chart to be deployed.
4. The WordPress service uses LoadBalancer as a way to expose the service. If you are using minikube, open another terminal window and type the following command to emulate the LoadBalancer:
minikube tunnel
5. When minikube displays the Running status, minimize the window and return to the previous one.
6. Check the readiness of the deployment by typing:
kubectl get all
The command lists and shows status of the pods, services, and deployments.
7. Once the pods and the deployment are ready, use the following command to export the SERVICE_IP
environment variable:
export SERVICE_IP=$(kubectl get svc --namespace default wp-test-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
8. Now use the echo command to display the IP address of the service:
echo "WordPress URL: http://$SERVICE_IP/"
9. Type the address into the address bar of your browser. The WordPress installation starts.
Deploying WordPress on Kubernetes with Persistent Volumes
When deploying WordPress using a custom configuration, you need to create a series of YAML files for WordPress and the database the app will be using. The example below uses MySQL, but you can also opt for MariaDB.
1. Use a text editor to create the YAML file to provision storage for the MySQL database.
nano mysql-storage.yaml
The file defines a persistent storage volume (PV) and claims that storage with the PersistentVolumeClaim (PVC). The example uses the following configuration:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Save the file and exit.
2. Create the MySQL deployment configuration YAML.
nano mysql-deployment.yaml
The deployment file contains the data related to the container image and the storage. The claimName
declaration at the bottom should correspond to the name of the PVC you created in Step 1.
apiVersion: apps/v1
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.7
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
Save the file and exit.
Note: Learn how to deploy a MySQL database instance on Kubernetes using persistent volumes.
3. Create the service configuration YAML for the database.
nano mysql-service.yaml
The file specifies the port that WordPress uses to connect to the service:
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
Save the file and exit.
4. Now create the same YAML files for WordPress itself. Start with the storage allocation:
nano wordpress-storage.yaml
The example uses the following configuration:
apiVersion: v1
kind: PersistentVolume
metadata:
name: wp-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Save the file and exit.
5. Create the deployment file:
nano wordpress-deployment.yaml
The file provides the Docker image and connects the WordPress deployment with the PVC:
apiVersion: apps/v1
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:5.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
Save the file and exit.
6. Create the service YAML:
nano wordpress-service.yaml
The example uses LoadBalancer to expose the service:
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
Save the file and exit.
7. Create the kustomization.yaml file, which will be used to apply the configuration easily:
nano kustomization.yaml
The file contains two parts:
secretGenerator
produces the Kubernetes secret that passes the login info to the containers.resources
section lists all the files that will participate in configuration. List the files you created in previous steps.
secretGenerator:
- name: mysql-pass
literals:
- password=test123
resources:
- mysql-storage.yaml
- mysql-deployment.yaml
- mysql-service.yaml
- wordpress-storage.yaml
- wordpress-deployment.yaml
- wordpress-service.yaml
Save the file and exit.
8. Apply the files listed in kustomization.yaml with the following command:
kubectl apply -k ./
The system confirms the successful creation of the secret, services, PVs, PVCs, and deployments:
9. Check if the pods and the deployments are ready:
kubectl get all
10. If you use minikube, open another terminal window and start minikube tunnel to provide load balancing emulation:
minikube tunnel
Once the emulation is running, minimize the window and return to the previous one.
11. Type the following command to expose the service URL that you will use to access the deployed WordPress instance:
minikube service wordpress-service --url
The URL is displayed as the command output:
Note: If you do not use minikube, use the external IP address and the port of the WordPress service from the table in Step 9.
12. Copy the URL and paste it into your web browser. The WordPress installation starts.
Conclusion
After reading this tutorial, you will learn two methods for deploying a WordPress instance on Kubernetes. If you want to know more about managing WordPress, read 25 Performance and Optimization Tips to Speed Up Your WordPress.