What is liveness probe
A Liveness Probe is a diagnostic mechanism in Kubernetes executed periodically by the node agent (kubelet) to determine whether an application inside a container is running prop...
🟢 Junior Level
30-Second Summary
A Liveness Probe is a diagnostic mechanism in Kubernetes executed periodically by the node agent (kubelet) to determine whether an application inside a container is running properly or has frozen into an unrecoverable state.
If a containerized process hangs (due to a Java thread deadlock, an infinite loop, or a corrupted state machine), the Linux operating system still considers the process ID active, even though it can no longer serve traffic:
kubeletsends a periodic probe request (HTTP, TCP, gRPC, or exec command).- If the application fails to respond or returns an error several times consecutively (
failureThreshold), Kubernetes deems the container dead and forcibly terminates and restarts it (Self-Healing).
Real-World Analogy
A Liveness Probe acts like a heart rate monitor on an intensive care patient:
- The attending nurse (
kubelet) checks the patient’s pulse every 10 seconds. - As long as the heart beats steadily, no medical intervention is needed.
- If the pulse stops for three consecutive checks, the medical team immediately applies a defibrillator (container restart) to shock the system back into functional operation.
Basic Manifest for Spring Boot 3 on Java 21
apiVersion: v1
kind: Pod
metadata:
name: payment-app
spec:
containers:
- name: payment-service
image: payment-service:1.0
livenessProbe:
httpGet:
path: /actuator/health/liveness # Spring Boot Actuator liveness endpoint
port: 8080
initialDelaySeconds: 30 # Delay before first check to allow JVM startup
periodSeconds: 10 # Probe interval (every 10 seconds)
timeoutSeconds: 3 # Max duration to wait for response
failureThreshold: 3 # Restart container after 3 consecutive failures
[!IMPORTANT] Primary Goal of Liveness: Detect situations where the application is completely deadlocked or corrupted and cannot self-recover without a full process restart.
🟡 Middle Level
The 4 Probe Execution Mechanisms
| Mechanism | Operational Mechanism | Standard Use Case |
|---|---|---|
httpGet |
Kubelet sends an HTTP GET request. Status codes 200–399 are considered successful. |
Web applications, REST APIs (Spring Boot Actuator). |
tcpSocket |
Validates that a TCP socket connection can be established on the specified port. | Databases, caches (PostgreSQL, Redis), message brokers. |
grpc |
Invokes the official gRPC Health Checking Protocol (K8s 1.24+ GA). | High-performance microservices communicating over gRPC. |
exec |
Executes a shell command inside the container namespace (exit code 0 = success). |
Legacy systems, checking internal lockfiles (test -f /tmp/ok). |
Cardinal Architectural Rule: Liveness vs. External Dependencies
[!CAUTION] NEVER CHECK EXTERNAL DEPENDENCIES (DATABASES, KAFKA, DOWNSTREAM APIS) IN A LIVENESS PROBE!
The Cascading Death Spiral Scenario:
- Your production PostgreSQL database experiences a temporary latency spike or connection pool saturation for 15 seconds.
- If your 50 Java backend pods evaluate database health inside their liveness probes, all 50 probes simultaneously fail.
- Kubelet across the cluster kills and restarts all 50 pods at once!
- As all 50 pods restart simultaneously, their HikariCP connection pools hammer the recovering database with thousands of concurrent connection requests, crashing the database permanently.
- Rule: A Liveness Probe must evaluate STRICTLY internal container health (memory, thread deadlocks, local event loops). External dependencies must be delegated solely to the Readiness Probe.
Native Support in Spring Boot Actuator
Spring Boot 2.3+ and Spring Boot 3+ automatically integrate with Kubernetes by exposing dedicated health group probes:
http://localhost:8080/actuator/health/liveness— Exposes internal container health (LivenessState). Excludes all remote database, cache, and broker checks.http://localhost:8080/actuator/health/readiness— Checks connection pool readiness, database connectivity, and messaging queues.
Enable both probes in application.yaml:
management:
health:
livenessstate:
enabled: true
readinessstate:
enabled: true
endpoint:
health:
probes:
enabled: true
🔴 Senior Level
The Tandem of startupProbe and livenessProbe
A classic operational challenge with enterprise Java applications is slow cold startup (Spring Boot context scanning, Liquibase/Flyway migrations, and JPA metamodel generation often take 40–90 seconds):
- If you configure
initialDelaySeconds: 15, the Liveness Probe kills a healthy JVM mid-initialization, triggering a boot-loop. - If you configure
initialDelaySeconds: 90, when a deadlock occurs in production during steady state, Kubelet waits 90 seconds before taking initial recovery action.
The Solution — startupProbe:
containers:
- name: payment-service
image: payment-service:1.0
startupProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
periodSeconds: 5
failureThreshold: 30 # Grants 30 * 5s = 150 seconds for cold initialization!
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
periodSeconds: 10
failureThreshold: 3 # Fast 30-second response window to runtime deadlocks
Until startupProbe succeeds, both livenessProbe and readinessProbe remain completely disabled!
HotSpot JVM Internals: False Positives During STW Full GC Pauses
When the JVM garbage collector (e.g., Parallel GC, or G1 experiencing memory fragmentation) triggers a heavy Stop-The-World (STW) Full GC:
- All application execution threads (including embedded Tomcat/Netty request acceptor and worker threads) are paused by the JVM safepoint mechanism.
- A probe packet dispatched by
kubeletarrives at the container network interface, but Tomcat cannot construct or return an HTTP response. - If
timeoutSeconds: 1is configured aggressively, Kubelet records a probe failure. Three consecutive STW pauses will prompt Kubelet to terminate a healthy JVM simply busy reclaiming memory. Recommendation: SettimeoutSeconds: 3to5andfailureThreshold: 3to provide adequate tolerance for temporary GC spikes.
Programmatic State Invalidation in Spring Boot 3
Java code can programmatically signal Kubernetes to trigger a container restart upon discovering unrecoverable background corruption:
@Service
public class CriticalWorkerService {
private final ApplicationEventPublisher eventPublisher;
public CriticalWorkerService(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void processCriticalQueue() {
try {
// Process mission-critical background queue
} catch (FatalCorruptionException ex) {
// Transition LivenessState to BROKEN -> Actuator returns HTTP 503
// Kubelet registers probe failure and orchestrates container restart
AvailabilityChangeEvent.publish(eventPublisher, this, LivenessState.BROKEN);
}
}
}
4 Tricky Questions
1. What happens if a container fails its Liveness Probe, but the Pod manifest specifies restartPolicy: Never?
Answer:
Kubelet will NOT restart the container.
Under Kubernetes pod lifecycle rules, if restartPolicy: Never is set:
- Kubelet forcefully stops the unresponsive container by sending
SIGTERM, followed bySIGKILL. - However, because restarts are explicitly disabled, Kubelet does not attempt to recreate the container.
- The container transitions into
Terminatedstatus, and the entire Pod permanently transitions into the terminalFailedphase until manually deleted or garbage-collected by the controller.
2. How can you detect a multithreaded Java Deadlock in production using a Liveness Probe?
Answer:
By registering a custom Spring Boot Actuator HealthIndicator utilizing the JVM’s ThreadMXBean:
@Component
public class DeadlockHealthIndicator implements HealthIndicator {
private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
@Override
public Health health() {
long[] deadlocked = threadBean.findDeadlockedThreads();
if (deadlocked != null && deadlocked.length > 0) {
return Health.down()
.withDetail("deadlockedThreadsCount", deadlocked.length)
.build();
}
return Health.up().build();
}
}
If two or more threads enter a circular monitor wait deadlock, the health indicator immediately reports DOWN (HTTP 503). Kubelet detects the failure and restarts the JVM container, resolving the deadlock without human intervention.
3. What is the fundamental difference in Kubernetes action when a livenessProbe fails versus when a readinessProbe fails?
Answer:
livenessProbeFailure: Kubernetes executes a destructive action — it terminates and restarts the container. The Pod IP remains unchanged, but inflight in-memory state is erased, and restart counts increment.readinessProbeFailure: Kubernetes executes a non-destructive routing action — it does NOT restart the container. Instead, it dynamically removes the Pod’s IP address from the ServiceEndpoints/EndpointSlice. The Pod remains running and can continue executing background tasks or completing existing requests, but no new external client traffic will be routed to it until the probe returns HTTP 200 again.
4. Why is executing Liveness Probes via the exec mechanism (e.g., command: ["curl", "localhost:8080/health"]) considered an anti-pattern in high-throughput workloads?
Answer:
When using exec, Kubelet instructs the container runtime (containerd / CRI-O) to fork and spawn a brand-new operating system process inside the container namespace for every health check interval:
- Spawning OS processes (
fork + exec) consumes substantial CPU and memory descriptors and triggers kernel context switches, especially when repeated across dozens of containers every 5 seconds. - Modern security best practices utilize Distroless or minimal Alpine base images that do not contain
curl,wget, or shell interpreters (sh/bash). - Native
httpGetprobes open a direct TCP socket connection from Kubelet to the container port over the host network bridge with zero process-spawn overhead.
🎯 Interview Cheat Sheet
Core Liveness Probe Architecture
- Primary Function: Verifies container process health; triggers a container restart on repeated failures.
- Golden Invariant: Never evaluate external databases, caches, or third-party APIs in a Liveness Probe.
- Startup Probe Coupling: Pair slow-booting JVM apps with
startupProbeto avoid false initial restart loops. - Spring Boot 3 Actuator: Always leverage the dedicated
/actuator/health/livenessendpoint. - GC STW Tolerance: Ensure
timeoutSeconds(3–5s) exceeds typical Full GC pauses to avoid false restarts. - Liveness vs. Readiness: Liveness restarts the container; Readiness removes the Pod from Service load balancers.
Comparison of the 3 Probe Types
| Probe Type | Execution Window | Action on Failure | Core Objective |
| :— | :— | :— | :— |
| startupProbe | During container boot only | Terminates and restarts container | Grants long grace window for JVM classloading |
| livenessProbe | After startup succeeds, continuous | Restarts container | Unfreezes deadlocks and infinite loops |
| readinessProbe | After startup succeeds, continuous | Removes Pod from Service Endpoints | Protects against traffic surges & warm-up latency |
Red Flags (What NOT to Say)
- ❌ “Our Liveness Probe connects to Postgres and Kafka to verify cluster connectivity.” — Guarantees a cluster-wide Cascading Death Spiral during database failovers.
- ❌ “Setting
initialDelaySeconds: 5is best practice for Spring Boot microservices.” — The JVM will not finish loading before Kubelet kills it. - ❌ “Liveness and Readiness probes can both point to
/actuator/healthwithout parameters.” — Default Actuator/healthincludes database checks, violating the isolation rule.
Related Topics
- What is readiness probe — Gating user traffic dynamically
- Why are health checks needed — Production observability strategy
- How to organize rolling update in Kubernetes — Zero-downtime rolling deployments
- What is Pod in Kubernetes — Pod container lifecycle management