Deploying a Java Application to Amazon Elastic Kubernetes Cluster in VS Code
This guide shows you how to create a Java application, containerize and deploy it to Amazon Elastic Kubernetes Service (EKS) from within VS Code with ease, using the Graal Development Kit for Micronaut Extension Pack. The Micronaut® Kubernetes module provides seamless integration with EKS.
EKS is a managed Kubernetes service for deploying containerized applications to the cloud.
Prerequisites #
- A Java Development Kit (JDK) installation (JDK 17 or later).
- A Docker-API compatible container runtime such as Rancher Desktop or Docker.
- An Amazon Web Services (AWS) account. Create an account at Sign up for AWS.
- The AWS CLI.
- An AWS user with sufficient permissions to create and manage EKS and Amazon Elastic Container Registry (ECR).
kubectl
to deploy the application to EKS.
1. Install Extensions #
To get started, install the Graal Development Kit for Micronaut Extension Pack and AWS Toolkit for Visual Studio Code.
-
Follow Installing the Graal Development Kit for Micronaut Extension Pack to install the extension pack and its dependencies in VS Code.
-
To install the AWS Toolkit for Visual Studio Code plugin, follow these steps:
- In the VS Code Activity Bar, click the Extensions icon. This opens the Extensions view, which provides you with access to the VS Code Marketplace.
- In the search box, search for AWS Toolkit.
- Once found, choose it to see its details, then click Install.
- Once installed, if you’re prompted to restart the editor, click Reload Required to finish the installation.
After you install the Toolkit for VS Code, notice the AWS icon the VS Code Activity Bar.
2. Create a Java Application Using Graal Development Kit for Micronaut Launcher #
Create a Java application, using the Graal Development Kit for Micronaut Launcher, that you will later containerize and deploy to Amazon Elastic Kubernetes Service (EKS).
-
Go to View, Command Palette, search for “Graal Dev Kit”, and invoke the Graal Dev Kit: Create New Project quick action:
- Follow the command prompts to generate a new Maven or Gradle project. For example, to create a simple Java application:
- Pick Micronaut version: Default
- Pick application type: Application
- Pick project Java: GraalVM or Other Java
- Provide a project name: aws-k8s-demo
- Provide base package: com.example
- Pick project services: none. Click OK to confirm
- Pick build tool: Gradle (Groovy)
- Pick test framework: JUnit
- Pick cloud platform: AWS. Click OK to confirm
-
Finally, select the destination directory on your local disk and whether to open the created project in a new window or add it to the current workspace. The wizard creates a directory named aws-k8s-demo containing an application in a package named
com.example
. -
(Required only for macOS AArch64) At the beginning of the configuration file, aws/build.gradle, add the following dependency to use the appropriate version of JNA:
buildscript { dependencies { classpath("com.github.docker-java:docker-java-transport-httpclient5:3.2.13") { because("macOS AArch64 needs a specific version of JNA") } } }
-
(Required only for macOS AArch64) At the end of the configuration file, aws/build.gradle, add the following code so that Gradle builds a container image using the
openjdk:17-slim
base image (it defaults toopenjdk:17-alpine
which is not multiplatform).tasks.withType(com.bmuschko.gradle.docker.tasks.image.Dockerfile) { baseImage = 'openjdk:17-slim' }
2.1. Add a Controller #
To create a microservice that responds with “Hello World”, you need a controller. Create a file named lib/src/main/java/com/example/HelloController.java with the following contents:
package com.example;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
@Controller // <1>
public class HelloController {
@Get
@Produces(MediaType.TEXT_PLAIN) // <2>
public String index() {
return "Hello World";
}
@Get ("/{name}") // <3>
@Produces(MediaType.TEXT_PLAIN)
public String index(String name) {
return "Hello " + name;
}
}
1 The class is defined as a controller with the @Controller
annotation mapped to the path /
(the default mapping for the base URI).
2 By default, a Micronaut response uses application/json
as Content-Type
. To return a String, not a JSON object, set it to text/plain
.
3 The @Get
annotation maps the index
method to an HTTP GET request on /{name}
.
2.2. Build and Run the Application #
-
Open a new Terminal window in VS Code (Terminal > New Terminal). Enter the following command to build the application JAR file and run it:
./gradlew :aws:run
It starts the application on port 8080.
-
Split the Terminal window (Terminal > Split Terminal) and send some
curl
requests to test the application in a split terminal:curl http://localhost:8080/
It should output “Hello World”.
curl http://localhost:8080/GDK/
It should output “Hello GDK”. Press
CTRL+C
to stop the application.
3. Create a Shared AWS Credentials File and Connect to AWS #
Follow the instructions provided in the AWS documentation to Add your AWS access keys to your environment.
Follow the instructions provided in the AWS documentation to Connect to AWS through the Toolkit for VS Code.
4. Create a Repository in Amazon Elastic Container Registry (ECR) #
Amazon Elastic Container Registry (Amazon ECR) is an AWS-managed container image registry service. Amazon ECR supports private repositories with resource-based permissions. Amazon ECR is integrated with Amazon Elastic Container Service (Amazon ECS).
The following steps walk you through what is needed to push a container image to a private Amazon ECR repository using the AWS CLI. Before you begin, make sure that you have necessary software listed in the Prerequisites. Also, ensure that you have your AWS account id and region identifier (both of these can be obtained from your AWS console).
-
Authenticate to Amazon ECR with
docker
(it requires the AWS CLI installed, see Prerequisites). The AWS CLI provides aget-login-password
command to simplify the authentication process. The Docker CLI (docker
) can push and pull images with Amazon ECR.- Open a Terminal window in VS Code (Terminal > New Terminal) and enter the following command to authenticate:
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.<region>.amazonaws.com
- Replace <region> with your AWS region key.
AWS
is the default username. The password is composed of <aws_account_id>, which is your AWS account ID, and of the <region> key. For example:aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 1234567890.dkr.ecr.us-east-1.amazonaws.com
Note: If you are a Windows user, the command is:
(Get-ECRLoginCommand).Password | docker login --username AWS --password-stdin aws_account_id.dkr.ecr.region.amazonaws.com
Read more on Using Amazon ECR with the AWS CLI.
- Open a Terminal window in VS Code (Terminal > New Terminal) and enter the following command to authenticate:
-
Create a repository in Amazon ECR that will hold your containerized application (a container image). Under your active AWS connection, focus on ECR and click Create Repository:
Enter a repository name, for example, gdk-demo.
-
Get the repository URI. Open the ECR repositories list, right-click your new repository, and click Copy Repository URI:
-
Specify the path to your new repository in the build configuration file, aws/build.gradle, as follows:
dockerBuild { images = ["<aws_account_id>.dkr.ecr.<region>.amazonaws.com/gdk-demo:$project.version"] }
You are all set to build a container image for your application and push it to Amazon ECR.
5. Containerize the Application and Push a Container Image #
In this section, you create a container image of your Java application and then push it to Amazon ECR.
Note: The build and deployment architecture must match. You cannot build a container image on an AArch64 platform and deploy it to an Intel-based platform, such as Amazon Elastic Compute Cloud (Amazon EC2) or Amazon Elastic Kubernetes Service (Amazon EKS).
- Build the project in your VS Code terminal:
./gradlew clean build
- Build a container image of the application. Note that, because you created the application using Graal Development Kit in VS Code, you do not need to provide a Dockerfile. It is provided by the extension at build time.
./gradlew dockerBuild
- Query
docker
to list your newly built container image:docker images | head -n2
- Push the container image to the container repository:
./gradlew dockerPush
Now that your container image is stored in Amazon ECR, you can deploy it to an Amazon EKS cluster.
6. Create an Amazon EKS Cluster and Setup Connection to Your Cluster #
Follow the AWS documentation to Create an Amazon EKS cluster, Configure Your Computer to Communicate with Your Cluster, and Create Nodes.
Do not follow the Step 5: Delete resources chapter at this point.
7. Deploy a Java Application to EKS Cluster #
-
Create a Kubernetes deployment manifest file. In the project root, create a file named deployment.yml with the following contents:
apiVersion: apps/v1 kind: Deployment metadata: name: "aws-k8s-demo" spec: selector: matchLabels: app: "aws-k8s-demo" template: metadata: labels: app: "aws-k8s-demo" spec: containers: - name: "aws-k8s-demo" image: "<aws_account_id>.dkr.ecr.<region>.amazonaws.com/gdk-demo:1.0-SNAPSHOT"
(Copy the repository URI from the build configuration file, aws/build.gradle.) To learn more, see Deployments in the Kubernetes documentation.
-
Create a deployment by applying the manifest:
kubectl apply -f deployment.yml
It should output the following:
deployment.apps/aws-k8s-demo created
This deployment pulls your container image from a public repository (Amazon ECR repository) and deploys three replicas (individual pods) of it to your cluster.
-
Run the next command to check the status of the pods:
kubectl get pods
It should return a similar message:
NAME READY STATUS RESTARTS AGE aws-k8s-demo-6fdf89f45-5rpsp 0/1 Pending 0 3m
Wait a couple of seconds for the
Pending
state to change toRunning
. Your application is now deployed to the EKS cluster. -
Port-forward the port to access your Kubernetes cluster directly from your local network:
kubectl port-forward <pod-name> 8080:8080
kubectl port-forward
uses a resource name, such as a pod name, to select a matching pod to port forward. -
Send some
curl
requests to test your application as you did in step 2.2:curl http://localhost:8080/
curl http://localhost:8080/GDK/
The difference is that now your application is deployed to an EKS cluster and running on an Amazon EC2 Linux compute host.
8. Clean Up Resources #
To delete all the resources you created in this guide, run this command:
kubectl delete namespaces <namespace-name>
Summary #
This guide demonstrated how to deploy a Java microservice application to Amazon Elastic Kubernetes Service (EKS) from within VS Code, using the Graal Development Kit for Micronaut Extension Pack.