A step by step guide to deploying WordPress on Kubernetes provided by the KataCoda website. Please note that this shouldn’t be used for a production deployment and should only be used for learning and/or practice.
Create a Secret for the MySQL Password
The first step is to create a secret that can be used to store the MySQL database password. Later in the deployment this will be used in creating the MySQL database pod and then used by the WordPress pod to connect to the database.
First base64 encode the password.
echo 'my-password' | base64
Copy the output and place it in the secrets.yaml file.
apiVersion: v1
data:
password: bXktcGFzc3dvcmQK
kind: Secret
metadata:
name: mysql-pass
namespace: default
type: Opaque
Once the file is created, apply it to create the secret.
kubectl apply -f secrets.yaml
Create a Storage Class
Both MySQL and WordPress need a persistent data store in order to preserve data through restarts, rescheduling or any other Pod disruptions.
Create the following storageclass.yaml on the server.
storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: manual
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
Next apply it to create the StorageClass.
kubectl apply -f storageclass.yaml
Create Persistent Volumes
In this step some two PersistentVolume(s) are created. One for each of MySQL and WordPress.
mysql-persistentvolume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
hostPath:
type: ""
path: /wordpress/mysql
kubectl apply -f worpdress-persistentvolume.yaml
wordpress-persistentvolume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: wp-pv-claim
spec:
storageClassName: manual
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /wordpress/wordpress
kubectl apply -f worpdress-persistentvolume.yaml
Deploy MySQL
Now it’s time to deploy the MySQL Pod.
First create a PersistentVolumeClaim, which is a request to use the storage created in the following step. Hopefully, the persistent volume is feeling generous and let’s us use it.
mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: manual
kubectl apply -f mysql-pvc.yaml
On to the Pod, for this step deploy MySQL. In this case using a deployment, however, it’s only going to have a replicaset with one Pod. So it’s not very good for High Availability (HA) or production use. Just for learning/practice purposes.
mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_DATABASE
value: wordpress
- 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
Create the deployment which in turn should create the Pod, it may take a few minutes to pull down the image and get things running, so be patient.
kubectl apply -f mysql-deployment.yaml
We have MySQL running in a Pod at this point! However, it’s not possible to reach it. In order to access it a service needs to be created. This will expose MySQL port 3306 to the local Kubernetes cluster.
mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
kubectl apply -f mysql-service.yaml
Deploy WordPress
Almost there now! Just have to deploy WordPress.
The first step is to create a persistent volume claim so WordPress has some where to keep its files.
wordpress-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: manual
kubectl apply -f wordpress-pvc.yaml
Next create the WordPress deployment that will create a replicaset and one Pod (again, this is only for learning/practice purposes).
wordpress-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: wordpress:latest
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_NAME
value: wordpress
- 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
Apply the deployment yaml to create the Pod.
kubectl apply -f wordpress-deployment.yaml
Finally! Create a service to expose WordPress to an external loadbalancer so it’s possible to access from a remote browser.
wordpress-service.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
nodePort: 30080
selector:
app: wordpress
tier: frontend
type: NodePort
kubectl apply -f wordpress-service.yaml