Did you know you can containerize your Spring Boot applications to start up in milliseconds, without compromising on throughput, memory, development-production parity, or Java language features? And with little or no refactoring of the application code? Here’s how with Liberty 220.127.116.11-beta…
The InstantOn capability in the Open Liberty runtime uses the IBM Semeru JDK and a Linux technology called Checkpoint/Restore in Userspace (CRIU) to take a checkpoint, or a point-in-time snapshot, of the application process. This checkpoint can then be restored very quickly to bring the application process back into the state it was in when the checkpoint was taken. The application can be restored multiple times because Open Liberty and the Semeru JDK preserve the uniqueness of each restored process in containers. Each restored application process runs without first having to go through the whole startup sequence, saving up to 90% of startup time (depending on your application). InstantOn requires very little modification of your Java application to make this improvement happen.
For more information about Liberty InstantOn, see the How to package your cloud-native Java application for rapid startup blog and Faster startup for containerized applications with Open Liberty InstantOn in the Open Liberty docs.
Spring Boot support for checkpoint/restore
The Spring Framework version 6.1 release will integrate with JVM checkpoint/restore by using the org.crac project to allow capable systems to reduce the startup times of Spring-based Java applications. With the Liberty InstantOn 18.104.22.168-beta version, you can configure a new
crac-1.3 feature to provide an implementation of the org.crac API that integrates with Liberty InstantOn. This allows Spring-based applications, including Spring Boot applications, to be deployed with Liberty InstantOn to achieve rapid startup times.
Production-ready Liberty container images
New Universal Base Image container images are uploaded to the IBM Container Registry for each new release of Liberty. Starting with the 22.214.171.124 Liberty release, the Liberty UBI container images include the necessary prerequisites to checkpoint your applications with Liberty InstantOn. And now, starting with the 126.96.36.199-beta release, the UBI beta container image also includes the prerequisites to checkpoint your Spring Boot 3.2-based applications.
This beta release includes an implementation of the
org.crac APIs with the Liberty beta feature
crac-1.3 feature, along with the Spring Framework version 6.1 support for
org.crac, allows you to checkpoint your Spring-based applications with Liberty InstantOn to achieve rapid startup times.
The Liberty container images make it easy to develop InstantOn applications that are ready to deploy into production. An important benefit of using Liberty InstantOn is the ability to do a checkpoint of the application process inside the container without requiring the root user to be running the application process in the container. It is important, from a security perspective, to avoid running the application process in the container as the root user. This allows you to deploy your InstantOn container images to existing Kubernetes services like AWS EKS and Azure EKS.
Spring Boot 3.2.0 example using Liberty InstantOn
This example uses the Containerizing, packaging, and running a Spring Boot application Open Liberty guide to demonstrate using Liberty InstantOn with a Spring Boot 3.2.0-based application. The fastest way to get up and running is to clone the
cracSpringBoot branch from the guide’s GitHub repository:
git clone --branch cracSpringBoot https://github.com/openliberty/guide-spring-boot.git cd guide-spring-boot/finish
cracSpringBoot branch updates the guide to use the Open Liberty beta and Spring Boot version 3.2.0-M1 , which contains the initial support of
orc.crac for Spring Boot applications. To build and run the example Spring Boot application, you must be using Java 17 or higher.
After cloning the
cracSpringBoot branch of the guide’s repository, the first step is to build the Spring Boot application. Build the application by running the
mvnw command provided with the project
After building the Spring Boot application, the next step is to containerize it. We focus here on changes to containerize the application with Liberty InstantOn. If you want more information about how to best containerize Spring Boot applications with Open Liberty, read through the Containerizing, packaging, and running a Spring Boot application guide.
To build the application container image with InstantOn, you must be able to either run a privileged container or grant the container image build engine the necessary Linux capabilities to do the checkpoint.
Enabling the crac-1.3 Liberty feature
Liberty is composed of features that you enable according to the requirements of your application. To use Liberty’s implementation of
org.crac, you must enable the
crac-1.3 feature in the Liberty configuration. For this example, we can do that by copying in the
src/main/liberty/config/crac.xml file into the container image with the following Dockerfile command:
COPY src/main/liberty/config/crac.xml /config/configDropins/defaults
crac.xml Liberty configuration file enables the
crac-1.3 feature with the following content:
<?xml version="1.0" encoding="UTF-8"?> <server description="Enable the org.crac API"> <featureManager> <feature>crac-1.3</feature> </featureManager> </server>
Building with Podman
With Podman, the container image build engine can be granted the necessary Linux capabilities to checkpoint the application during the container image build. This allows you to run the
checkpoint.sh script as a
RUN instruction, as specified in the
Dockerfile.podman file. This is the last instruction of the
Dockerfile.podman file, as shown in the following example:
... RUN configure.sh RUN checkpoint.sh afterAppStart
To grant the necessary capabilities to the Podman container image build engine, run the following command as root or with
sudo podman build \ -f Dockerfile.podman \ -t springboot \ --cap-add=CHECKPOINT_RESTORE \ --cap-add=SYS_PTRACE\ --cap-add=SETPCAP \ --security-opt seccomp=unconfined .
You can run the previous command or run the provided
scripts/build-instanton-podman.sh script to build the application container image.
During the build, the last thing done is to run the
checkpoint.sh script by using the
afterAppStart option. This causes the checkpoint to happen after the application is started. See when to make a checkpoint for more information on the checkpoint options.
You see the following output when the application has started:
[AUDIT ] CWWKZ0001I: Application thin-guide-spring-boot-0.1.0 started in 3.880 seconds. [AUDIT ] CWWKC0451I: A server checkpoint "afterAppStart" was requested. When the checkpoint completes, the server stops. 2023-09-06T21:06:18.763Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping Spring-managed lifecycle beans before JVM checkpoint 2023-09-06T21:06:18.767Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 2147483647 2023-09-06T21:06:18.768Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Bean 'applicationTaskExecutor' completed its stop procedure 2023-09-06T21:06:18.769Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 2147482623 2023-09-06T21:06:18.771Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Bean 'webServerGracefulShutdown' completed its stop procedure 2023-09-06T21:06:18.771Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 2147481599 2023-09-06T21:06:18.796Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Bean 'webServerStartStop' completed its stop procedure 2023-09-06T21:06:18.796Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase -2147483647 2023-09-06T21:06:18.797Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Bean 'springBootLoggingLifecycle' completed its stop procedure [2/2] COMMIT springboot
The debug output from the Spring Framework shows the
Lifecycle beans in the application were stopped to prepare for the checkpoint. At this point, you have an application container image called
springboot that can be run to restore the application process.
Building with Docker
At this time, Docker does not allow you to grant the container image build engine the Linux capabilities necessary to perform an application checkpoint. This prevents you from running the
checkpoint.sh script doing the
docker build command. Instead, you need to use a three step approach:
Build the application container image without the InstantOn layer.
Run the application container to perform a checkpoint of the application.
Commit the stopped container with the checkpoint process data into an InstantOn application container image.
Complete these three build steps by running the
scripts/build-instanton-docker.sh script . The resulting output is similar to the checkpoint during the Podman build. You will notice some debug output from the Spring Framework for the lifecycle beans. At this point, you have an application container image called
springboot that can be run to restore the application process.
Run the InstantOn Spring Boot application
Both Podman and Docker can use the same options to run the
springboot InstantOn application:
[sudo podman or docker] run \ --rm \ -p 9080:9080 \ --cap-add=CHECKPOINT_RESTORE \ --cap-add=SETPCAP \ --security-opt seccomp=unconfined \ springboot
You can run the previous command or run the provided
scripts/run-instanton-docker.sh script to run the application container image.
You see the following output when the application process is restored:
[AUDIT ] Launching defaultServer (Open Liberty 188.8.131.52-beta/wlp-1.0.81.cl230920230904-1158) on Eclipse OpenJ9 VM, version 17.0.7+7 (en_US) 2023-09-07T15:22:52.683Z INFO 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Restarting Spring-managed lifecycle beans after JVM restore 2023-09-07T15:22:52.684Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase -2147483647 2023-09-07T15:22:52.684Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Successfully started bean 'springBootLoggingLifecycle' 2023-09-07T15:22:52.685Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147481599 [AUDIT ] CWWKT0016I: Web application available (default_host): http://e93ebe585ce3:9080/ 2023-09-07T15:22:52.759Z INFO 118 --- [ecutor-thread-1] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 106109 ms 2023-09-07T15:22:52.762Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Successfully started bean 'webServerStartStop' 2023-09-07T15:22:52.763Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147482623 2023-09-07T15:22:52.763Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Successfully started bean 'webServerGracefulShutdown' 2023-09-07T15:22:52.763Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647 2023-09-07T15:22:52.763Z DEBUG 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Successfully started bean 'applicationTaskExecutor' 2023-09-07T15:22:52.764Z INFO 118 --- [ecutor-thread-1] o.s.c.support.DefaultLifecycleProcessor : Spring-managed lifecycle restart completed in 80 ms [AUDIT ] CWWKC0452I: The Liberty server process resumed operation from a checkpoint in 0.263 seconds. [AUDIT ] CWWKZ0001I: Application thin-guide-spring-boot-0.1.0 started in 0.265 seconds. [AUDIT ] CWWKF0012I: The server installed the following features: [crac-1.3, expressionLanguage-5.0, pages-3.1, servlet-6.0, springBoot-3.0, ssl-1.0, transportSecurity-1.0, websocket-2.1]. [AUDIT ] CWWKF0011I: The defaultServer server is ready to run a smarter planet. The defaultServer server started in 0.277 seconds.
Notice the last message
… server started in 0.277 seconds. The
0.277 second startup time includes the time it took for
criu to restore the Java process as well as the Liberty runtime to properly restore the runtime state such that it can safely run the application once restored. Additional debug messages are enabled for the Spring Framework to show the default Spring lifecycle processor restoring the lifecycle beans in the application. This is a greater than 10x improvement in startup time when compared the original startup time of 5.5+ seconds when not using InstantOn.
Open Liberty InstantOn provides a holistic runtime for deploying cloud-native applications with rapid startup. Liberty InstantOn can be applied to applications using open standards, such as Jakarta EE and MicroProfile, as well as Spring-based applications using the latest versions of Spring Boot and Spring Framework that have support for
org.crac. Applications continue to benefit from the other advantages that the Open Liberty runtime provides, such as:
Access to the full Java SE platform without compromise. No need to adjust application code to fit into environments, like native compilation, to achieve rapid startup.
An optimized Liberty runtime that continues to provide top-performing throughput for applications, while also using less memory compared to other runtimes.
Advanced JIT compilation features provided by the JVM, such as the Semeru Cloud Compiler when deploying to the cloud.
Running on a fit-for-purpose runtime that allows you to use only what you need in order to reduce the container image size.
Using the production-ready Open Liberty container images, an InstantOn application image can be built using the best practices for building optimized and secure application images, such as not running as root in the container or running a privileged container.
InstantOn application images will be ready to deploy into existing public clouds, such as AWS EKS and Azure AKS platforms. The rapid startup times that Liberty InstantOn provides make it an ideal platform for building your serverless applications, including those based on SpringBoot.