Do cold starts make FaaS unusable and too expensive for you? Try Kontain’s FaaS! Prepare your mind to be blown.

Instantly starting Spring Boot Java Containers for scale to zero benefits

Tl;dr: This article explains how “Instastart” provides a rather amazing opportunity for Java Spring Boot Containers to be scaled down to 0 during times when there are no events or when there no customers waiting for a request, and provides a way to respond “Instantly” and scale up when the request load suddenly spikes. This allows the possibility of instantly starting Spring Boot java containers for scale to zero benefits.

Introduction

How many times have you wished that your Spring Boot Java microservice would start instantaneously without any delay whatsoever? How many times did you wish you could scale down your Java Containers with faith that you would be able to relaunch them in an instant during a spike in request load.

If only a big heavy JVM could start as quick as those other language runtimes?

How many times did you wish you had tiny Java microservices that could be launched instantly on an event, respond to the event and shut down.

Did you wish you could shut down your service and launch it only when necessary without any “warm” up time?

And, all this while running like containers but getting the Security and strong VM-level isolation benefits of VMs?

Well, read on to see how we can do this with Kontain Containers.

As a recap, last week, you read about how by using Kontain-based Containers rather than traditional Docker Containers, you could drastically reduce the attack surface and mitigate effects due to the Log4Shell attack.

In this article, in addition to enjoying the secure aspects/advantages of using Kontain-based Containers with VM-level isolation boundaries, we want to introduce you to yet another benefit of using Kontain:

“Instantly” starting Spring Boot Java Containers

Just as a reminder, please don’t forget to “star” the project on github:

GitHub - kontainapp/km: Kontain Monitor

and see the guide at:

Introduction to Kontain

 

Using Kontain for “Instantly” starting a Spring Boot Container

Normal Spring boot microservice starting up

In the first video, you will see a normal Spring Boot microservice starting up and that it takes about 9–10 seconds for it to be ready to service requests.

YouTube player

 

“Instantly” starting up Spring Boot Kontainer

In this second video you will the Spring Boot Application “Kontainerized” with the“Instastart” version of the Kontainer running.

You will see that the “Kontainer” is ready to service requests Instantaneously.

YouTube player

 

How do we do this?

Installing Kontain

To install Kontain on your Linux machine, you can follow the steps in the guide. Please note that you need a recent version of Fedora or Ubuntu OS (Linux kernel version 4.15 or newer) for this as specified in the guide.

 

Reviewing the Spring Boot Application

We will use a very simple Spring Boot application as our example as shown below:

$ tree
├── Dockerfile
├── pom.xml
├── resources
│   └── placeholder.txt
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── example
    │               ├── HelloController.java
    │               └── HelloWorldApp.java
    └── test
        └── java
            └── com
                └── example
                    └── HelloControllerTest.java

Application files

The Spring Boot Application:

// HelloWorldApp.java
package com.example;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class HelloWorldApp {
 
public static void main(String[] args) {
SpringApplication.run(HelloWorldApp.class, args);
}
 
}

The Spring Boot Controller:

// HelloController.java
package com.example;
 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class HelloController {
 
@RequestMapping("/")
String hello() {
return "Hello from Kontain!";
}
 
}

Dockerfile

Its Dockerfile:

FROM openjdk:11-jdk-slim-buster as build
RUN mkdir -p /tmp
WORKDIR /opt/src/app
 
# copy jar
COPY target/spring-boot-hello-1.0.jar app.jar
 
FROM kontainapp/runenv-jdk-11 as release
COPY --from=build /opt/src /opt/src
COPY --from=build /tmp /tmp
 
WORKDIR /opt/src/app
 
EXPOSE 8080
 
ENV KM_MGTPIPE=/tmp/km.sock
CMD [ "KM_MGTPIPE=/tmp/km.sock", "/opt/kontain/java/bin/java", "-XX:-UseCompressedOops", "-jar", "/opt/src/app/app.jar" ]

Build and Run

To build the code and the container, we can do:

$ mvn clean package test
$ docker build -t kg/springboothello:latest .

To run using Docker:

$ docker run --rm --runtime=krun -p 8080:8080 kg/springboothello:latest
 
...

As you can see, it takes a few seconds (about 9–10 seconds) before the Spring Boot Application starts up and is ready.

Now, let’s serve a request from this Container just to verify.

Hello from Kontain!

Using an “Instastart” Container

Prep for creating an “Instastart” Container

Now let’s restart the application container with a few other parameters so that we can create an alternate “instantly” starting container for the same Spring Boot Application.

$ docker run --runtime=krun --name=KM_springboothello -p 8080:8080 -v /opt/kontain/bin/km_cli:/opt/kontain/bin/km_cli -v $(pwd):/mnt:rw kg/springboothello:latest
....

Serve a request to verify:

Hello from Kontain!

Creating an “Instastart” Container

Now let’s take an Application Container Snapshot and copy it so as to create an “Instastart” container.

$ docker exec KM_springboothello /opt/kontain/bin/km_cli -s /tmp/km.sock
$ docker cp KM_springboothello:/opt/src/app/kmsnap .
$ chmod +x kmsnap

This will generate a kmsnap file with a re-usable Application Snapshot. Note that KM will report it as saving a core dump, since core dumps and snapshots have the same format and are generated using the same mechanism.

Now, let’s package up the Snapshot as an “Instastart” Container. This bundles the Application Snapshot into a new Docker container that can be used to “instantly” run the Spring Boot application.

# build
$ docker build -t kg/springboothellosnap -f Dockerfile.snap .

Running the “Instastart” Container

Now let’s start up the “Instastart” Container:

# Run in terminal 1
$ docker run --runtime=krun --rm -it --name=KM_springboothello_snap -p 8080:8080 kg/springboothellosnap
 
# Run in terminal 2, you will "instantly" get a response
Hello from Kontain!

You will notice that the container starts up instantly (with almost all of the overhead being Docker startup cost) and that the request gets a response “instantly” as well.

 

Conclusion

“Instastart” provides a rather amazing opportunity for Java Spring Boot Containers to be scaled down to 0 during times when there are no events or when there no customers waiting for a request, and provides a way to respond “Instantly” and scale up when the request load suddenly spikes.

You can view the Kontain project on GitHub here.