Deploy a Spring Boot Java app to Kubernetes on GCP-Google Kubernetes Engine

Kubernetes is an open source project, which can run in many different environments, from laptops to high-availability multi-node clusters, from public clouds to on-premise deployments, and from virtual machine (VM) instances to bare metal.

You’ll use GKE, a fully managed Kubernetes service on Google Cloud Platform, to allow you to focus more on experiencing Kubernetes, rather than setting up the underlying infrastructure.

In this post , i will show you the steps to deploy your simple react application to GCP app engine service .

Before going for actual deployment you should consider below pre-requisites –

GCP account – You need to create at least Free tier GCP account by providing your credit card details which will be valid for 3 months. You can create it using https://cloud.google.com/

Github project – Spring boot project on github (https://github.com/AnupBhagwat7/gcp-examples)

Below are the steps to deploy application to App Engine –

  1. Package a simple Java app as a Docker container.
  2. Create your Kubernetes cluster on GKE.
  3. Deploy your Java app to Kubernetes on GKE.
  4. Scale up your service and roll out an upgrade.
  5. Access Dashboard, a web-based Kubernetes user interface.

1. GCP Setup

Go to Google cloud console(https://console.cloud.google.com/) and click to open cloud shell –

Run the following command in Cloud Shell to confirm that you are authenticated:

gcloud auth list

This command will give you below output –

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

Now run the below command to get the list of projects present under your GCP account –

gcloud config list project

If project is not set then you can do it by using below command –

gcloud config set project <PROJECT_ID>

2. Package your java application

Get the application source code from github –

git clone https://github.com/AnupBhagwat7/gcp-examples.git
cd gcp-demo-springboot-app

Now run the project in gcp cloud shell –

mvn -DskipTests spring-boot:run

once the application is started , you can click on web preview as shown below –

You will be able to see your application launched in browser as below –

3. Package the Java app as a Docker container

Next, you need to prepare your app to run on Kubernetes. The first step is to define the container and its contents.

You need to take below steps to package your application as a docker image –

Step 1: Create the JAR deployable for the app

mvn -DskipTests package

Step 2: Enable Container Registry to store the container image that you’ll create

gcloud services enable containerregistry.googleapis.com

Step 3: Use Jib maven plugin to create the container image and push it to the Container Registry

mvn -DskipTests com.google.cloud.tools:jib-maven-plugin:build   -Dimage=gcr.io/$GOOGLE_CLOUD_PROJECT/gcp-demo-springboot-app.jar

Step 4: If all goes well, then you should be able to see the container image listed in the console by navigating to CI/CD > Container Registry > Images. You now have a project-wide Docker image available, which Kubernetes can access and orchestrate as you’ll see in next steps .

Step 5: You can locally test the image with the following command, which will run a Docker container as a daemon on port 8080 from your newly created container image:

docker run -ti --rm -p 8080:8080 \
  gcr.io/$GOOGLE_CLOUD_PROJECT/gcp-demo-springboot-app.jar

Step 6: You can go to web preview feature of cloud shell to check if docker container is started successfully .You will see response in browser –

4. Deploy your application to Google Kubernetes

Step 1: Create a cluster

You’re ready to create your GKE cluster. A cluster consists of a Kubernetes API server managed by Google and a set of worker nodes. The worker nodes are Compute Engine VMs.

First, make sure that the related API features are enabled

gcloud services enable compute.googleapis.com container.googleapis.com

Create a cluster named springboot-java-cluster with two n1-standard-1 nodes using below command –

gcloud container clusters create springboot-java-cluster \
  --num-nodes 2 \
  --machine-type n1-standard-1 \
  --zone us-central1-c

This will take few minutes to create a cluster. You can see all the clusters by navigating to Kubernetes Engine > Clusters

It’s now time to deploy your containerized app to the Kubernetes cluster. You’ll use the kubectl command line (already set up in your Cloud Shell environment).
The rest of the tutorial requires the Kubernetes client and server version to be 1.2 or higher. kubectl version will show you the current version of the command.

Step 2: Deploy app to Kubernetes cluster

A Kubernetes deployment can create, manage, and scale multiple instances of your app using the container image that you created. Deploy one instance of your app to Kubernetes using the kubectl run command.

kubectl create deployment springboot-java \
--image=gcr.io/$GOOGLE_CLOUD_PROJECT/gcp-demo-springboot-app.jar

To view the deployment that you created, simply run the following command:

kubectl get deployments

To view the app instances created by the deployment, run the following command:

kubectl get pods

At this point, you should have your container running under the control of Kubernetes, but you still have to make it accessible to the outside world.

Step 3: Allow external traffic

By default, the Pod is only accessible by its internal IP within the cluster. In order to make the springboot-java container accessible from outside the Kubernetes virtual network, you have to expose the Pod as a Kubernetes service.

In Cloud Shell, you can expose the Pod to the public internet with the kubectl expose command combined with the –type=LoadBalancer flag. The flag is required for the creation of an externally accessible IP.

kubectl create service loadbalancer springboot-java --tcp=8080:8080

O/P: service/springboot-java created

The flag used in the command specifies that you’ll be using the load balancer provided by the underlying infrastructure. Note that you directly expose the deployment, not the Pod. That will cause the resulting service to load balance traffic across all Pods managed by the deployment (in this case, only one Pod, but you’ll add more replicas later).

The Kubernetes Master creates the load balancer and related Compute Engine forwarding rules, target pools, and firewall rules to make the service fully accessible from outside of Google Cloud.

To find the publicly accessible IP address of the service, simply request kubectl to list all the cluster services.

kubectl get services

O/p:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.3.240.1 443/TCP 44m
springboot-java LoadBalancer 10.3.250.58 34.123.60.207 8080:32034/TCP 85s

Notice that there are two IP addresses listed for your service, both serving port 8080. One is the internal IP address that is only visible inside your Virtual Private Cloud. The other is the external load-balanced IP address. In the example, the external IP address is aaa.bbb.ccc.ddd. You should now be able to reach the service by pointing your browser to http://34.123.60.207:8080

Step 4: Scale your application

One of the powerful features offered by Kubernetes is how easy it is to scale your app. Suppose that you suddenly need more capacity for your app. You can simply tell the replication controller to manage a new number of replicas for your app instances.

kubectl scale deployment springboot-java --replicas=3

O/P: deployment.apps/springboot-java scaled

kubectl get deployment

NAME              READY   UP-TO-DATE   AVAILABLE   AGE
springboot-java   3/3     3            3           23m

Step 5: Roll out an upgrade to your service

At some point, the app that you deployed to production will require bug fixes or additional features. Kubernetes can help you deploy a new version to production without impacting your users.

You can launch editor in CLOUD Shell and update the controller to return a new value as shown below-

Use Jib maven plugin to build and push a new version of the container image.

mvn -DskipTests package \
  com.google.cloud.tools:jib-maven-plugin:build \
  -Dimage=gcr.io/$GOOGLE_CLOUD_PROJECT/springboot-java:v2

In order to change the image label for your running container, you need to edit the existing springboot-java deployment and change the image from gcr.io/PROJECT_ID/springboot-java:v1 to gcr.io/PROJECT_ID/springboot-java:v2.

You can use the kubectl set image command to ask Kubernetes to deploy the new version of your app across the entire cluster one instance at a time with rolling updates.

kubectl set image deployment/springboot-java \
springboot-java=gcr.io/$GOOGLE_CLOUD_PROJECT/springboot-java:v2

Step 6: Rollback to previous version

Perhaps the new version contained an error and you need to quickly roll it back. With Kubernetes, you can roll it back to the previous state easily. Roll back the app by running the following command:

kubectl rollout undo deployment/springboot-java

This marks the end of this tutorial. Thanks for following.

Github link –

https://github.com/AnupBhagwat7/gcp-examples/tree/main/gcp-demo-springboot-app

Monitoring Spring boot application using Prometheus and Grafana

In continuation with previous article ,we will see how we can monitor spring boot application developed in earlier post with actuator. We have already seen prometheus tool for monitoring application but as prometheus doesn’t provide better visualization experience, we have to go with other tools which has rich UI for better visualization of application metrics.

You can use Grafana for the better visualization .

Grafana

While Prometheus does provide some crude visualization, Grafana offers a rich UI where you can build up custom graphs quickly and create a dashboard out of many graphs in no time. You can also import many community built dashboards for free and get going.

Grafana can pull data from various data sources like Prometheus, Elasticsearch, InfluxDB, etc. It also allows you to set rule-based alerts, which then can notify you over Slack, Email, Hipchat, and similar.

Let’s start with running Grafana using Doc

You can download grafana for windows using below link –

https://grafana.com/grafana/dashboards

If you visit http://localhost:3000, you will be redirected to a login page:

Login page

Default credentials to login are admin/admin .

Since Grafana works with many data sources, we need to define which one we’re relying on. In our case we have to select Prometheus as our data source:

Datasource configuration

Select Prometheus from below provided options –

Now, add the URL that Prometheus is running on, in our case http://localhost:9090 and select Access to be through a browser.

At this point, we can save and test to see if the data source is working correctly:

You can search for JVM (Micrometer) dashboard on grafana website and provide its ID in next step to import that dashboard into grafana –

You can find the dashboard ID as highlighted in below screenshot –

As i mentioned earlier, Grafana has lots of of pre-built dashboards. For Spring Boot projects, the JVM dashboard is popular. We are going to use JVM micrometer (ID = 4701) dashboard in this example .

Click on highlighted plus icon and then import –

Select the Prometheus datasource name created in earlier steps as highlighted in below screenshot-

Once you click on import , your dashboard is ready . You can have a look at all the metrics exposed by prometheus on a single dashboard –

I hope this tutorial is helpful for you to configure your spring boot application with Grafana

In this article, we used Micrometer to reformat the metrics data provided by Spring Boot Actuator and expose it in a new endpoint. This data was then regularly pulled and stored by Prometheus, which is a time-series database. Ultimately, we’ve used Grafana to visualize this information with a user-friendly dashboard.

Monitoring an application’s health and metrics helps us manage it better, notice unoptimized behavior, and better understand its performance. This especially holds true when we’re developing a system with many microservices, where monitoring each service can prove to be crucial when it comes to maintaining our system.

Based on this information, we can draw conclusions and decide which microservice needs to scale if further performance improvements can’t be achieved with the current setup.

Github Downlod Link:

Monitoring Spring boot applications using actuator and prometheus

In this article ,we will see how we can monitor spring boot applications using actuator spring boot project and prometheus tool .

Prometheus

Prometheus is a time-series monitoring application written in Go. It can run on a server, in a docker container, or as part of a Kubernetes cluster (or something similar). Prometheus collects, stores, and visualizes time-series data so that you can monitor your systems. You can tell Prometheus exactly where to find metrics by configuring a list of “scrape jobs”. Applications that are being monitored can provide metrics endpoints to Prometheus using any one of the many client libraries available; additionally, separate exporters can gather metrics from applications to make them available in Prometheus. Metrics get stored locally for 15 days, by default, and any Prometheus server can scrape another one for data. Additionally, remote storage is another option for Prometheus data – provided there is a reliable remote storage endpoint.

Benefits:

  • The option of “service discovery” allows Prometheus to keep track of all current endpoints effortlessly.
  • Outages are quickly detected .
  • The PromQL query language is incredibly flexible and Turing-complete.
  • There’s also a very low load on the services monitored (metrics get stored in memory as they get generated), allowing fewer resources to get used.
  • Additionally, Prometheus users can control traffic volumes, access metrics in the browser, and allow for easy reconfiguration.

Part 1: Spring boot application configuration

We will create a simple spring boot REST application which will expose the metrics to prometheus. Please find below project structure of application –

Project Structure

Below is the pom.xml required for project –

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.db</groupId>
    <artifactId>spring-boot-prometheus</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</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>

We need spring-boot-starter-actuator dependency ,this would expose the endpoints of our application and makes it available to prometheus server. You can run the application and check the endpoints exposed by actuator by hitting below link in browser –

http://localhost:8081/actuator

Micrometer

micrometer-registry-prometheus dependency is required to register metrics with prometheus server. It exposes Actuator metrics to external monitoring systems such as Prometheus, Netflix Atlas, AWS Cloudwatch, and many more.

Similarly, Micrometer automatically exposes /actuator/metrics data into something your monitoring system can understand. All you need to do is include that vendor-specific micrometer dependency in your application.

Micrometer is a separate open-sourced project and is not in the Spring ecosystem, so we have to explicitly add it as a dependency. Since we will be using Prometheus, let’s add it’s specific dependency in our pom.xml:

Part 2: Prometheus Server Configuration

For this example , i will be installing portable prometheus on local system . You can download the prometheus setup from official prometheus website as below –

https://prometheus.io/download/

You need to make below changes in prometheus.yml file of prometheus configuration to scrape the metrices your application .Please add below job to scrape the metrices of your application –

 # Details to connect Prometheus with Spring Boot actuator end point to scrap the data
  # The job name is added as a label `job=` to any time series scraped from this config.
  - job_name: 'spring-actuator'
   
    # Actuator end point to collect the data. 
    metrics_path: '/actuator/prometheus'

    #How frequently to scape the data from the end point
    scrape_interval: 5s

    #target end point. We are using the Docker, so local host will not work. You can change it with
    #localhost if not using the Docker.
    static_configs:
    - targets: ['192.168.43.33:8081']

Run the prometheus server by double clicking prometheus.exe flie .

Now prometheus console will open and it will strat gathering the metrices of your application. You can access the prometheus server in browser using http://localhost:9090

Targets for metrics
Classes loaded in JVM prometheus metrics
Number of Threads in different states

You can gather the metrices of your application by selecting the various parameters provided by prometheus like –

  • jvm_classes_loaded_classes
  • jvm_threads_live_threads
  • jvm_threads_states_threads
  • jvm_threads_states_threads
  • tomcat_global_request_seconds_count

These parameters are useful to monitor your systems. In the next article, we will create a prometheus server using docker and expose the metrices.

Github Downlod Link:

Close Bitnami banner
Bitnami