Deploying WordPress, MySQL, Prometheus & Grafana on Amazon EKS

Amazon Elastic Kubernetes Service (Amazon EKS) is a fully managed Kubernetes service. Customers such as Intel, Snap, Intuit, GoDaddy, and Autodesk trust EKS to run their most sensitive and mission critical applications because of its security, reliability, and scalability.

The Kubernetes control plane plays a crucial role in a Kubernetes deployment as it is responsible for how Kubernetes communicates with your cluster — starting and stopping new containers, scheduling containers, performing health checks, and many more management tasks.

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 Cloud Formation, and EKS will provision, scale and manage the Kubernetes control plane for you to ensure high availability, security and scalability.

Prerequisites:-

put all these files in a folder and provide its path to environment variable

Create 1 IAM user and provide it Administration power

IAM User With administration power

Login via CMD to this user account

Creating the EKS cluster:-

There are multiple ways to create a cluster in Amazon EKS. One of the best way is using a YAML file. We need to provide the details like instance type we need, our desired capacity, the region and if we need to login then we need to provide a key for ssh. The syntax is:

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
name: mycluster
region: ap-south-1

nodeGroups:
— name: node
desiredCapacity: 5
instanceType: t2.micro
ssh:
publicKeyName: mykey

Now use under given command to create cluster using given yaml file

eksctl create cluster -f cluster.yml

Launching WordPress using MySQL database

Now create these 3 files inside the folder where we created cluster.yml file.
1. for WordPress :- wp.yml
2. for MySQL :- mysql.yml
3. for kustomization :-kustomization.yml

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:
— ReadWriteOnce
resources:
requests:
storage: 5Gi
— -
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: wp-pv-claim

2. mysql.yml

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:
— ReadWriteOnce
resources:
requests:
storage: 5Gi
— -
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: mysql-pv-claim

3. kustomization.yml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: mysql-pass
literals:
— password=redhat
resources:
— mysql.yml
— wp.yml

Now update config file using this command :- aws eks update-kubeconfig — name mycluster

Now use this command :- kubectl create -k .
This command create the entire setup from creating the replica set , creating pods , attach the external volume and create the load balancer.
WordPress expose for the outside world while MySQL database is kept private . No one from external world can access to MySQL. Both WordPress and MySQL has their own persistent storage. pvc create the elastic block storage provided by aws. while service use in WordPress provide us external load balancer and in case of MySQL we provide clusterIP ,so no one can access it.

nodes and pods
cluster
WordPress
commands

Setting up HELM, Prometheus & Grafana

HELM

Helm helps you manage Kubernetes applications — Helm Charts help you define, install, and upgrade even the most complex Kubernetes application.Charts are easy to create, version, share, and publish — so start using Helm and stop the copy-and-paste.

1. helm init
2. helm repo add stable
https://kubernetes-charts.storage.googleapis.com/
3. helm repo list
4. helm repo list
5. kubectl -n kube-system create serviceaccount tiller
6. kubectl create clusterrolebinding tiller — clusterrole cluster-admin — serviceaccount=kube-system:tiller
7. helm init — service-account tiller
8. kubectl get pods — namespace kube-system

Till now we have completed our WordPress and MySQL set up.
Now we are going to implement Prometheus and Grafana .

For launching Prometheus and Grafana, we need to do scaling to balance the load. We can use the following command

eksctl scale nodegroup — cluster mycluster — nodes=10 — name=node — nodes-max=15 — region ap-south-1

After this we can now setup Prometheus & Grafana.

Prometheus

Prometheus is an open-source systems monitoring and alerting toolkit originally built at SoundCloud. Since its inception in 2012, many companies and organizations have adopted Prometheus, and the project has a very active developer and user community. It is now a standalone open source project and maintained independently of any company. To emphasize this, and to clarify the project’s governance structure, Prometheus joined the Cloud Native Computing Foundation in 2016 as the second hosted project, after Kubernetes.

Grafana

Grafana is a multi-platform open source analytics and interactive visualization web application. It provides charts, graphs, and alerts for the web when connected to supported data sources. It is expandable through a plug-in system. End users can create complex monitoring dashboards using interactive query builders.

Since we have everything setup now, we can now launch Prometheus using the following commands:

1. kubectl create namespace prometheus
2. helm install stable/prometheus — namespace prometheus — set alertmanager.persistentVolume.storageClass=”gp2" — set server.persistentVolume.storageClass=”gp2"
3. kubectl get svc -n prometheus
4. kubectl -n prometheus port-forward svc/looming-mongoose-prometheus-server 8888:80

Run IP ,which you will get after running last command , in your browser to get Prometheus portal .

GRAFANA

First create namespace for Grafana by command :-
kubectl create namespace grafana

Now use following commands:-
1. helm install stable/grafana — namespace grafana — set persistence.storageClassName=”gp2" — set adminPassword=’GrafanaAdm!n’ — set datasources.”datasources\.yaml”.apiVersion=1 — set datasources.”datasources\.yaml”.datasources[0].name=Prometheus — set datasources.”datasources\.yaml”.datasources[0].type=prometheus — set datasources.”datasources\.yaml”.datasources[0].url=http://prometheus-server.prometheus.svc.cluster.local — set datasources.”datasources\.yaml”.datasources[0].access=proxy — set datasources.”datasources\.yaml”.datasources[0].isDefault=true — set service.type=LoadBalancer
2. kubectl get secret worn-bronco-grafana — namespace grafana -o yaml

So , We have completed our Setup of Amazon EKS for Deploying WordPress, MySQL, Prometheus & Grafana .

Thanks for giving your precious time to my this blog.