AWS-EKS
Harsh Rajotya
Technical Blogger & DevOps Engineer @ Medium & DevOpsFarm Inc | Writing, Automation, Cloud
ELASTIC KUBERNETES SERVICE:
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 runs the Kubernetes management infrastructure across multiple AWS Availability Zones, automatically detects and replaces unhealthy control plane nodes, and provides on-demand, zero downtime upgrades, and patching.
AIM: Deploy a webapp over AWS-EKS
PRE-REQUISITES:
* Setup Kubernetes by installing minikube.exe file and use command prompt for further procedure. Also, configure kubectl in the same folder.
minikube start --vm-driver=virtualbox
The above command will setup Kubernetes in the system.
* Install eksctl application in your windows.
* install helm & tiller for prometheus and grafana.
* Last but not the least, If you don't have the account on AWS, then make a free account and install aws windows installer and configure in the system.
NOTE: EKS is not a free service. It costs you .18 dollars per hour according to usage. So We'll delete it after using.
And Finally! After completing all the pre-requisites, Now we can proceed to our aim.
PROCEDURE:
1. Create a EKS-CLUSTER.
CODE:
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: basic-cluster region: ap-south-1 nodeGroups: - name: ng-1 instanceType: m5.large desiredCapacity: 2 - name: ng-2 instanceType: m5.xlarge desiredCapacity: 2 nodeGroups: - name: ng-1 minSize: 2 maxSize: 5 instancesDistribution: maxPrice: 0.017 instanceTypes: ["t3.small", "t3.medium"] # At least one instance type should be specified onDemandBaseCapacity: 0 onDemandPercentageAboveBaseCapacity: 50 spotInstancePools: 2
OUTPUT:
2. Create efs- provisioner (ELASTIC FILE SYSTEM) for the file-storage in cloud . We can also use EBS(ELASTIC BLOCK STORAGE) as an alternative. Here we're proceeding with EFS.
CODE:
kind: Deployment apiVersion: apps/v1 metadata: name: efs-provisioner spec: replicas: 1 selector: matchLabels: app: efs-provisioner strategy: type: Recreate template: metadata: labels: app: efs-provisioner spec: serviceAccount: efs-provisioner containers: - name: efs-provisioner image: quay.io/external_storage/efs-provisioner:v0.1.0 env: - name: FILE_SYSTEM_ID value: fs-9145cf40 - name: AWS_REGION value: ap-south-1 - name: PROVISIONER_NAME value: ss-prov/aws-efs volumeMounts: - name: pv-volume mountPath: /persistentvolumes volumes: - name: pv-volume nfs: server: fs-9145cf40 .efs.ap-south-1.amazonaws.com path: /
We can get FILE SYSTEM ID from following command:
aws-efs create-file-system
OUTPUT:
3. Create a cluster role binding to allow any user in the group"manager' to read secrets in any namespace.
CODE:
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: nfs-provisioner-role subjects: - kind: ServiceAccount name: efs-provisioner namespace: default roleRef: kind: ClusterRole name: efs-provisioner-runner apiGroup: rbac.authorization.k8s.io
OUTPUT:
4. Create storage class to provide a way for administrators to describe the "classes" of storage they offer.
CODE:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: aws-efs-1 provisioner: ss-prov/aws-efs
OUTPUT:
5. Create a Pvc(persistent volume claim), a request for providing storage by user.
CODE:
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: efs-wordpress annotations: volume.beta.kubernetes.io/storage-provisioner: ss-prov/aws-efs finalizers: - kubernetes.io/pvc-protection spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: aws-efs-1 volumeMode: Filesystem kind: PersistentVolumeClaim apiVersion: v1 metadata: name: mysql annotations: volume.beta.kubernetes.io/storage-provisioner: ss-prov/aws-efs finalizers: - kubernetes.io/pvc-protection specs: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: aws-efs-1 volumeMode: Filesystem
6. Deploy Mysql(a webapp).[ We can any webservice of our choice,[I'm going with Mysql as for now]
CODE:
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-mysq-1 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:
Output:
7. Deploy WordPress.
CODE:
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-1 labels: app: wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi --- 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
Here we're done. After port forwarding, We're able to run the webapp.
kubectl get all cluster-ip-addres:80
Run above command and we will get the IP and using that,We will get the webapp.
Here we're done with deploying WordPress over AWS-eks.
Now we'll go with helm . Helm is a tool that streamlines installing and managing Kubernetes applications. Helm is made of two components: 1.The CLI binary named helm that allows us to perform communication with the remote component. 2.TILLER: It lives inside Kubernetes cluster i.e responsible to perform patches and changes resource us to ask manage.
Now that we've already done the installation of helm and tiller, we can directly procedure with helm to manage Prometheus and grafana. Use command prompt for further procedure.
kubectl -n kube-system create serviceaccount tiller kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller helm init --service account tiller
1. INSTALL PROMETHEUS.
kubectl create ns prometheus helm install stable/prometheus --set alertmanager.persisitentVolume.storageClass="gp2"
-Port forwarding:
kubectl get svc -n prometheus kubectl -n prometheus --port forward svc/righteous-seal-prometheus-server 8080:80
Using the IP, We can run Prometheus.
And here we're done with Prometheus.
Similarly, we'll go with grafana.
2.INSTALLATION OF GRAFANA.
kubectl create ns grafana helm install stable/grafana --set persistent.storageClassName="gp2" --set adminPassword=redhat --set service.type=LoadBalancer
-Port Forwarding:
kubectl get svc -n grafana kubectl -n grafana --port forward svc/dangling-oyster-grafana-server 1234:80
Using the IP, we can run the Grafana.
NOTE: As we mentioned earlier,aws-eks is not a free service so just delete the whole cluster to avoid the extra billing. We can do it manually also but sometimes it doesn't delete the cluster properly. So we'll go with the command prompt and using below command, we'll delete the cluster.
eksctl delete cluster --region=ap-south-1 --name=basic-cluster