Launching PHP-MySql website over EKS.

What is EKS?
Amazon Elastic Kubernetes Service (Amazon EKS) is a fully managed Kubernetes service. Using EKS we can make multi node cluster within minute with all the configuration done. EKS manages the master node as it is a managed service by AWS. EKS also provides facility to launch cluster with Fargate which make application serverless. EKS is deeply integrated with services such as Amazon CloudWatch, Auto Scaling Groups, AWS Identity and Access Management (IAM), and Amazon Virtual Private Cloud (VPC), providing you a seamless experience to monitor, scale, and load-balance your applications.
How it Works?

Lets get started
Step 1: Create a IAM user with admin access







Make sure to download or Mail the User information.
Step 2 : AWS CLI configuration
You will need to install aws cli from AWS website for this.
You can download it from here : https://aws.amazon.com/cli/
Add the aws command to your path depending upon your OS.
To configure AWS CLI run :-
$ aws configure
And enter the access key and secret keys you downloaded while creating IAM user.

Step 3: eksctl Configuration
We can use eks service from amazon, but it is time consuming.
amazon have adopted a new way to launch eks clusture using eksctl.
What is “eksctl”?eksctl
is a simple command line utility for creating and managing Kubernetes clusters on Amazon EKS. It creates a CloudFormation script ni the background to launch eks clusture.
You can download eksctl from here https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html and add it to your PATH.
Download and extract the latest release of eksctl
with the following command :-
$ curl — silent — location “https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz” | tar xz -C /tmp
Move the extracted binary to /usr/local/bin :-
$ sudo mv /tmp/eksctl /usr/local/bin
To confirm the Setup run following command :-
$ eksctl version

Step 3: Launching EKS Cluster
There are two ways to launch EKS cluster: -
1. Using EC2 Instances
2. Using Fargate service
I am going to launch EC2 instances in this article.
For that we need to make a yaml file with all the configuration we need.
Before launching the instance we can attach a public key, So that we can login via SSH. So you must create key-pair in AWS beforehand. I have already created the key and downloaded it.
Now Lets make the yaml file :-
I have launched two node groups ng1 and ng-2 with desiredCapacity of two i.e the number of instances in each group

To create the cluster, we just need to run the following command:-
$ eksctl create cluster -f eks_cluster.yml
The output will be like this:-

It will take some time to launch the cluster.
You can see in AWS Web cnsole that a Cloudformation created :-

To access the kubernetes cluster, we need to configure local kubectl.
It can be done easily using AWS CLI command :-
$ aws eks update-kubeconfig — name cluster
To confirm and view configuration of kubectl, use following command :-
$ kubectl config view
Step 4 : Create EFS storage
We can use EBS volume also to start pods but as EBS can only be atached to one EC2 instance for multi node cluster it’s not usefull.
So we create a Storage Class in EKS using EFS
To create go to AWS WebUI console -> EFS -> Create
Give the same VPC and Security Group as clusture so that it can be accessed.
Now we have to make a provisioner which will let us mount the efs storage to the cluster.
For this you will need the FILE_SYSTEM_ID, DNS name of EFS(server), etc
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-8343d652
- name: AWS_REGION
value: ap-south-1
- name: PROVISIONER_NAME
value: basic/aws-efs
volumeMounts:
- name: pv-volume
mountPath: /persistentvolumes
volumes:
- name: pv-volume
nfs:
server: fs-8343d652.efs.ap-south-1.amazonaws.com
path: /
Run the yaml using following command:-
$ kubectl create -f eks_provisioner.yml
Now we have to create a RBAC role for efs:-
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nfs-provisioner-role-binding
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
Run the following using the given command:-
$ kubectl create -f rbac.yml
Now lets create Storage Class for using the EFS Storage.
Following Storage class yaml file can be used to create a storage class for efs.
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: aws-efs
provisioner: basic/aws-efs
Just run this and storge class will be ready for use.
$ kubectl create -f eks_storage.yml
Step 5: Creating Secrets
You can pass the password for MySQL database in the yaml file but this is not a good practice. It may be possible if anyone got the file they will also know your password. Kubernetes provide a good way to store password i,e Secrets.
You have to encode any data before passing it to yaml fie for security reasons.
e.g aman@3214 → YW1hbkAzMjE0
apiVersion: v1
kind: Secret
metadata:
name: mysql-pass
type: Opaque
data:
mysql-pass: YW1hbkAzMjE0
Run to create a storage class :-
$ kubectl create -f secrets.yml
Step 6: Creating PVC
We need to create a Persistent Volume Claim so that we can attach storage to pods.
We will two PVC, one for DB and another for hosting site. These storage will be persistent as they come from EFS. We have to give anotation that we want the storage from EFS storage class.
We also have to set read/write access to Many since we want it connected to all pods in clusture.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: efs-php
annotations:
volume.beta.kubernetes.io/storage-class: "aws-efs"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: efs-mysql
annotations:
volume.beta.kubernetes.io/storage-class: "aws-efs"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
Run the following command to create above PVC:-
$ kubectl create -f pvc.yml
Step 7: Deploying MySQL Pods
It’s time to deploy MySQL pods.
Note: MySQL pods must be created first so that the pod which have website doesn’t go in Crashing when launched.
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-mysql
labels:
app: webapp
spec:
replicas: 2
selector:
matchLabels:
app: webapp
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: webapp
tier: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: mysql-pass
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: efs-mysql
$ kubectl create -f mysql.yml
Step 8 : Launching PHP Website
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-website
labels:
app: php
spec:
selector:
matchLabels:
app: php
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: php
tier: frontend
spec:
containers:
- image: vimal13/
name: php
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: efs-wordpress
$ kubectl create -f php.yml
Step 9: Connecting PHP and Mysql
Both the pods have been deployed but because they are not connected our apps won’t run.
To connect we have to create a service which connect to each other and also if we want to access the website publicly (outside the cluster) we have to also create a Load balance which will give us access to the website.
For MySQL:
apiVersion: v1
kind: Service
metadata:
name: php-mysql
labels:
app: webapp
spec:
ports:
- port: 3306
selector:
app: webapp
tier: mysql
clusterIP: None
$ kubectl create -f mysql_service.yml
For PHP Website:
apiVersion: v1
kind: Service
metadata:
name: php
labels:
app: php
spec:
ports:
- port: 80
selector:
app: php
tier: frontend
type: LoadBalancer
$ kubectl create -f php_service.yml