Lets create K8s volumes and configuring a WP instance with a MySQL database in a most simple way – a perfect introduction to Kubernetes for newbies.
Configure a PersistentVolume in the K8s cluter
In this example, we’ll use a hostPath volume since we only have one node in the cluster. This type of volume mounts the path from the node’s filesystem into K8s.
The hostPath volume is not recommended for multi-node production clusters. If you’re working on multiple nodes, follow the instructions here.
Create volumes.yml
apiVersion: v1 kind: PersistentVolume metadata: name: local-pv-1 labels: type: local spec: capacity: storage: 10Gi accessModes: - ReadWriteOnce hostPath: path: /k8/volume/pv-1 --- apiVersion: v1 kind: PersistentVolume metadata: name: local-pv-2 labels: type: local spec: capacity: storage: 10Gi accessModes: - ReadWriteOnce hostPath: path: /k8/volume/pv-2 This config will create two R/W 10GB volumes in the node paths: /k8/volume/pv-1 /k8/volume/pv-2
Create your K8s volumes
To create the volumes, run
# kubectl apply -f volumes.yml
You can check if everything’s working correctly by running
# kubectl get pv NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE local-pv-1 10Gi RWO Retain Available 13s local-pv-2 10Gi RWO Retain Available 13s
Configure a MySQL database
Start with creating a secret password for the MySQL root user:
# kubectl create secret generic mysql-pass --from-literal=password=ROOT_PASSWORD
You can check if the password was properly configured by running
# kubectl get secrets NAME TYPE DATA AGE mysql-pass Opaque 1 17h
Secrets in K8s are hidden and cannot be displayed. This means there’s no risk of exposing them in config files in public repositories.
Create mysql.yml
The file below will create a single MySQL instance with a proper volume and port mapping. It also uses the secret that we created earlier:
apiVersion: v1 kind: Service metadata: name: wordpress-mysql labels: app: wordpress spec: ports: - port: 3306 selector: app: wordpress tier: mysql --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim labels: app: wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi --- 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
Details of mysql.yml
The file consists of 3 separate configs:
Service – maps MySQL’s port 3306 and makes it available for all containers with labels app:wordpress & tier:mysql
Persistent volume claim – declares claim on the volume that will be used in the MySQL container configuration
Deployment – declares the creation strategy and specs of our MySQL container:
- it’s an image from the Docker Hub: mysql:5.6
- it has app:wordpress & tier:frontend labels (used in Service)
- it contains an environment variable called MYSQL_ROOT_PASSWORD which holds the value from our secret password
- it has an open port 3306
- it has a volume claim mounted in /var/lib/mysql
Create your MySQL instance on K8s
To create the database, run
# kubectl apply -f mysql.yml
You can check the progress of deployment by running
# kubectl get pods
Once you see status:Running, the MySQL service is ready for action.
Deploy WordPress to Kubernetes
Begin with downloading WordPress sources from https://wordpress.org/download/
Configure the Docker file
Now we need to dockerize the WordPress instance. The Docker file only requires WP sources:
FROM wordpress:php7.1-apache COPY . /usr/src/wordpress/
Build & push the Docker image
The next step is building the Docker image and pushing it to your Docker registry:
# docker login # docker build –t <<your-repo-name>>/wordpress . # docker push <<your-repo-name>>/wordpress
Create wordpress.yml
To deploy WordPress on a Kubernetes node you need to create a proper config file:
apiVersion: v1 kind: Service metadata: name: wordpress labels: app: wordpress spec: ports: - port: 80 nodePort: 30000 selector: app: wordpress tier: frontend type: NodePort --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: wp-pv-claim labels: app: wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi --- 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: <<your-repo-name>>//wordpress:latest 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
Details of wordpress.yml
The file consists of 3 separate configs:
Service – maps port 80 of the container to the node’s external IP:30000 for all containers with labels app:wordpress & tier:frontend
Persistent volume claim – declares claim on the volume that will be used in the WP container configuration
Deployment – declares the creation strategy and spec of our WordPress container:
- it’s an image from the Docker Hub: <<your-repo-name>>//wordpress:latest
- it has app:wordpress & tier:frontend labels (used in Service)
- it contains environment variables WORDPRESS_DB_HOST, which is the internal host name of the MySQL instance, and WORDPRESS_DB_PASSWORD, which holds the value from our secret password
- it has an open port 80
- it has a volume claim mounted in /var/www/html from which the WP sources are served
Create your WP instance on K8s
To deploy your WP instance, run
# kubectl apply -f wordpress.yml
You can check the progress of deployment by running
# kubectl get pods
Once you see status:Running, the WordPress service is ready for action.
Congratulations! You have successfully deployed your WordPress project to Kubernetes. You can visit the site by going to node IP:30000.
Read More: How to Setup Kubernetes on Ubuntu
Advantages & Extenstions
Running WordPress and other web projects on Kubernetes gives you a series of benefits:
- easy configuration in just a few files
- you can recreate the whole configuration on any host with a couple of commands:
- kubectl apply -f volumes.yml
- kubectl apply secret generic mysql-pass –from-literal=password=ROOT_PASSWORD
- kubectl apply -f mysql.yml
- kubectl apply -f wordpress.yml
- you can extend the configuration by using volumes on AWS or other production ready volumes
- you can change the external port mapping for proper load balancing
- you can change the deployment strategy from Recreate to Rolling Update to increase container counts and ensure no downtime during the deployment