How to Run WordPress on a Kubernetes Cluster from Scratch

1- Ubuntu 16.04 EC2 Instance
2- Memory- 8 GB
3-Type- T2 Medium
4-Security Group — All TCP open

Step 1— Set up each server in the cluster to run Kubernetes

On each of the three Ubuntu 16.04 servers run the following commands as root:

apt-get update && apt-get install -y apt-transport-httpscurl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get updateapt-get install -y kubelet=1.15.4–00 kubeadm=1.15.4–00 kubectl=1.15.4–00 docker.io

Step 2— Setup the Kubernetes Master

kubeadm init

The output look like this as shown below

Image for post
Image for post

This can take a minute or two to run, the result will look like this:

To start using your cluster, you need to run the following as a regular user:

mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config

Run the following command to check the status of the master

kubectl get nodes

The output looks like this as shown below. Here Master is not ready as network plugin is not installed.

Image for post
Image for post

Step 3— Setup a Kubernetes Add-On For Networking Features And Policy

We are going to install the Weave Net Add-On on the kube-01 master which provides networking and network policy, will carry on working on both sides of a network partition, and does not require an external database. Read more about the Weave Net Add-on in the Weave Works Docs.

Next you will deploy a pod network to the cluster.

The options are listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/

Installing the Weave Net Add-On

curl -o weave.yaml https://cloud.weave.works/k8s/v1.8/net.yamlkubectl apply -f weave.yaml

The output looks like this after running above two commands

Image for post
Image for post

Check the status of master by using the following command and now the master is ready

kubectl get nodes
Image for post
Image for post
kubectl get pods — all-namespaces

Step 3b— Resolve Taint for single node master (optional) when only one master exists and no worker loads

Note: To get the namespace, Using the command kubectl get nodes

kubectl describe nodes <Namespace>
Image for post
Image for post
apt-get install jq

Untaint the node

kubectl taint nodes --all node-role.kubernetes.io/master-
Image for post
Image for post

Check the status of the taint by running the following command

kubectl describe nodes <Namespace>
Image for post
Image for post

Step 4— WordPress Setup

WordPress would require a persistent volume (a volume which doesn’t get destroyed over reboots or deletion of applications) this volume will be used by mysql for maintaining various databases to be used by WordPress. To do that, open a file persistent-volume.yaml using any terminal text editor that you prefer. Then enter the following contents in the file:

Here we are setting the following values

PersistentVolume

local-pv-1 storage: 3Gi
local-pv-2 storage: 2Gi

vi local-volumes.yamlapiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv-1
labels:
type: local
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /tmp/data/pv-1
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv-2
labels:
type: local
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /tmp/data/pv-2

After this is saved, in the same directory as this file, run the command:

kubectl create -f local-volumes.yaml

This file consists instructions for creating two persistent volumes. To see if this has indeed worked, run:

kubectl get pv

Once the status shows that the volumes are available, let’s move on to creating a secret which would be used to store your mysql password. Replace the YOUR_PASSWORD field with your secure password.

kubectl create secret generic mysql-pass --from-literal=password=YOUR_PASSWORD

The mysql-pass object is what holds the secret now, and we shall use it to deploy mysql by first creating a file called mysql-deployment.yaml

vi mysql-deployment.yaml

Here we are setting the following values

PersistentVolumeClaim

mysql-pv-claim: 2Gi

apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
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

That file would kick in the mysql database if you run:

kubectl create -f mysql-deployment.yaml
Image for post
Image for post

Finally, we are ready for our WordPress installation. Create a wordpress-deployment.yaml file:

vi wordpress-deployment.yaml

Here we are setting the following values

PersistentVolumeClaim

wordpress: 1Gi

apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
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

After creating the above file, run:

kubectl create -f wordpress-deployment.yaml

Check the status of the pods by running the following command

kubectl get pods -o wide
Image for post
Image for post

Now check the status of the service by using the following command

kubectl get svc
Image for post
Image for post

Go to your browser and use your public IP address (mine is 3.236.140.2) followed by wordpress port . Here wordpress port is 31546 as shown in the above pic.

http://3.236.140.2:31546/

In the below picture 1 is for public ip and 2 is your port number for wordpress

Image for post
Image for post
wordpress Homepage

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store