Deploying WordPress on Amazon-EKS

Shivangi Sharma
5 min readJul 15, 2020

Amazon EKS (Elastic Container Service for Kubernetes) is a managed Kubernetes service that allows you to run Kubernetes on AWS without the hassle of managing the Kubernetes control plane.

The big benefit of EKS, and other similar hosted Kubernetes services, is taking away the operational burden involved in running this control plane. You deploy cluster worker nodes using defined AMIs and with the help of CloudFormation, and EKS will provision, scale and manage the Kubernetes control plane for you to ensure high availability, security and scalability.

The following project implements the deployment of WordPress on EKS-

Prerequisites:

  • AWS cli installed and configured
  • Installed kubectl and eksctl

Create a cluster

we would be using eksctl program to create the cluster, eksctl command is used to manage the cluster easily without any hassle. It contacts CloudFormation which creates everything for us.

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: mycluster
region: ap-southeast-1
nodeGroups:
- name: ng1
desiredCapacity: 2
instanceType: t2.micro
ssh:
publicKeyName: ekskey

- name: ng2
desiredCapacity: 1
instanceType: t2.micro
ssh:
publicKeyName: ekskey

Use the following command to create the cluster using the <filename>.yml

eksctl create cluster -f <cluster-filename>
creating cluster.yml

Use the following command to update the kube-config file-

aws eks --region ap-southeast-1 update-kubeconfig --name mycluster

Install amazon-efs-utils

install the package amazon-efs-utils on all worker nodes. It is recommend to u use the mount helper included in amazon-efs-utils to mount the Amazon EFS file systems.

The following command can be used to install the package within each node -

sudo yum install amazon-efs-utils -y

Amazon EFS

Create the EFS by the amazon console but make sure that the efs is launched in the same VPC and security group as the cluster.

EFS console

EFS-Provisioner

The EFS Provisioner is deployed as a Pod that has a container with access to an AWS EFS file system. The container reads a ConfigMap containing the File system ID, Amazon Region of the EFS file system, and the name of the provisioner.


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: <file-system-id>
- name: AWS_REGION
value: <region-name>
- name: PROVISIONER_NAME
value: <provisioner-name>
volumeMounts:
- name: pv-volume
mountPath: /persistentvolumes
volumes:
- name: pv-volume
nfs:
server: <DNS server-id>
path: /

Use the following code to deploy the efs provisioner-

kubectl create -f create-efs-provisioner.yaml -n <namespace>

RBAC

The roles in RBAC refer to the levels of access that employees have to the network. Employees are only allowed to access the information necessary to effectively perform their job duties.

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nfs-provisioner-role-binding
subjects:
- kind: ServiceAccount
name: default
namespace: my <need-to-be-updated>
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io

Use the following code to create role-

kubectl create -f role.yaml -n my

Storage Class

A StorageClass provides a way for administrators to describe the “classes” of storage they offer. We create a storage class from where PV gets the storage for PVC.

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: aws-efs
provisioner: lw-course/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

Use the following code to create storage class-

kubectl create -f sc.yaml -n my

MySQL Deployment

Create a deployment for MySQL, also mount the PVC to /var/lib/mysql folder as that's where MySQL stores its data. Here we are using secret box for storing password.

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: efs-mysql

Use the following code to create MySQL deployment -

kubectl create -f deploy-mysql.yaml -n <namespace>

WordPress Deployment

Create a deployment for WordPress which will be using LoadBalancer as service which will make our site extremely fault-tolerant, scalable, and expose the IP.

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

Use the following code to create WordPress deployment -

kubectl create -f deploy-wordpress.yaml-n <namespace>

WordPress site is ready!!

--

--