WordPress is well-known as one of the most popular blogging tools. It uses relational database to store the contents: articles, involved metadata while PersistentVolume (PV) and PersistentVolumeClaim (PVC) store assets data.
This tutorial will show you the way to install a single replica of a WordPress site using MySQL database on Kubernetes on Linode.
Setup a Kubernetes cluster on Linode
This section will go through all steps of setting up a Kubernetes on linode.com. First, let’s register an account on Linode then login to Linode Dashboard. Go to Kubernetes submenu then click to 'Add a Cluster' button on the upper-right corner and fill up the field: Cluster Label, pick a suitable Region and choose the Kubernetes version.
Then, let’s add Node Pools for your Kubernetes cluster. In this tutorial, we will setup 1-node cluster with 'Dedicated 4GB' plan, node has 4 GB RAM, 2 CPUs and 80 GB storage.
Finally, click “Create Cluster” to provision the Kubernetes cluster.
Waiting for a few minutes, the Kubernetes cluster was successfully provisioned. Let’s download the Kubeconfig file to your local machine, so you can interact with the cluster conveniently.
On your local machine, create a folder named .kube on the Home directory and move the downloaded file to that folder:
$ mkdir ~/.kube $ mv wordpress-kubeconfig.yaml .kube/config
In addition, you have to install kubectl tool:
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl $ chmod +x kubectl $ sudo mv kubectl /usr/local/bin
Now you can get the information of your Kubernetes cluster by running the following command:
$ kubectl get node NAME STATUS ROLES AGE VERSION lke11043-13758-5f73eca05dae Ready 5m v1.18.8
Create PersistentVolume and PersistentVolumeClaim
Both of WordPress and MySQL need PersistentVolume (PV) to store data. PersistentVolume (PV) and PersistentVolumeClaim (PVC) are independent from lifecycle of the application Pod. When you restart, reschedule or delete a Pod, the PV and PVC still remains and preserve the data.
Firstly, provision a PersistentVolume (PV) and it will be claimed by a PersistentVolumeClaim (PVC). Create the manifest file named pvc-mysql-wp.yaml
as follows:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim labels: app: wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: wp-pv-claim labels: app: wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi
Using command kubectl apply to create the PV:
$ kubectl apply -f pvc-mysql-wp.yaml persistentvolumeclaim/mysql-pv-claim created persistentvolumeclaim/wp-pv-claim created
Verify that the PVs were automatically provisioned after creating PVC:
$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-658d8d2da7a241bd 20Gi RWO Retain Bound default/wp-pv-claim linode-block-storage-retain 5m pvc-ca93cd86df0d49c8 20Gi RWO Retain Bound default/mysql-pv-claim linode-block-storage-retain 5m1s
Create password for MySQL database
Kubernetes use Secret to store sensitive data such as password or private key.
Let’s create a file secret.yaml
with your favorite editor as follows:
apiVersion: v1 kind: Secret metadata: name: mysql-pass type: Opaque data: password: yourpassword
Apply the manifest:
$ kubectl apply -f secret.yaml secret/mysql-pass created
Verify that the secret was successfully created:
$ kubectl get secret NAME TYPE DATA AGE default-token-gcgp4 kubernetes.io/service-account-token 3 7h52m mysql-pass Opaque 1 2m33s
Deploy MySQL
You can use the following manifest file to create a single instance deployment of MySQL. The PersistentVolume will be mounted at /var/lib/mysql.
Let’s create file mysql-deployment.yaml
:
apiVersion: v1 kind: Service metadata: name: wordpress-mysql labels: app: wordpress spec: ports: - port: 3306 selector: app: wordpress tier: mysql clusterIP: None --- 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
Then, apply the above manifest:
$ kubectl apply -f mysql-deployment.yaml service/wordpress-mysql unchanged deployment.apps/wordpress-mysql created
Verify that the MySQL pod was successfully deployed:
$ kubectl get pod NAME READY STATUS RESTARTS AGE wordpress-mysql-57464b4779-vtjrf 1/1 Running 0 3m33s
Deploy WordPress
You can use the following manifest to deploy WordPress on your Kubernetes cluster. The PersistentVolume used by WordPress container will be mounted at /var/www/html.
The service wordpress has type LoadBalancer in order to be accessed from outside of the cluster.
Let’s create file wordpress-deployment.yaml
:
apiVersion: v1 kind: Service metadata: name: wordpress labels: app: wordpress spec: ports: - port: 80 selector: app: wordpress tier: frontend type: LoadBalancer --- 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
Now, let’s run the following command to deploy WordPress:
$ kubectl apply -f wordpress-deployment.yaml service/wordpress created deployment.apps/wordpress created
Verify that WordPress is up and running:
$ kubectl get pod NAME READY STATUS RESTARTS AGE wordpress-6857459697-wmgn9 1/1 Running 0 3m34s wordpress-mysql-57464b4779-vtjrf 1/1 Running 0 32m
Verify that all the services is running:
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.128.0.1 443/TCP 12h wordpress LoadBalancer 10.128.108.139 172.104.37.236 80:30567/TCP 5s wordpress-mysql ClusterIP None 3306/TCP 29m
Now you can access the WordPress page by the EXTERAL-IP of service wordpress. Let’s copy it and paste to your web browser:
Conclusion
WordPress is a really powerful blogging tool for any content creators and also developers. This tutorial has gone through all steps of creating a Kubernetes cluster on Linode and setting up the WordPress page on it.
Thanks for reading and please leave your suggestion in the below comment section.
How do we install SSL’s on these WP sites deployed via Kuberenets?
Hi Prasad,
You have to make use of ingress controller say nginx, haproxy etc to route external traffic to Kubernetes apps.