Harnessing custom Kubernetes probes in Spring Boot applications
Tags: springboot, kubernetes, java, kotlin
Published: 2023-08-25 15:13:49

## Disclaimer

This article represents my perspective on this solution, thus any suggestions, fixes, or discussions will be highly appreciated.

## The short story

In my previous article I've explained how to create customized health indicators within a Spring Boot application: [Monitoring the health of Spring Boot applications with custom health indicators](https://dev.to/pavelzeger/monitoring-the-health-of-spring-boot-applications-with-custom-health-indicators-4836). Now I'll show how to use these custom indicators for Kubernetes readiness and liveness probes.

In Kubernetes, readiness and liveness probes are mechanisms used to ensure the availability and health of containerized applications running within pods. They play a crucial role in maintaining the stability and reliability of applications in a Kubernetes cluster.

A **liveness** probe is used to determine if a container is still functioning properly. It periodically checks the health of the application within the container. If the liveness probe fails (i.e., the application within the container becomes unresponsive or crashes), Kubernetes takes action based on the probe's configuration. This action could include restarting the container or even killing the pod and allowing it to be rescheduled on a different node. Liveness probes are essential to prevent applications from hanging in a broken or unresponsive state.

A **readiness** probe is used to determine if a container is ready to accept incoming traffic. It indicates whether the application within the container is fully up and running and capable of serving requests. Readiness probes are particularly useful during deployment scenarios when new versions of an application are being rolled out. By configuring a readiness probe, Kubernetes can delay sending traffic to a newly started container until it's fully prepared to handle requests. This helps prevent instances where users are directed to containers that might still be initializing or not fully functional.
Both types of probes can be configured in Kubernetes using HTTP endpoints, TCP sockets, or command execution within the container. Probes can be customized with parameters such as probe intervals, timeouts, and failure thresholds. Properly configuring these probes contributes to the overall stability and resilience of applications in a Kubernetes environment.

A startup probe is another type of probe introduced in Kubernetes to enhance the reliability of applications, especially during their startup phase. While liveness and readiness probes focus on the ongoing health and readiness of a container, a startup probe specifically targets the early stages of container initialization.

A **startup** probe is used to determine if a container has successfully started and become ready to handle requests. Unlike a liveness probe, which monitors the ongoing health of a container, a startup probe is concerned with the initial state of the container. It helps delay marking the container as ready until a specific condition is met during startup.

Startup probes are useful when containers take longer than usual to initialize or when certain critical services need to be up and running before the application is considered fully operational. For example, an application might need to establish a database connection or load configuration files during startup. By configuring a startup probe, Kubernetes can wait for this initialization process to complete before allowing the container to receive traffic from services or users.

In essence, a startup probe complements liveness and readiness probes by focusing on the specific requirements of a container's startup process, ensuring that the container is not considered ready until it has reached a desired level of initialization.

Overall, by using liveness, readiness, and startup probes effectively, you can create a more robust and fault-tolerant application deployment in a Kubernetes environment.

## The implementation

When deploying a Spring Boot application within a Kubernetes environment, one can leverage the capabilities of the Actuator module to seamlessly integrate "Liveness" and "Readiness" information. This information is sourced from the ApplicationAvailability interface and subsequently utilized in dedicated health indicators, namely `LivenessStateHealthIndicator` and `ReadinessStateHealthIndicator`. These indicators are visible both on the global health endpoint (`/actuator/health`) and as distinct HTTP Probes accessible through health groups: `/actuator/health/liveness` and `/actuator/health/readiness`.

The initial step involves enabling liveness and readiness probes within the Spring Boot application for the Kubernetes environment:

```properties
management.health.kubernetes.enabled=true
management.health.livenessstate.enabled=true
management.health.readinessstate.enabled=true
management.endpoint.health.probes.enabled=true
```

Subsequently, the aim is to furnish comprehensive health information to each Kubernetes request pertaining to our application:

```properties
management.endpoint.health.validate-group-membership=true
management.endpoint.health.group.liveness.show-details=always
management.endpoint.health.group.liveness.show-components=always
management.endpoint.health.group.readiness.show-details=always
management.endpoint.health.group.readiness.show-components=always
```

The more intriguing facet lies in the integration of our custom health indicators into the liveness and readiness probes. Achieving this merely requires the reconfiguration of the Health Groups within the Spring Boot application.

Assume we possess the subsequent custom health indicators:

- _serviceState_ (derived from the `ServiceStateHealthIndicator` class)
- _cacheState_ (derived from the `CacheStateHealthIndicator ` class)

Spring Boot conveniently permits customization of these health checks by employing inclusion and exclusion of diverse health check indicators:

```properties
management.endpoint.health.group.liveness.exclude=readinessState,serviceState
management.endpoint.health.group.liveness.include=cacheState
management.endpoint.health.group.readiness.include=cacheState,serviceState
```

The final accord pertains to the utilization of an alternative or supplementary path for liveness or readiness probes, accomplished through the following configuration:

```properties
management.endpoint.health.probes.add-additional-paths=true
management.endpoint.health.group.liveness.additional-path=server:liveness
management.endpoint.health.group.readiness.additional-path=server:readiness
```

## Summary

When deploying a Spring Boot application in Kubernetes, you can leverage the following probes to ensure the application's reliability and responsiveness: liveness and readiness, and add additional layers of your application into these probes in a very convenient way. This approach helps maintain the stability and availability of your Spring Boot application, even in dynamic containerized environments.

## Resources

1. [Monitoring the health of Spring Boot applications with custom health indicators](https://dev.to/pavelzeger/monitoring-the-health-of-spring-boot-applications-with-custom-health-indicators-4836)
2. [Configure Liveness, Readiness and Startup Probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) 
3. [Kubernetes Probes](https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints.kubernetes-probes)


* * *
Finding my articles helpful? You could give me a caffeine boost to keep them coming! Your [coffee donation](https://www.paypal.com/donate/?hosted_button_id=M3CP3GHUVHEXQ) will keep my keyboard clacking and my ideas brewing. But remember, it's completely optional. Stay tuned, stay informed, and perhaps, [keep the coffee flowing](https://www.paypal.com/donate/?hosted_button_id=M3CP3GHUVHEXQ)!
![keep the coffee flowing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gyl3stjvhahszobv89ta.png)