Introduction
This post provides instructions for setting up EKS kubernetes cluster with Elastic stack.
One of my projects required deployment to kubernetes cluster and since this was a new project I decided to do it completely in the cloud. So my obvious choice was EKS from AWS as a main provider of cloud technology. My next task was to set up cross-cutting concerns for the application. First default requirement was setting up logging system. I decided to use Elastic search with Kibana for this purpose.
The following post contains steps that I did to generate such environment
EKS
I decided to use CDK in order to manipulate my AWS environment. Prerequisites for the CDK are:
In order to generate CDK project type (I decided to use go version of the tool)
1
cdk init app --language go
Modify app.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package main  
  
import (  
   "github.com/aws/aws-cdk-go/awscdk/v2"  
   "github.com/aws/aws-cdk-go/awscdk/v2/awsautoscaling"   
   "github.com/aws/aws-cdk-go/awscdk/v2/awsec2"   
   "github.com/aws/aws-cdk-go/awscdk/v2/awseks"   
   "github.com/aws/aws-cdk-go/awscdk/v2/awsiam"   
   "github.com/aws/aws-sdk-go-v2/aws"   
   "github.com/aws/constructs-go/constructs/v10"   
   "github.com/aws/jsii-runtime-go")  
  
type AwsStackProps struct {  
   awscdk.StackProps  
}  
  
func NewAwsStack(scope constructs.Construct, id string, props *AwsStackProps) awscdk.Stack {  
	var sprops awscdk.StackProps  
	if props != nil {  
      sprops = props.StackProps  
	}  
	stack := awscdk.NewStack(scope, &id, &sprops)  
  
   // Create VPC  
	vpc := awsec2.NewVpc(stack, aws.String("my-vpc"), &awsec2.VpcProps{})  
  
   // IAM role for our EC2 worker nodes  
	workerRole := awsiam.NewRole(stack, jsii.String("EKSWorkerRole"), &awsiam.RoleProps{  
      AssumedBy: awsiam.NewServicePrincipal(jsii.String("ec2.amazonaws.com"), nil),  
   })  
  
   // Create Kubernetes cluster  
	cluster := awseks.NewCluster(stack, jsii.String("my-cluster"), &awseks.ClusterProps{  
      ClusterName:             jsii.String("my-cluster"),  
      Vpc:                     vpc,  
      Version:                 awseks.KubernetesVersion_V1_24(),  
      DefaultCapacityInstance: awsec2.InstanceType_Of(awsec2.InstanceClass_T3, awsec2.InstanceSize_MEDIUM),  
   })  
  
	onDemandASG := awsautoscaling.NewAutoScalingGroup(stack, jsii.String("OnDemandASG"), &awsautoscaling.AutoScalingGroupProps{  
      Vpc:          vpc,  
      Role:         workerRole,  
      MinCapacity:  jsii.Number(1),  
      MaxCapacity:  jsii.Number(10),  
      InstanceType: awsec2.NewInstanceType(jsii.String("t3.medium")),  
      MachineImage: awseks.NewEksOptimizedImage(&awseks.EksOptimizedImageProps{  
         KubernetesVersion: jsii.String("1.24"),  
         NodeType:          awseks.NodeType_STANDARD,  
      }),  
   })  
  
	cluster.ConnectAutoScalingGroupCapacity(onDemandASG, &awseks.AutoScalingGroupOptions{})
	
	return stack  
}
...
I configured the cluster to use t3.medium boxes for control plane and for worker nodes.
Deployment
Prerequisites for this part is:
Deploy EKS cluster
1
cdk deploy
Deployment of the cluster could take 15 minutes. After that you should register context in kubernetes aws eks update-kubeconfig --region us-east-1 --name my-cluster --role-arn <role arn>
Example:
1
aws eks update-kubeconfig --name my-cluster --region us-east-1 --role-arn arn:aws:iam::11111111111:role/AwsStack-myclusterMastersRoleA2A674AE-1K40LT54NLBLL
Create ODIC provider for the cluster
1
eksctl utils associate-iam-oidc-provider --cluster=my-cluster --region us-east-1 --approve
Add Amazon EBS CSI driver
Elasticsearch uses local storage and Kubernetes cluster need a driver to connect to EBS. Basically you need to install addon - EBS CSI driver
1
2
3
4
5
6
7
8
9
10
11
eksctl create iamserviceaccount \  
	--name ebs-csi-controller-sa \  
	--namespace kube-system \  
	--cluster my-cluster \  
	--attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \  
	--approve \  
	--role-only \  
	--role-name AmazonEKS_EBS_CSI_DriverRole
   
eksctl create addon --name aws-ebs-csi-driver --cluster my-cluster --service-account-role-arn arn:aws:iam::111111111111:role/AmazonEKS_EBS_CSI_DriverRole --force
Create EBS Storage Class
Create file storage-class.yaml with content
1
2
3
4
5
6
7
8
9
10
kind: "StorageClass"  
apiVersion: "storage.k8s.io/v1"  
metadata:  
  name: "standard"  
  annotations:    
	  storageclass.kubernetes.io/is-default-class: "true"
provisioner: "kubernetes.io/aws-ebs"  
parameters:  
  type: "gp2"  
  fsType: "ext4"  
Apply the yaml file with kubectl
1
kubectl apply -f storage-class.yaml
ELK
Add elastic repository and create namespace for the ELK
1
2
3
helm repo add elastic https://helm.elastic.co
helm repo update  
kubectl create namespace monitoring
Elasticsearch
Create file values.yaml with content:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---  
# Permit co-located instances for solitary minikube virtual machines.  
antiAffinity: "soft"  
  
# Shrink default JVM heap.  
esJavaOpts: "-Xmx512m -Xms512m"  
  
# Allocate smaller chunks of memory per pod.  
resources:  
  requests:    
	  cpu: "100m"    
	  memory: "1Gi"  
  limits:    
	  cpu: "1000m"    
	  memory: "1Gi"  
# Request smaller persistent volumes.  
volumeClaimTemplate:  
  accessModes: [ "ReadWriteOnce" ]  
  storageClassName: "standard"  
  resources:    
	requests:
		storage: 10Gi  
Install elastic
1
helm install elasticsearch elastic/elasticsearch -n monitoring -f values.yaml --set replicas=1
Kibana
1
helm install kibana elastic/kibana -n monitoring --set replicas=1
You’ll be able to connect to Kibana with elastic username. In order to get password run the following command:
1
kubectl get secrets --namespace=monitoring elasticsearch-master-credentials -ojsonpath='{.data.password}' | base64 -d
Usage
In order to get access to Kibana run the following commend in a separate window:
1
kubectl port-forward deployment/kibana-kibana 5601 -n monitoring
After that you can access your cluster through Kibana by URL http://localhost:5601
Credentials are elastic and password could be obtained as described above
Hope it helped somebody…
Comments powered by Disqus.