Amazon EKS Cluster setup & Spring Boot Rest API deployment

Bharathvajan G
6 min readApr 16, 2023

--

Introduction:

Kubernetes is an open-source system for automatic deployment, scaling and management of containerized (usually Docker) application. It is cloud agnostic for container orchestration. Basically it groups containers that make up an application into logical units for easy management and discovery. In this story we will focus on how we can deploy simple spring boot rest api on Amazon EKS.

Amazon Elastic Kubernetes Service

  • Managed Kubernetes clusters on AWS
  • EKS has two options for pod deployment one is on EC2 (worker node) and another one is Fargate (serverless)

There are two ways to create EKS Cluster. (1) Using eksctl (2) AWS Management Console.

eksctl — simplifies the step of creating cluster and saves time. But it abstracts lot of steps required to setup cluster.

In this story, we will see how we can setup cluster through AWS Management console in details.

Step-1: Create EKS Cluster

To setup the cluster, following configuration — required

  1. Kubernetes Version — K8s version
  2. Cluster Service Role — Allows K8s to manage resource
  3. VPC — VPC for cluster resource
  4. Cluster Endpoint Access — Public / private access
  5. Networking (Add on)
  6. Logging — Enable logging for K8s

Before creating Cluster, let’s create Cluster service role required for cluster.

1.1: Cluster Service Role

  • Open the AWS Management Console, Choose IAM => Role => Create Role
  • Choose “AWS service” for Trusted entity type and “EKS-Cluster” for the use-case
  • Provide role name details and Create role.
Create IAM Role for EKS Cluster

Create Role by providing role name details

EKS ClusterRole — Details

1.2: Setup Cluster

EKS Cluster Configuration with name, Kubernetes version and IAM Role
Configure VPC, Subnet and Security Group for EKS Cluster
Cluster Endpoint Access
Have the default Add-Ons
Add-Ons versions — configuration

Step-2: Create Node Group

Node group is a set of EC2 instance that caters compute capacity for Amazon EKS

AMI ID, Instance Type, Auto Scaling Configuration, Disk Size

Node Group needs to be associated with EKS

IAM Role needs to be associated with NodeGroup to ensure EC2 instance can perform action like pull image from ECR.

2.1: Create IAM Role for EKS Node

Configure the IAM role for EKS Node

Enter the role name and associate permission (as shown below) to role.

Provide details for IAM Role (name) & associate permissions to eks Node role

2.2: Configure Node Group

Go to java-k8s-cluster & select “Compute” tab. In the Node groups section, click on “Add node group”

  • Enter Node group name and select IAM role for Node.
Configure Node group name and IAM Role
  • Choose AMI Type, Capacity Type, Instance Type and Disk Size.
Configure AMI Type, Capacity Type & Instance Type for EKS Node
  • Configure desired, minimum & maximum size for auto scaling
Setup Node group scaling configuration
  • Configure worker node’s subnet.
Configure Subnet for node group

Go to “Compute” tab in eks cluster & ensure node-group/node is created.

Node & Node group is available for eksCluster

Step-3: Setup & Configure Kubectl:

Kubectl: Kubernetes provides a command line tool for communicating with a Kubernetes cluster’s control plane, using the Kubernetes API.

Important Note: Lets ensure kubectl versions needs to be compatible with Kubernetes cluster version

3.1 Installation Link: https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html

Once installed, ensure correct version is available using the following command.

kubectl version --output yaml

3.2 Create KubeConfig file:

Create kubeconfig file with following command to connect to kubernetes cluster

 aws eks update-kubeconfig --region us-east-1  --name java-k8s-cluster

And ensure the file is created in location: <home-directory>/.kube/config

It has the following key information to connect to the Kubernetes clusters.
1. certificate-authority-data: Cluster CA
2. server: Cluster endpoint (IP/DNS of master node)
3. name: Cluster name
4. user: name of the user/service account.
5. token: Secret token of the user/service account.

We can use the following commands to test kubectl commands.

#To Print all worker node information
kubectl get nodes.

#To Print all pods available in default namespace
kubectl get pods

Step-4: Create Java/Spring Boot Project

Create Spring Boot project with Spring Intializer (https://start.spring.io) configuring spring-web dependencies.

4.1: pom.xml source file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.spingboot</groupId>
<artifactId>restapi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>restapi</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

4.2: Simple Rest Controller — Source file

package com.spingboot.restapi;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SimpleRestController {
@GetMapping("/")
public String hello() {
return "Hello World! from simple rest controller";
}
}

4.3: Docker Source file

FROM openjdk:11
WORKDIR /usr/src/myapp
COPY target/restapi-0.0.1-SNAPSHOT.jar /usr/src/myapp
CMD ["java", "-jar", "/usr/src/myapp/restapi-0.0.1-SNAPSHOT.jar"]

Step-5: Build the Image & Push Image to ECR

Use the following command to build and push docker image to Amazon ECR.

# Build the Docker Image
docker build . -t java-restapi

# Login to ECR
aws ecr get-login-password --region us-east-1 --profile default | docker login --username AWS --password-stdin <aws-account-no>.dkr.ecr.us-east-1.amazonaws.com

# Create ECR Repo
aws ecr create-repository --repository-name java-restapi --image-tag-mutability IMMUTABLE --image-scanning-configuration scanOnPush=true

# Create the Tag
docker tag java-restapi:latest <aws-account-no>.dkr.ecr.us-east-1.amazonaws.com/java-restapi:v1

# Push the Image
docker push <aws-account-no>.dkr.ecr.us-east-1.amazonaws.com/java-restapi:v1

Step-6: Deploy & Run the Pod in EKS Cluster

Kubernete file.

apiVersion: apps/v1kind: Deployment
metadata:
name: rest-api
spec:
selector:
matchLabels:
app: rest-api
template:
metadata:
labels:
app: rest-api
spec:
containers:
- name: rest-api
image: <aws-account-no.>.dkr.ecr.us-east-1.amazonaws.com/java-restapi:v1
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- name: tcp
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: rest-api
spec:
selector:
app: rest-api
ports:
- port: 80
targetPort: 8080
type: LoadBalancer

Use the following command to deploy the pod.

# Use the following command to 
kubectl apply -f k8s.yaml

Conclusion:

Using Amazon EKS, users don’t have to maintain a Kubernetes control plane on their own. Only User have to focus on Worker Node (Data Plane) setup with EC2 instance. EKS also have option to run Data plane on fargate profile which is serverless.

--

--