How to Install WordPress on Kubernetes on Linode

Install WordPress on Kubernetes on Linode

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.

Kubernetes - create a cluster linode

Kubernetes submenu on Linode dashboard

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.

Add node pools

Add node pools

Finally, click “Create Cluster” to provision the Kubernetes cluster.

Create cluster

Create 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.

Download kubeconfig

Download kubeconfig

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:

WordPress setup page

WordPress setup page

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.

Truong Nguyen 12:30 pm

Comments

Your email address will not be published. Required fields are marked *