Deploying WordPress, MySQL, Prometheus & Grafana on Amazon EKS

Rohan Khandelwal
6 min readJul 12, 2020

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.

EKS is the best place to run Kubernetes for several reasons. First, you can choose to run your EKS clusters using AWS Fargate, which is serverless compute for containers. Fargate removes the need to provision and manage servers, lets you specify and pay for resources per application, and improves security through application isolation by design. Second, 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. Third, EKS integrates with AWS App Mesh and provides a Kubernetes native experience to consume service mesh features and bring rich observability, traffic controls and security features to applications. Additionally, EKS provides a scalable and highly-available control plane that runs across multiple availability zones to eliminate a single point of failure.

EKS runs upstream Kubernetes and is certified Kubernetes conformant so you can leverage all benefits of open source tooling from the community. You can also easily migrate any standard Kubernetes application to EKS without needing to refactor your code.

Setting up the environment

To start using the service, first we need to set up the following

  1. AWS CLI — The AWS Command Line Interface (CLI) is a unified tool to manage your AWS services. With just one tool to download and configure, you can control multiple AWS services from the command line and automate them through scripts. Click here for the complete information about setting up AWS CLI.
  2. eskctl — It is a simple CLI tool for creating clusters on EKS — Amazon’s new managed Kubernetes service for EC2. It is written in Go, uses CloudFormation, was created by Weaveworks and it welcomes contributions from the community.
  3. kubectl — kubectl controls the Kubernetes cluster manager. Click here for the complete information about setting up kubectl.

Creating 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: taskcluster
region: ap-south-1

nodeGroups:

-name: node

instanceType: t2.micro
desiredCapacity: 5
ssh:
publicKeyName: key1

Now we need to run the following command to create a cluster using this file

eksctl create cluster -f cluster.yml

Launching WordPress using MySQL database

We need to just create 3 files for the entire setup

For WordPress:

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

For MySQL:

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

Kustomization.yml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: mysql-pass
literals:
- password=redhat
resources:
- mysql-deployment.yaml
- wordpress-deployment.yaml

Now we need to run the following command to launch the entire setup:

kubectl create -k .

The setup will now look like:

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.

We need to run following commands to setup the helm according to our requirements:

# helm init
# helm repo add stable https://kubernetes-charts.storage.googleapis.com/
# helm repo list
# helm repo update

# kubectl -n kube-system create serviceaccount tiller
# kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller
# helm init --service-account tiller
# kubectl get pods --namespace kube-system

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

eksctl scale nodegroup --cluster taskcluster --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:

First we need to create a namespace for Prometheus using the command:

# kubectl create namespace prometheus

Now, commands to setup Prometheus

# helm install  stable/prometheus     --namespace prometheus     --set alertmanager.persistentVolume.storageClass="gp2"     --set server.persistentVolume.storageClass="gp2"# kubectl get svc -n prometheus
# kubectl -n prometheus port-forward svc/nameprovided-server 8888:80

For Grafana:

First we should create a namespace for Grafana using the command:

# kubectl create namespace grafana

Now, commands to setup Grafana


# 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
# kubectl get secret worn-bronco-grafana --namespace grafana -o yaml

Thank You for reading!!

LinkedIn Profile

--

--