Deploying wordpress on AWS with persistent volume Using EKS

Arifiya Khan
7 min readJul 12, 2020

Before getting started with this task,We should know about kubernetes and EKS.

What is Kubernetes??

It is a tool for automating, deployment, scaling, and operations of application containers across clusters of hosts.It keeps on monitoring the containers.If any container goes down, behind the scenes it requests docker to create another container.

What is EKS??

Amazon Elastic Kubernetes Service (Amazon EKS) is a managed service that makes it easy for you to run Kubernetes on AWS.Amazon provides EKS for hosting the Kubernetes cluster.

What is amazon EFS??

Amazon Elastic File System (Amazon EFS) provides a simple, scalable, fully managed elastic NFS file system for use with AWS Cloud services and on-premises resources.

Objective:-

In this task,we will launch kubernetes cluster on AWS.Also we will attach a volume to make a data persistent and use ELB for load Balancing and integrate it with EFS.After this we will launch a service like Wordpress,mysql with persistent volume.

pre-requisites:-

  1. create AWS account
  2. Download Amazon CLI
  3. Download Eksctl
  4. Download minikube
  5. Download Kubectl

STEP-BY-STEP IMLEMENTATION

So the very first thing that we have to do is creating a new user in AWS with the power of “AdministratorAccess”.

New user

After this we can configure this user using command in CLI

aws configure

And then provide all the credententials.

Now,for launching the clusters we can create the cluster code.

cluster.yml

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: arifiyaclusternew
region: ap-south-1
nodeGroups:
— name: ng1
desiredCapacity: 2
instanceType: t2.micro
ssh:
publicKeyName: mynewkey
— name: ng2
desiredCapacity: 2
instanceType: t2.small
ssh:
publicKeyName: mynewkey
— name: ng-mixed
minSize: 2
maxSize: 5
instancesDistribution:
maxPrice: 0.017
instanceTypes: [“t3.micro”]
onDemandBaseCapacity: 0
onDemandPercentageAboveBaseCapacity: 50
spotInstancePools: 2
ssh:
publicKeyName: mynewkey

Here,mynewkey is the name of the key.Then to create the cluster below written command is used

eksctl create cluster -f cluster.yml

Now as you can see that till now I have no clusters in aws.

After running the above command my cluster automatically gets created,which we can check from GUI as well as CLI.

While creation screen will appear something like this

It will take around 15–20 minutes for creation.After this,Checking from CLI whether the cluster has been created or not.

Checking from GUI

Also I can check my instances to see all the instances running and cloudformation stacks to check all the nodegroups,

What is AWS fargate??

AWS Fargate is a server less compute engine for containers that works with both Amazon Elastic Container Service (ECS) and Amazon Elastic Kubernetes Service (EKS). Fargate makes it easy for you to focus on building your applications.

fargate.yml

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig


metadata:
name: far-lwcluster
region: ap-southeast-1


fargateProfiles:
- name: fargate-default
selectors:
- namespace: kube-system
- namespace: default

To create the fargate ,run the command

eksctl create cluster -f fargate.yml
Screen appearance

Now the next step will be creating an EFS and choose the EKS cluster VPC and security groups.

As you can see that subnets and NAT gateway is also created.

Also check if there is config file in .kube folder.If not then create it or Update config file to allow kubectl to send instructions to master node.

aws eks update-kubeconfig --name clustername

Now we will create a namespace so that my all files will be created and stored in a single place.

For this,

kubectl create namespace lwnamesp

then,

kubectl get ns

Now,We can create an EFS provisioner that allows us to mount EFS storage as PersistentVolumes in kubernetes.

efs-provisioner.yml

kind: Deployment
apiVersion: apps/v1
metadata:
name: efs-provisioner
spec:
selector:
matchLabels:
app: efs-provisioner
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: efs-provisioner
spec:
containers:
- name: efs-provisioner
image: quay.io/external_storage/efs-provisioner:v0.1.0
env:
- name: FILE_SYSTEM_ID
value: fs-be65ef6f
- name: AWS_REGION
value: ap-south-1
- name: PROVISIONER_NAME
value: lwcluster/aws-efs
volumeMounts:
- name: pv-volume
mountPath: /persistentvolumes
volumes:
- name: pv-volume
nfs:
server: fs-be65ef6f.efs.ap-south-1.amazonaws.com
path: /

Now we will create rbac file

rbac.yaml

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nfs-provisioner-role-binding
subjects:
- kind: ServiceAccount
name: default
namespace: lwnamesp
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io

creating the storage class

storageclass.yml

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: aws-efs
provisioner: lwcluster/aws-efs
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: efs-wordpress
annotations:
volume.beta.kubernetes.io/storage-class: “aws-efs”
spec:
accessModes:
— ReadWriteMany
resources:
requests:
storage: 10Gi
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: efs-mysql
annotations:
volume.beta.kubernetes.io/storage-class: “aws-efs”
spec:
accessModes:
— ReadWriteMany
resources:
requests:
storage: 10Gi

Now,Run these commands

We can create a secret password.For this we use command

kubectl create secret generic mysql-pass --from-literal=user=username --from-literal=mypass=password -n lwnamesp

Let’s write our mysql.yaml file

mysql.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
kind: Deployment
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
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: efs-mysql

Now let’s write a yaml file for deploying our WordPress app.

wordpress.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: efs-wordpress

After writing codes ,we will create the files using commands

kubectl create -f wordpress.yaml -n lwnamespkubectl create -f mysql.yaml -n lwnamesp

Then to get an External IP,below command will be run through which we will an external IP.Using which we will open wordpress byrunning it on our browser and then create our website.

kubectl get all -n lwnamesp -o wide

There is an interesting thing to know is that even if the nodes are deleted,another nodes will automatically get created.It is because of fargate.We don’t need to specify the nodes, it dynamically creates by using ec2 instances.

To delete the pods

kubectl delete pods --all

then,

kubectl get nodes

We will find that nodes are now dynamically created

We can check the GUI view,

So,the benefit of this is that sometimes due to high traffic or load on our website can result in the site crash.So at that time,other nodes get automatically created so that the client will not face any issue while accessing the site.

So,

Thanks For reading.I hope my this blog might have helped you in some way.

Happpy learning!😊

--

--