The following blog portrays the process of deploying a simple WordPress website in a Kubernetes cluster running on AWS.


What is Kubernetes :

  • A Service for Container Cluster Management
  • Open-Sourced by Google
  • Used to manage Docker containers as a default implementation

What is WordPress :

  • Most popular blogging and Content Management System (CMS) in existence today
  • An open-source tool written in PHP
  • Highly customisable, has thousands of plugins

What is EFS :

  • EFS stands for Elastic File System, one of many services provided by Amazon Web Services
  • A NFS-v4 based file system for EC2 instances
  • Shareable across instances in an AWS region the file system is created in
  • Elastically grows to petabyte scale

THE PROCESS

Step 1 : Launching a Highly Available Kubernetes cluster

  • There are multiple ways to deploy a Kubernetes cluster. For deploying to AWS, our personal favourite is the Kubernetes Operations (kops) tool. The availability of kops has made deployment of Kubernetes clusters to AWS a piece of cake.
  • A user can follow this link for a detailed guide for deploying a kubernetes cluster on AWS using Kubernetes Operations.

 

Step 2 : Installing heapster and kubernetes dashboard

  • The Dashboard project provides a nice administrative UI for kubernetes cluster management

Install using :

kubectl create -f https://raw.githubusercontent.com/kubernetes/kops/master/addons/kubernetes-dashboard/v1.5.0.yaml

And then navigate to https://api.<cluster-name>/ui

The login credentials are:

Username : admin

Password : can be retrieved by running ‘kubectl config view —minify’

  • Monitoring with Heapster – Standalone

Monitoring supports the horizontal pod autoscaler.

Install using :

kubectl create -f https://raw.githubusercontent.com/kubernetes/kops/master/addons/monitoring-standalone/v1.2.0.yaml

Step 3 : Creating an EFS File System

  • The Amazon EFS console provides an integrated experience, where we can use the user interface to specify VPC subnets to create mount targets and optional file system tags when we create a file system.
  • When we choose Create File System, the console sends a series of API requests to create the file system, and then create tags and mount targets for the file system.

 

Step 4 : Creating 2 Persistent Volumes

  • MySQL and WordPress will each use a Persistent Volume to store their data. We will use a Persistent Volume Claim to claim an available persistent volume
  • We will use AWS EFS as the source for these Persistent Volumes. For that we need to use the EFS DNS name as the server name.
  • Save the following yaml configuration to create two Volumes as efs-pv.yaml :

apiVersion: v1

kind: PersistentVolume

metadata:

  name: wordpress-pv-1

spec:

  capacity:

    storage: 10Gi

  accessModes:

    – ReadWriteMany

  nfs:

    server: fs-xxxxxxxx.efs.us-west-2.amazonaws.com

    path: “/mysql”

apiVersion: v1

kind: PersistentVolume

metadata:

  name: wordpress-pv-2

spec:

  capacity:

    storage: 10Gi

  accessModes:

    – ReadWriteMany

  nfs:

    server: fs-xxxxxxxx.efs.us-west-2.amazonaws.com

    path: “/web”

  • Use the kubectl command to create volumes as follows : kubectl create -f efs-pv.yaml

 

Step 5 : Launching a MySQL deployment with a persistent volume claim

  • Now that we’ve created the volumes, lets launch a mysql container that claims the volume we created and saves data on it
  • Also, we need to create a service that exposes the deployment to other pods, i.e. WordPress
  • Save the following yaml configuration to create a mysql deployment as 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: v1

kind: PersistentVolumeClaim

metadata:

  name: mysql-pv-claim

  labels:

    app: wordpress

spec:

  accessModes:

    – ReadWriteMany

  resources:

    requests:

      storage: 10Gi

  volumeName: wordpress-pv-1

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

          value: redhat

        ports:

        – containerPort: 3306

          name: mysql

        volumeMounts:

        – name: mysql-persistent-storage

          mountPath: /var/lib/mysql

      volumes:

      – name: mysql-persistent-storage

        persistentVolumeClaim:

          claimName: mysql-pv-claim

