Hello Devs! In this post, we’ll show how Kubernetes checks a Spring boot application’s health.
· Overview
∘ Probes Check mechanisms
∘ Probe outcome
∘ Types of probe
· How does it work with Spring Boot?
∘ Spring Boot Actuator
∘ Kubernetes deployment
∘ Deploy the container image to Kubernetes
· Conclusion
· References
This series of stories shows how to use Kubernetes in the Spring ecosystem. We work with a Spring boot API and Minikube to have a lightweight and fast development environment similar to production.
- Lab1 (Spring Boot/K8S): Deploy Spring Boot application on Kubernetes
- 👉 Lab2 (Spring Boot/K8S): Kubernetes health probes with Spring Boot
In the previous lab, we containerized and deployed a Spring Boot API to a Kubernetes cluster using Minikube. In this story, we’ll look at how to configure our Spring Boot API to use Kubernetes Probes.
Overview
Health checks are a way to query the status of the running application, such as whether the service is slow or unavailable.
Kubernetes probes are a diagnostic performed periodically by the kubelet on a container. kubelet runs code in the container or makes a network request to perform this diagnosis.
Probes Check mechanisms
There are four different ways to check a container using a probe. Each probe must define exactly one of these four mechanisms:
exec
Executes a specified command inside the container. The diagnostic is considered successful if the command exits with a status code of 0.
grpc
Performs a remote procedure call using gRPC. The target should implement gRPC health checks. The diagnostic is considered successful if the status of the response is SERVING.
httpGet
Performs an HTTP GET request against the Pod’s IP address on a specified port and path. The diagnostic is considered successful if the response has a status code greater than or equal to 200 and less than 400.
tcpSocket
Performs a TCP check against the Pod’s IP address on a specified port. The diagnostic is considered successful if the port is open. If the remote system (the container) closes the connection immediately after it opens, this counts as healthy.
Probe outcome
Each probe has one of three results:
Success
The container passed the diagnostic.
Failure
The container failed the diagnostic.
Unknown
The diagnostic failed (no action should be taken, and the kubelet will make further checks).
Types of probe
livenessProbe
Indicates whether the container is running. If the liveness probe fails, the kubelet kills the container, and the container is subjected to its restart policy. If a container does not provide a liveness probe, the default state is Success.
readinessProbe
Indicates whether the container is ready to respond to requests. If the readiness probe fails, the endpoints controller removes the Pod’s IP address from the endpoints of all Services that match the Pod. The default state of readiness before the initial delay is Failure. If a container does not provide a readiness probe, the default state is Success.
startupProbe
Indicates whether the application within the container is started. All other probes are disabled if a startup probe is provided until it succeeds. If the startup probe fails, the kubelet kills the container, and the container is subjected to its restart policy. If a container does not provide a startup probe, the default state is Success.
How does it work with Spring Boot?
Spring Boot includes out-of-the-box support for the commonly used “liveness” and “readiness” availability states. If you are using Spring Boot’s “actuator” support then these states are exposed as health endpoint groups.
Now let’s clone the main Spring boot project with lab1 configuration.
$ git clone https://github.com/anicetkeric/spring-boot-k8s.git -b lab1
Spring Boot Actuator
Add the actuator to the pom.xml file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Then, in the application.yaml file, we need to enable probes:
management:
endpoint:
health:
show-details: always
show-components: always
probes:
enabled: true
health:
livenessState:
enabled: true
readinessState:
enabled: true
endpoints:
web:
exposure:
include: ['env', 'health', 'info']
The liveness endpoint will be exposed at/actuator/health/liveness and the readiness at /actuator/health/readiness.
As we can see, the actuator configuration works well.
Kubernetes deployment
We can then configure the Kubernetes infrastructure with the following endpoint information:
livenessProbe:
httpGet:
path: "/actuator/health/liveness"
port: <actuator-port>
failureThreshold: ...
periodSeconds: ...
readinessProbe:
httpGet:
path: "/actuator/health/readiness"
port: <actuator-port>
failureThreshold: ...
periodSeconds: ...
<actuator-port> should be set to the port that the actuator endpoints are available on. It could be the main web server port or a separate management port if the "management.server.port" property has been set.
We need to include these probes in our Kubernetes deployment:
apiVersion: v1
kind: Service
metadata:
name: book-api-service
spec:
selector:
app: backend
ports:
- protocol: TCP
port: 8081
targetPort: 8080
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-book-api
spec:
replicas: 2
selector:
matchLabels:
app: backend
environment: dev
template:
metadata:
labels:
app: backend
environment: dev
spec:
containers:
- name: book-api
image: spring-boot-k8s:latest
ports:
- containerPort: 8080
imagePullPolicy: Never
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 1
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 1
initialDelaySeconds: Number of seconds after the container has started before startup, liveness, or readiness probes are initiated. If a startup probe is defined, liveness and readiness probe delays do not begin until the startup probe has succeeded. If the value ofperiodSecondsis greater thaninitialDelaySecondsthen theinitialDelaySecondswould be ignored. Defaults to 0 seconds. The minimum value is 0.periodSeconds: How often (in seconds) to perform the probe. Default to 10 seconds. The minimum value is 1.timeoutSeconds: Number of seconds after which the probe times out. Defaults to 1 second. The minimum value is 1.successThreshold: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup Probes. The minimum value is 1.failureThreshold: After a probe failsfailureThresholdtimes in a row, Kubernetes considers that the overall check has failed: the container is not ready/healthy/live. In the case of a startup or liveness probe, if at leastfailureThresholdprobes have failed, Kubernetes treats the container as unhealthy and triggers a restart for that specific container. The kubelet honors the setting ofterminationGracePeriodSecondsthat container. For a failed readiness probe, the kubelet continues running the container that failed checks, and also continues to run more probes; because the check failed, the kubelet sets theReadycondition on the Pod tofalse.terminationGracePeriodSeconds: configure a grace period for the kubelet to wait between triggering a shutdown of the failed container, and then forcing the container runtime to stop that container. The default is to inherit the Pod-level value forterminationGracePeriodSeconds(30 seconds if not specified), and the minimum value is 1. See probe-levelterminationGracePeriodSecondsfor more details.
Deploy the container image to Kubernetes
Now we are ready to deploy this app to Kubernetes.
$ kubectl apply -f k8s.yaml
service/book-api-service created
deployment.apps/backend-book-api created
Check that the application is running:


kubelet will check for the liveness and readiness probe every 5 seconds.
Conclusion
Well done !!. In this post, we have seen how to use Spring’s Actuator to improve our application’s health monitoring with Kubernetes.
The complete source code of this series is available on GitHub.
You can reach out to me and follow me on Medium, Twitter, GitHub, Linkedln
Support me through GitHub Sponsors.
Thanks for reading!


