Implementing Kubernetes liveness, Readiness and Startup probes with Spring Boot Microservice Application?
Maintaining a healthy kubernetes cluster is really challenging especially if you have not configured the Liveness, Readiness and Startup Probes correctly for your containers deployed under kubernetes containers.
If I have to put in a simple way -
- Liveness probes - It is responsible for restarting your container, if it senses a deadlock.
- Readiness probes - This probe will tell when the container is ready to start traffic.
- Startup probes - It tells when the container application has started.
But who is communicating with these probes? - The answer is kubelet.
Now the next question comes: what is kubelet? - Kubelet is a Node Agent which acts like caretaker for containers running inside Kubernetes Pod.
If kubelet is caretaker then it should have some mode of communication with containers, which are running inside kubernetes POD and these mode of communication we call it Liveness, Readiness and Startup probes
In this blog post we are going to take an Example of Spring Boot Microservice application and we are going to define Liveness, Readiness and Startup probes.
Here are our steps for implementing Liveness, Readiness and Startup probes -
- Create an Spring Boot Microservice Application
- Write kubernetes deployment.yaml and service.yaml
- Define Liveness probe inside deployment.yaml
- Define Readiness probe inside deployment.yaml
- Define Startup probe inside deployment.yaml
- Deploy both deployment.yaml as well as service.yaml
- Verify the application
1. Create an Spring Boot Microservice Application
(*Note - If your application stack is different and you note using Spring Boot Application then you can skip this part and directly jump to probes configuration steps.)
1.1 Setup spring boot using Spring Initializr
Before we start implementing the probes, the first important step we need to do is create a Spring Boot application. So head over to Spring Initializr and create your basic Spring Boot Microservice Project.
Here is the screenshot which I have taken from while setting up the project details of my Spring Boot application. You can customize the details as per your need.
1.2 Import the Spring Boot Project in your favorite IDE
Now after configuring your Spring Boot Project you can import the project into your favorite IDE. After importing your project into your favorite IDE we can start writing our first microservice.
Here is an Example Java class containing Hello World microserve
1package com.jhooq.Jhooqk8s.ws;
2
3import org.springframework.web.bind.annotation.GetMapping;
4import org.springframework.web.bind.annotation.RestController;
5
6@RestController
7public class HelloWorldMicroservice {
8
9 @GetMapping("/hello")
10 public String hello() {
11 return "Hello - Foo Bar!";
12 }
13}
For this spring boot application project we are using Gradle as our preferred build tool. You can build the complete project using the following command -
1./gradlew build
Let’s run the Spring Boot Microservice Application and test the rest end point by accessing it.
Here is the command for running the application -
1java -jar Jhooq-k8s-0.0.1-SNAPSHOT.jar
For testing you can use the following URL for verifying the rest endpoint -
1curl http://localhost:8080/hello
1.3 Containerize spring boot application using Docker and Push it to Docker Hub
After implementing the microservice we can create a Docker container Image and Push the image to Docker Hub so that later on we can use the same Docker image to deploy inside the kubernetes container.
Let’s first create a Dockerfile -
1FROM openjdk:8-jdk-alpine
2ARG JAR_FILE=build/libs/*.jar
3COPY ${JAR_FILE} app.jar
4ENTRYPOINT ["java","-jar","/app.jar"]
Now build and tag docker image using the following command -
1docker build -t jhooq-k8s-springboot .
2
3docker tag jhooq-k8s-springboot rahulwagh17/kubernetes:jhooq-k8s-springboot
And finally push the Spring boot Docker image to Docker Hub
1docker push rahulwagh17/kubernetes:jhooq-k8s-springboot
(*Note - I have already created any docker hub repository with the name rahulwagh17/jhooq-k8s-springboot)
2. Write kubernetes deployment.yaml and service.yaml
In the previous step we have prepared the Docker container image and pushed the same docker container image to Docker Hub.
Now after that we need to create kubernetes deployment.yaml and kubernetes service.yaml.
2.1 deployment.yaml
There few things which you should always keep in mind while creating your deployment.yaml configurations
- Docker image name - rahulwagh17/kubernetes:jhooq-k8s-springboot
- Port - 8080
- matchLabels.app - jhooq-springboot
If your docker image name is incorrect then you will not be able to deploy your docker container inside the kubernetes cluster. Please refer to this article on how to troubleshoot kubernetes deployment errors
Here is the deployment.yml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: jhooq-springboot
5spec:
6 replicas: 2
7 selector:
8 matchLabels:
9 app: jhooq-springboot
10 template:
11 metadata:
12 labels:
13 app: jhooq-springboot
14 spec:
15 containers:
16 - name: springboot
17 image: rahulwagh17/kubernetes:jhooq-k8s-springboot
18
19 resources:
20 requests:
21 memory: "128Mi"
22 cpu: "512m"
23 limits:
24 memory: "128Mi"
25 cpu: "512m"
26
27 ports:
28 - containerPort: 8080
29 env:
30 - name: PORT
31 value: "8080"
2.2 service.yaml
The next kubernetes manifest we need is service.yaml and here we are going to use the same matchLabels.app which we have defined in deployment.yaml .i.e. - matchLabels.app - jhooq-springboot
Here is the service.yaml -
1apiVersion: v1
2kind: Service
3metadata:
4name: jhooq-springboot
5spec:
6type: NodePort
7ports:
8- port: 80
9targetPort: 8080
10selector:
11app: jhooq-springboot
3. Define Liveness probe inside deployment.yaml
Alright if you reached here which means you have your application ready to be deployed inside kubernetes cluster and now you want to add the liveness probe to it.
For creating liveness probe you need to have following -
- Port - 8080
- path - /hello
- initialDelaySeconds - 15
- periodSeconds - 10
So in our example we are running spring boot application on port - 8080 the microservice service endpoint path is /hello.
We have also added an initialDelaySeconds - 15 because we want the first Liveness check to be performed after the first 15 seconds.
There is one more property which we have added: periodSeconds - 10 which will be responsible for verifying the liveness of the application every 10 seconds.
Here is an updated deployment.yaml -
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: jhooq-springboot
5spec:
6 replicas: 2
7 selector:
8 matchLabels:
9 app: jhooq-springboot
10 template:
11 metadata:
12 labels:
13 app: jhooq-springboot
14 spec:
15 containers:
16 - name: springboot
17 image: rahulwagh17/kubernetes:jhooq-k8s-springboot
18
19 resources:
20 requests:
21 memory: "128Mi"
22 cpu: "512m"
23 limits:
24 memory: "128Mi"
25 cpu: "512m"
26
27 ports:
28 - containerPort: 8080
29 livenessProbe:
30 httpGet:
31 path: /hello
32 port: 8080
33 initialDelaySeconds: 15
34 periodSeconds: 10
35 env:
36 - name: PORT
37 value: "8080"
4. Define Readiness probe inside deployment.yaml
Now after adding the liveness probe in Step no 3 let’s add Readiness probe into the same deployment.yaml.
(Note - For readiness probe we also need to define the same number of config parameters)
Here are few config parameters which you need to define for Readiness probe -
- Port - 8080
- path - /hello
- initialDelaySeconds - 15
- periodSeconds - 10
Here is the updated deployment.yaml after adding the readiness probe -
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: jhooq-springboot
5spec:
6 replicas: 2
7 selector:
8 matchLabels:
9 app: jhooq-springboot
10 template:
11 metadata:
12 labels:
13 app: jhooq-springboot
14 spec:
15 containers:
16 - name: springboot
17 image: rahulwagh17/kubernetes:jhooq-k8s-springboot
18
19 resources:
20 requests:
21 memory: "128Mi"
22 cpu: "512m"
23 limits:
24 memory: "128Mi"
25 cpu: "512m"
26
27 ports:
28 - containerPort: 8080
29
30 readinessProbe:
31 httpGet:
32 path: /hello
33 port: 8080
34 initialDelaySeconds: 15
35 periodSeconds: 10
36
37 livenessProbe:
38 httpGet:
39 path: /hello
40 port: 8080
41 initialDelaySeconds: 15
42 periodSeconds: 10
43
44 env:
45 - name: PORT
46 value: "8080"
5. Define Startup probe inside deployment.yaml
As the name suggests it helps you to determine whether an application has started or not. Let us take an example where an application takes around 10 minutes to startup. So if you have configured the liveness probe with an initialDelaySeconds of 15 seconds then liveness probe will always assume that application is in deadlock state because it takes 10 minutes to finish its first initialization which will always be greater than 15 seconds of liveness probe.
So to overcome this situation, a startup probe has been introduced in the kubernetes ecosystem. While defining the startup probe you should always pay attention to the following configuration properties -
- path - /hello
- port - 8080
- failureThreshold - 30
- periodSeconds - 20
Considering the above parameters the startup probe will take 30*20 = 600 Seconds which is 10 minutes. So once the 10 minutes are over and the startup probe succeeds then the liveness probe takes over.
Here is an updated deployment.yaml with startup probe -
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: jhooq-springboot
5spec:
6 replicas: 2
7 selector:
8 matchLabels:
9 app: jhooq-springboot
10 template:
11 metadata:
12 labels:
13 app: jhooq-springboot
14 spec:
15 containers:
16 - name: springboot
17 image: rahulwagh17/kubernetes:jhooq-k8s-springboot
18
19 resources:
20 requests:
21 memory: "128Mi"
22 cpu: "512m"
23 limits:
24 memory: "128Mi"
25 cpu: "512m"
26
27 ports:
28 - containerPort: 8080
29
30 readinessProbe:
31 httpGet:
32 path: /hello
33 port: 8080
34 initialDelaySeconds: 15
35 periodSeconds: 10
36
37 livenessProbe:
38 httpGet:
39 path: /hello
40 port: 8080
41 initialDelaySeconds: 15
42 periodSeconds: 10
43
44 startupProbe:
45 httpGet:
46 path: /hello
47 port: 8080
48 failureThreshold: 30
49 periodSeconds: 10
50
51 env:
52 - name: PORT
53 value: "8080"
6. Deploy both deployment.yaml as well as service.yaml
Now after preparing the deployment.yaml, service.yaml and setting up liveness, readiness, startup probe let us deploy the application inside the kubernetes cluster.
6.1 Apply the deployment configuration
Applying the deployment configuration is very easy inside the kubernetes cluster and it can be done using kubectl command -
1kubectl apply -f deployment.yaml
Verify the deployment by running the following command -
1kubectl get deployments
2
3NAME READY UP-TO-DATE AVAILABLE AGE
4jhooq-springboot 1/1 1 1 5h20m
6.2 Apply the service configuration
As we have applied the deployment configuration, similarly we can apply the service configuration also -
1kubectl apply -f service.yaml
Verify the deployed services using the following kubectl command -
1kubectl get service
2
3NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
4jhooq-springboot NodePort 10.233.5.144 1.1.1.1 8080:31901/TCP 2s
5kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 28h
Great, you have made successful deployment using Liveness, Readiness and Startup probe.
7. Verify the application
At last you verify the microservice by accessing the cluster ip and port. The Cluster IP you will get from kubectl get service
Now you can curl the URL -
1curl http://10.233.5.144:31901/hello
The output should return - Hello - Foo Bar!
Learn more On Kubernetes -
- Setup kubernetes on Ubuntu
- Setup Kubernetes on CentOs
- Setup HA Kubernetes Cluster with Kubespray
- Setup HA Kubernetes with Minikube
- Setup Kubernetes Dashboard for local kubernetes cluster
- Setup Kubernetes Dashboard On GCP(Google Cloud Platform)
- How to use Persistent Volume and Persistent Volume Claims in Kubernetes
- Deploy Spring Boot Microservice on local Kubernetes cluster
- Deploy Spring Boot Microservice on Cloud Platform(GCP)
- Setting up Ingress controller NGINX along with HAproxy inside Kubernetes cluster
- CI/CD Kubernetes | Setting up CI/CD Jenkins pipeline for kubernetes
- kubectl export YAML | Get YAML for deployed kubernetes resources(service, deployment, PV, PVC....)
- How to setup kubernetes jenkins pipeline on AWS?
- Implementing Kubernetes liveness, Readiness and Startup probes with Spring Boot Microservice Application?
- How to fix kubernetes pods getting recreated?
- How to delete all kubernetes PODS?
- How to use Kubernetes secrets?
- Share kubernetes secrets between namespaces?
- How to Delete PV(Persistent Volume) and PVC(Persistent Volume Claim) stuck in terminating state?
- Delete Kubernetes POD stuck in terminating state?
Posts in this Series
- Kubernetes Cheat Sheet for day to day DevOps operations?
- Delete Kubernetes POD stuck in terminating state?
- How to Delete PV(Persistent Volume) and PVC(Persistent Volume Claim) stuck in terminating state?
- Share kubernetes secrets between namespaces?
- How to use Kubernetes secrets?
- How to delete all kubernetes PODS?
- kubernetes pods getting recreated?
- Implementing Kubernetes liveness, Readiness and Startup probes with Spring Boot Microservice Application?
- kubectl export yaml OR How to generate YAML for deployed kubernetes resources
- Kubernetes Updates
- CI/CD Kubernetes | Setting up CI/CD Jenkins pipeline for kubernetes
- Kubernetes cluster setup with Jenkins
- How to use Persistent Volume and Persistent Claims | Kubernetes
- How to fix ProvisioningFailed persistentvolume controller no volume plugin matched
- Fixing – Cannot bind to requested volume: storageClasseName does not match
- Fixing – pod has unbound immediate persistentvolumeclaims or cannot bind to requested volume incompatible accessmode
- How to fix kubernetes dashboard forbidden 403 error – message services https kubernetes-dashboard is forbidden User
- How to fix Kubernetes – error execution phase preflight [preflight]
- Deploy Spring Boot microservices on kubernetes?
- How to fix – ansible_memtotal_mb minimal_master_memory_mb
- How to use kubespray – 12 Steps for Installing a Production Ready Kubernetes Cluster
- How to setup kubernetes on CentOS 8 and CentOS 7
- How to fix – How to fix - ERROR Swap running with swap on is not supported. Please disable swap
- 14 Steps to Install kubernetes on Ubuntu 20.04(bento/ubuntu-20.04), 18.04(hashicorp/bionic64)
- Kubernetes Dashboard | Kubernetes Admin GUI | Kubernetes Desktop Client
- Install Kubernetes with Minikube