Kubernetes Liveness vs Readiness Probes Explained
Kubernetes Liveness, Readiness, and Startup Probes: A Practical Production Guide
By Avadhoot Patil | DevOps with Patil
A pod can show Running while its application is still starting, unable to accept requests, or stuck in an unhealthy state. Kubernetes needs a way to distinguish these situations.
That is the purpose of three probes:
- Startup probe: Has the application finished starting?
- Readiness probe: Can this pod receive traffic now?
- Liveness probe: Is this container stuck in a state that requires a restart?
This guide explains what each probe does, how to configure them for a slow-starting Spring Boot application, and how to investigate failures.
The difference at a glance
| Probe | Question it answers | What Kubernetes does when it keeps failing |
|---|---|---|
| Startup | Has the application started successfully? | Restarts the container after the allowed startup window |
| Readiness | Can this pod receive traffic now? | Marks the pod unready and removes it from matching Service endpoints |
| Liveness | Is the application stuck and unable to recover? | Restarts the container after the configured failure threshold |
When a startup probe is configured, Kubernetes waits for it to succeed before running the liveness and readiness probes. After startup succeeds, readiness and liveness continue checking for their different purposes.
1. Liveness probe: restart a stuck container
A liveness probe detects an application state that is unlikely to recover without a restart.
Imagine a Java application that remains running but stops responding because of a deadlock. If its liveness endpoint also stops responding, repeated probe failures can cause Kubernetes to restart that container.
A liveness probe is not a general test of every external dependency. If a shared database fails and every application’s liveness check also fails, Kubernetes could restart all application containers. Those restarts would not repair the database and could make the incident worse.
The liveness endpoint should answer a narrower question: Is this application instance still capable of making progress?
2. Readiness probe: control traffic to the pod
A readiness probe tells Kubernetes whether a pod should receive traffic through a Service.
During startup, the application may need time to initialize. Later, it may briefly become unable to serve requests. When readiness fails, Kubernetes marks the pod unready and stops selecting it as a ready Service endpoint. A readiness failure does not restart the container.
For a banking-style application, consider a pod that has started but cannot process its main API requests. Marking it unready can protect users from being routed to that instance—provided other healthy instances remain available.
Be selective about dependency checks. If every replica marks itself unready during a shared database outage, the Service may have no ready application endpoints. Decide whether a dependency is essential for the traffic this application serves, and test the behavior during a dependency outage.
3. Startup probe: give a slow application time to initialize
A new container image may cause a Spring Boot application to take longer to start. Perhaps it loads more classes, initializes a cache, or performs additional startup work. An aggressive liveness probe can restart it before initialization finishes, leading to repeated restarts.
A startup probe solves this by giving the application a defined startup window. During that window, liveness and readiness probes do not run. Once startup succeeds, the normal probes take over.
There is an important distinction: image download time is not application startup time. A startup probe runs against a started container. If the pod is waiting for an image to download or fails with ImagePullBackOff, investigate the registry, image size, network, credentials, and image pull events. Changing probe timing will not fix an image pull failure.
Example: probes for a Spring Boot application
The following is an illustrative starting configuration, not a universal production setting. It assumes Spring Boot Actuator exposes these endpoints on port 8080:
/actuator/health/liveness/actuator/health/readiness
containers:
- name: banking-api
image: example-registry/banking-api:1.0.0
ports:
- name: http
containerPort: 8080
startupProbe:
httpGet:
path: /actuator/health/liveness
port: http
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 30
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
successThreshold: 1
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
periodSeconds: 15
timeoutSeconds: 3
failureThreshold: 3
Here, the startup probe allows approximately 30 attempts at 10-second intervals. If startup never succeeds within that window, Kubernetes restarts the container according to the pod’s restart policy. Probe scheduling and timeouts mean you should treat this as a configured tolerance, then verify actual behavior in your environment.
After startup succeeds:
- Readiness failures stop traffic being routed to this pod through matching Services.
- Repeated liveness failures cause a container restart.
- Readiness and liveness continue to run independently.
The example does not use a large initialDelaySeconds for both normal probes because the startup probe handles the initialization period.
Check your actual application configuration before copying this YAML. If Actuator uses a separate management port such as 8081, the probe port and network configuration must match. Also verify that checking only the management port gives a meaningful signal for the main application port.
How to choose the startup window
Do not choose failureThreshold: 30 simply because another application uses it. Measure how long your application takes to become healthy.
Test the new image in a representative environment. Record startup times across several runs, including slower runs. Then allow a reasonable margin for expected variation without hiding a genuine startup failure for too long.
For example, if the application normally becomes healthy within two minutes but occasionally takes closer to three minutes, a startup window of several minutes may be justified. Investigate the cause of unusually slow starts as well—probe settings should accommodate expected startup behavior, not conceal a performance regression.
Also check where the time is spent:
| What you observe | Investigate |
|---|---|
Pending or image pull events | Scheduling, registry access, image download, pull secret |
| Container starts, then probe gets connection refused | Application initialization or wrong probe port |
| Probe returns 404 | Incorrect path or Actuator configuration |
| Probe returns 401 or 403 | Security rules on the health endpoint |
| Probe times out | Slow health endpoint, overloaded application, or networking |
| Probe succeeds but users still receive errors | Health endpoint does not reflect the user-facing failure |
Troubleshooting commands
Start by checking pod status, events, and restart counts:
kubectl get pods -n <namespace> -o wide
kubectl describe pod <pod-name> -n <namespace>
Look in describe for events such as failed startup, readiness, or liveness probes. Check the current and previous container logs:
kubectl logs <pod-name> -n <namespace> -c banking-api
kubectl logs <pod-name> -n <namespace> -c banking-api --previous
The --previous output is particularly useful when a failed liveness or startup probe caused a restart.
Inspect whether the Deployment has ready replicas and whether the Service has endpoints:
kubectl get deployment <deployment-name> -n <namespace>
kubectl get service <service-name> -n <namespace>
kubectl get endpointslice -n <namespace> \
-l kubernetes.io/service-name=<service-name>
If your cluster uses OpenShift, the equivalent oc get, oc describe, and oc logs commands can be used.
A useful test before production
In a development or test namespace:
- Deploy the image with the current probe configuration.
- Watch pod status and restart counts while the application starts.
- Record when the container starts, when the startup probe succeeds, and when the pod becomes Ready.
- Check whether the Service receives a ready endpoint.
- Simulate a temporary readiness failure and confirm the pod becomes unready without restarting.
- Simulate an application state that makes the liveness endpoint fail and confirm the container restarts after the configured failures.
- Restore normal behavior and verify that the pod returns to Ready.
Record the actual timings and relevant events. Those results provide better evidence for your production values than copying a generic YAML example.
Common mistakes
Using only a long initial delay
A fixed delay waits the same amount of time on every start. A startup probe can succeed as soon as the application is ready while still allowing a slower start within its configured window.
Putting a shared database check in liveness
A database outage should not automatically cause every application container to restart. Keep liveness focused on whether this instance needs a restart.
Assuming Running means ready
Running describes the pod’s phase. Check the Ready condition and matching Service endpoints to see whether Kubernetes can route traffic to it.
Exposing health information publicly
The kubelet must be able to call the endpoint, but that does not mean it should be publicly accessible through your ingress or route. Configure application security and network exposure appropriately.
Claiming probes guarantee zero downtime
Probes support safe traffic routing and recovery, but availability also depends on sufficient healthy replicas, rollout settings, application behavior, capacity, and dependencies.
Interview questions
What is the difference between liveness and readiness?
Liveness determines when Kubernetes should restart a container. Readiness determines whether a pod should receive Service traffic.
Why use a startup probe?
It protects an application that legitimately needs time to initialize from being restarted prematurely by liveness checks.
Does a failed readiness probe restart a pod?
No. It marks the pod unready. The container continues running and Kubernetes keeps checking it.
Should liveness check a database connection?
Generally, no. A shared database outage is unlikely to be fixed by restarting every application instance.
Will a startup probe fix ImagePullBackOff?
No. The container has not started successfully; investigate image retrieval and registry access.
Conclusion
A reliable probe configuration reflects how your application starts, serves requests, and fails. Use a startup probe for a slow initialization period, readiness to control traffic, and liveness for conditions that require a restart. Measure the new image’s behavior and test failures before applying the settings to production.
What probe failure have you faced in Kubernetes or OpenShift? Share the event message in the comments after removing any private environment details.
Loading Viewer…
Discover more from DevOps with Patil
Subscribe to get the latest posts sent to your email.