Difficulty: Beginner
Estimated Time: 20 minutes

Spring Boot comes with features that make it work well in Kubernetes. This scenario shows you how to add liveness and readiness probes to a Spring Boot application in Kubernetes. To do this we need to do two things:

  1. Add some endpoints to a Spring Boot application and build and push a Docker image
  2. Configure the probes in a few lines of YAML
  3. Deploy the image as a container in Kubernetes

You will need a few minutes of time. We don't cover all the features of Spring and Spring Boot. For that you could go to the Spring guides or Spring project homepages.

We also don't cover all the options available for building containers. There is a Spring Boot topical guide covering some of those options in more detail.

When it comes to deploying the application to Kubernetes, there are far too many options to cover them all in one tutorial. We can look at one or two, but the emphasis will be on getting something working as quickly as possible, not on how to deploy to a production cluster.

Source code for this guide is in Github. It is deployed in Katacoda where you can run the code interactively in your browser.

Well done! You built an app and pushed it to Kubernetes using liveness and readiness probes. Here are the links again to the Spring guides and Spring project homepages. And the Spring Boot Docker covering some more of the containerization options.

Kubernetes Probes with Spring Boot

Step 1 of 2

Add Actuators to a Spring Boot Application

Kubernetes has 3 types of probe. The most important are liveness and readiness. Not all apps need probes, and not all apps need readiness if they have a liveness probe. But in cases where both are present they would map naturally to /actuator/info (liveness) and /actuator/health (readiness). These endpoints are provided out of the box by the https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready-endpoints[Spring Boot Actuators] feature.

NOTE: The /health and /info endpoints are actually the only actuators enabled and exposed over HTTP by default. You don't have to worry about the others until you want to use them.

If a readiness probe fails then the app is taken out of the load balancer rotation, and no more traffic is sent to it, until it passes again. It can continue to pass liveness checks the whole time it is out of rotation.

Open the demo/pom.xml in the editor and add the actuator dependency:

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

In the terminal, pop into the demo director with cd demo. Build the app ./mvnw package:

[INFO] Scanning for projects...
[INFO]
[INFO] --------------------------< com.example:demo >--------------------------
[INFO] Building demo 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
...

...
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  40.807 s
[INFO] Finished at: 2019-11-27T14:00:53Z
[INFO] ------------------------------------------------------------------------

And build the container:

docker build -t localhost/springguides/demo .

NOTE: There is a Docker (v2) registry running on localhost port 80, just to make the tutorial work smoothly, and so you don't have to authenticate to Dockerhub. If you prefer to use Dockerhub just remove localhost/ from the container labels (or insert another registry host instead of localhost).

You can test that the container is working:

docker run -p 8080:8080 localhost/springguides/demo

Sample output:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.1.RELEASE)

2019-11-27 10:13:54.838  INFO 1 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication on 051fa7c2fe52with PID 1 (/app started by root in /)
2019-11-27 10:13:54.842  INFO 1 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2019-11-27 10:14:00.070  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-11-27 10:14:01.093  INFO 1 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path'/actuator'
2019-11-27 10:14:01.809  INFO 1 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
2019-11-27 10:14:01.816  INFO 1 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.793 seconds(JVM running for 2.061)

If the Actuator endpoints are there you can test with curl localhost:8080/actuator/health:

{"status":"UP"}

Once you are sure it is working you can kill the container:

echo "Send Ctrl+C to kill the application"

And push it to the local registry:

docker push localhost/springguides/demo

Great! Now you have a container image in a local Docker registry. You are ready to deploy it to Kubernetes.