– Use the kubectl command to create a mysql deployment with a persistent volume claim and a service that exposes the deployment : kubectl create -f mysql-deployment.yaml

Step 6 : Launching a WordPress replication controller with a persistent volume claim

  • Lets launch a WordPress replication controller that claims the volume we created and saves data on it
  • Also, we need to create a service that exposes the deployment to the public via an Elastic Load Balancer
  • Save the following yaml configuration to create a mysql deployment as 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: v1

kind: PersistentVolumeClaim

metadata:

  name: wp-pv-claim

  labels:

    app: wordpress

spec:

  accessModes:

    – ReadWriteMany

  resources:

    requests:

      storage: 10Gi

  volumeName: wordpress-pv-2

apiVersion: v1

kind: ReplicationController

metadata:

  name: wordpress

  labels:

    app: wordpress

spec:

  replicas: 3

  template:

    metadata:

      labels:

        app: wordpress

        tier: frontend

    spec:

      containers:

      – image: wordpress:4.7-apache

        name: wordpress

        env:

        – name: WORDPRESS_DB_HOST

          value: wordpress-mysql

        – name: WORDPRESS_DB_PASSWORD

          value: redhat

        ports:

        – containerPort: 80

          name: wordpress

        volumeMounts:

        – name: wordpress-persistent-storage

          mountPath: /var/www/html

      volumes:

      – name: wordpress-persistent-storage

        persistentVolumeClaim:

          claimName: wp-pv-claim

  • Use the kubectl command to create a WordPress replication controller with a persistent volume claim and a service that exposes the deployment : kubectl create -f wordpress-deployment.yaml
  • Since we created a Service of the type ‘LoadBalancer’, Kubernetes will launch an external Elastic Load Balancer (ELB) and attach all the existing WordPress pods to it.

 

Step 7 : Configuring horizontal pod autoscaler for WordPress replication controller

  • The autoscaler (implemented as a Kubernetes API resource and controller) is responsible for dynamically controlling the number of replicas of some collection (e.g. the pods of a ReplicationController) to meet some objective(s) (e.g. a target per-pod CPU utilisation)
  • It uses heapster for gathering the metrics necessary
  • A simple kubectl command can be used to enable autoscaling on existing resources like our WordPress Replication Controller:

kubectl autoscale rc wordpress –min=2 –max=5 —cpu-percent=80

  • The above command enables auto scaling on pods in the replication controller ‘wordpress’ based on average CPU utilisation.

 

Step 8 : Accessing WordPress using the Load Balancer CNAME

  • AWS provides every external Elastic Load Balancer with a unique CNAME record that can be accessed from anywhere. A user can use this CNAME to access the WordPress site we just created.

One Comment

  1. Miguel

    I wonder what version of Kubernetes you used for this as it doesn’t seem to work for me:

    $ kubectl version
    Client Version: version.Info{Major:”1″, Minor:”7″, GitVersion:”v1.7.1″, GitCommit:”1dc5c66f5dd61da08412a74221ecc79208c2165b”, GitTreeState:”clean”, BuildDate:”2017-07-14T05:22:03Z”, GoVersion:”go1.8.3″, Compiler:”gc”, Platform:”darwin/amd64″}
    Server Version: version.Info{Major:”1″, Minor:”6″, GitVersion:”v1.6.2″, GitCommit:”477efc3cbe6a7effca06bd1452fa356e2201e1ee”, GitTreeState:”clean”, BuildDate:”2017-04-19T20:22:08Z”, GoVersion:”go1.7.5″, Compiler:”gc”, Platform:”linux/amd64″}

    Error:
    Unable to mount volumes for pod “wordpress-bb61s_default(f9043115-7abf-11e7-963b-0acf69b8190a)”: timeout expired waiting for volumes to attach/mount for pod “default”/”wordpress-bb61s”. list of unattached/unmounted volumes=[wordpress-persistent-storage]

    The PVC is green and bound, so I’m not sure what is wrong here…

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


CAPTCHA Image
Reload Image