Amazon EKS - Deploying WordPress, MySQL, Prometheus & Grafana
Amazon EKS is a managed service that makes it easy for you to use Kubernetes on AWS without needing to install and operate your own Kubernetes control plane.
How EKS works -
There are two ways that aws provisions EKS.
1> aws Fargate - This black box is "Serverless" kind of architecture. We don't have to provide any setup as fargate profile will manage all itself. It is easy way but here we can't do any customization
2> Create customized node cluster - Here we can configure nodes according to our requirements. It is better to use as we can go deeper in EKS through this. So here we are going through this way.
Aim - What we are going to do :
Main aim here is to implement EKS. We are going to deploy WordPress in EKS cluster with MySQL as a secure database for it, and to store database persistent here use EFS.
- Create EKS cluster nodes
- Create EFS to use it for both WordPress and MySQL
- Launch WordPress and MySQL in EKS nodes
- Launch Prometheus and Grafana using Helm
As a prerequisite, we need following configuration -
- aws CLI - aws CLI tool
- eksctl - eks CLI tool
- kubectl - kubernetes CLI tool
- Helm - k8s package manager
First, we have to create an aws IAM user with Administrator Access and with this user configure the aws CLI.
with above configuration we are good to go...
- We will use YAML for configuration
Creating cluster in EKS :
> eks-cluster.yml
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: myekscluster region: ap-south-1 # Mumbai region nodeGroups: - name: ng1 desiredCapacity: 2 instanceType: t2.micro ssh: publicKeyName: neokey - name: ng2 desiredCapacity: 1 instanceType: t2.small ssh: publicKeyName: neokey - name: ng-mixed # Spot instance minSize: 1 maxSize: 2 instancesDistribution: maxPrice: 0.025 instanceTypes: ["t3.small", "t3.medium"] # At least one instance type should be specified onDemandBaseCapacity: 0 onDemandPercentageAboveBaseCapacity: 50 spotInstancePools: 2 ssh: publicKeyName: neokey
With this yml file we create eks cluster, it requires around 15-20 mins to get ready the cluster
Cluster will create all the required environment on aws - that we can see through console
After cluster is ready we must update our cluster in kube configuration so that kubectl will use only eks cluster and not local minikube cluster
This setup architecture -
For further operation it is better to use new namespace and use it as current in order to avoid any collisions with cluster. It is like allocating separate space.
Creating Elastic File System :
Go to your aws console and create one EFS. It must be created in same VPC as of eks cluster and have same security group
This EFS we have to provision to pods so create provisioner
> 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-3ebc29ef - name: AWS_REGION value: ap-south-1 - name: PROVISIONER_NAME value: vivek/eks-efs volumeMounts: - name: pv-volume mountPath: /persistentvolumes volumes: - name: pv-volume nfs: server: fs-3ebc29ef.efs.ap-south-1.amazonaws.com path: /
Creating role based access control :
In aws there are many services and here EKS cluster should able to contact EFS, so it will need permission. Role based access control (RBAC) will give this permission.
> eks-rbac.yml
apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: nfs-provisioner-role-binding subjects: - kind: ServiceAccount name: default namespace: eksns roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io
Creating Storage Class and Persistent Volume Claim :
Now create storage class that will use provisioned EFS. Create persistent volume claim (PVC) for both WordPress and MySQL that will provide persistent volume (PV)
> eks-storage.yml
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: aws-efs provisioner: vivek/eks-efs # provisioner name of EFS --- kind: PersistentVolumeClaim # PVC for WordPress apiVersion: v1 metadata: name: efs-wordpress annotations: volume.beta.kubernetes.io/storage-class: "aws-efs" spec: accessModes: - ReadWriteMany resources: requests: storage: 01Gi --- kind: PersistentVolumeClaim # PVC for MySQL apiVersion: v1 metadata: name: efs-mysql annotations: volume.beta.kubernetes.io/storage-class: "aws-efs" spec: accessModes: - ReadWriteMany resources: requests: storage: 01Gi
Creating Service, Deployment, Secret :
Next, create service and deployment for both WordPress and MySQL. In case here for password storage create secret box and give its link in deployment file instead of giving password directly, this will keep our password encoded. We need this configuration in proper order, for this we will use kustomization concept that will create all files in order of preferance.
> wordpress-deployment.yml
apiVersion: v1 kind: Service metadata: name: wordpress labels: app: wordpress spec: ports: - port: 80 selector: app: wordpress tier: frontend type: LoadBalancer --- apiVersion: apps/v1 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
> mysql-deployment.yml
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
Customization file that will create secret first, then MySQL and last WordPress. This order must be maintained because WordPress will require MySQL and password is provided in secret.
> kustomization.yml
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization secretGenerator: - name: mysql-pass literals: - password=vivek resources: - mysql-deployment.yml - wordpress-deployment.yml
Create all this configuration is sequence -
we can see all configured setup -
To launch WordPress use service external IP -
Now we can create blogs. Even after log out all data remains permanent in PV
WordPress working fine, let's get inside MySQL and see the database stored in.
Helm :
The package manager for Kubernetes, it will help us to find, share and use k8s apps. Helm chart is a hub for kubernetes-ready apps, with it we can discover and launch apps on the top of k8s.
For it we need two programs one is helm as a client and tiller as a server, this will work as shown below
Initialize helm and configure the repo from which we will use Prometheus and Grafana
Create new namespace for better management. Then create tiller service account in k8s > create role for cluster binding > initialize tiller account with upgrade. This will configure tiller server
Prometheus :
Prometheus is a free software application used for event monitoring and alerting. It records real-time metrics in a time series database built using a HTTP pull model, with flexible queries and real-time alerting.
Install stable version in new namespace
We can see services, here I forward port 80 to 8888 because services already active on port 80.
Now we can use prometheus using server IP
In this manner we can set targets and monitor them.
Grafana :
Grafana is a multi-platform open source analytics and interactive visualization web application. It is expandable through a plug-in system. End users can create complex monitoring dashboards using interactive query builders.
Install stable version in new namespace
Now decode the password from secret yml file and use it to login.
We can set prometheus as a data source for visualization.
Deleting EKS cluster :
It is better to delete EKS cluster after use because it is paid service from aws. It will take some time delete everything, also cross check it from aws console. So wipe it after use and avoid any surprise bill.
That's it ! Thanks to Vimal Daga Sir