Target Audience: Backend developers who want to monitor application status in Kubernetes Prerequisites: Pod, Deployment concepts After reading this: You will understand the differences between Liveness, Readiness, and Startup Probes and how to configure them

TL;DR
  • Liveness Probe: Check if container is alive, restart on failure
  • Readiness Probe: Check if ready to receive traffic, remove from service on failure
  • Startup Probe: Check startup completion, other Probes disabled until completion

Why Health Checks are Needed?#

A Running container doesn’t mean the application is healthy.

SituationContainer StateActual State
Deadlock occurredRunningCannot respond
DB connection lostRunningService unavailable
Starting upRunningNot ready
Memory shortageRunningSlow response

Health checks allow us to detect these situations and respond automatically.

Probe Types Comparison#

flowchart TB
    subgraph Probes
        LP[Liveness Probe<br>Are you dead?]
        RP[Readiness Probe<br>Are you ready?]
        SP[Startup Probe<br>Have you started?]
    end

    LP -->|failure| RESTART[Restart container]
    RP -->|failure| REMOVE[Remove from service]
    SP -->|failure| WAIT[Continue waiting]

Comparing characteristics of each Probe:

ProbeQuestionAction on FailureWhen to Use
LivenessAre you alive?Restart containerAlways
ReadinessAre you ready?Remove from serviceAlways
StartupHave you started?WaitOnly at startup

Liveness Probe#

Checks if application is operating normally. On failure, kubelet restarts the container.

HTTP Check#

apiVersion: v1
kind: Pod
metadata:
  name: liveness-http
spec:
  containers:
  - name: app
    image: my-app:1.0
    livenessProbe:
      httpGet:
        path: /health
        port: 8080
      initialDelaySeconds: 30
      periodSeconds: 10
      timeoutSeconds: 5
      failureThreshold: 3

TCP Check#

Checks if port is open.

livenessProbe:
  tcpSocket:
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 20

Command Execution Check#

livenessProbe:
  exec:
    command:
    - cat
    - /tmp/healthy
  initialDelaySeconds: 5
  periodSeconds: 5

Probe Configuration Values#

SettingDefaultDescription
initialDelaySeconds0Wait time before first check
periodSeconds10Check interval
timeoutSeconds1Response wait time
successThreshold1Consecutive successes for success
failureThreshold3Consecutive failures for failure

Readiness Probe#

Checks if application is ready to receive traffic. On failure, removed from Service Endpoints.

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
  failureThreshold: 3

Readiness vs Liveness#

SituationReadinessLiveness
DB connection lostFail (exclude traffic)Success (no restart needed)
Loading configurationFail (not ready)Success (operating normally)
DeadlockFailFail (restart needed)
flowchart LR
    SVC[Service] --> EP[Endpoints]
    EP --> P1[Pod 1 ✓ Ready]
    EP --> P2[Pod 2 ✓ Ready]
    EP -.-x P3[Pod 3 ✗ Not Ready]

Startup Probe#

Used when application takes long to start. Liveness/Readiness Probes are disabled until Startup Probe succeeds.

startupProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 10
  failureThreshold: 30  # Wait max 5 minutes (10s × 30)

Why is Startup Probe Needed?#

Wouldn’t setting Liveness Probe’s initialDelaySeconds longer work?

MethodProblem
Use only Liveness, long initialDelayCheck interval remains long after startup
Startup + LivenessLong wait only at startup, short interval afterwards
sequenceDiagram
    participant K as Kubelet
    participant C as Container

    Note over K,C: Startup Phase
    K->>C: Startup Probe
    C-->>K: Failure (starting)
    K->>C: Startup Probe
    C-->>K: Success!

    Note over K,C: Operation Phase
    K->>C: Liveness Probe
    C-->>K: Success
    K->>C: Readiness Probe
    C-->>K: Success

Real Example: Spring Boot#

Example Probe configuration for Spring Boot application.

Spring Boot Actuator Configuration#

# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health
  endpoint:
    health:
      probes:
        enabled: true
  health:
    livenessState:
      enabled: true
    readinessState:
      enabled: true

Spring Boot Actuator provides these endpoints:

EndpointPurpose
/actuator/health/livenessLiveness Probe
/actuator/health/readinessReadiness Probe
/actuator/healthOverall status

Kubernetes Probe Configuration#

apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: spring-app
  template:
    metadata:
      labels:
        app: spring-app
    spec:
      containers:
      - name: app
        image: spring-app:1.0
        ports:
        - containerPort: 8080
        startupProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 10
          failureThreshold: 30
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          periodSeconds: 5
          failureThreshold: 3
Application TypestartupProbelivenessProbereadinessProbe
Fast startup (< 30s)OptionalRequiredRequired
Slow startup (> 30s)RequiredRequiredRequired
Has external dependenciesOptionalSimple checkInclude dependency check

Health Check Endpoint Design#

ProbeWhat to Check
LivenessProcess survival only (fast and simple)
ReadinessExternal dependencies (DB, cache, external API)
Caution with External Dependencies in Liveness
Checking DB connection in Liveness Probe can worsen the situation by restarting all Pods on DB failure. Check external dependencies in Readiness Probe.

Troubleshooting#

Pod Keeps Restarting#

# Check events
kubectl describe pod <pod-name>

# Check logs
kubectl logs <pod-name> --previous

Common causes:

CauseSolution
Insufficient initialDelaySecondsUse Startup Probe or increase value
Insufficient timeoutSecondsIncrease value or optimize endpoint
Wrong health check pathVerify path and port

Cannot Receive Traffic Due to Readiness Failure#

# Check Endpoints
kubectl get endpoints <service-name>

# Check Pod Ready status
kubectl get pods -o wide

If Endpoints is empty, Readiness Probe is failing.

Practice: Configuring and Testing Probes#

Check Probe Operation#

apiVersion: v1
kind: Pod
metadata:
  name: probe-test
spec:
  containers:
  - name: app
    image: nginx:1.25
    ports:
    - containerPort: 80
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5
    readinessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5
# Create Pod
kubectl apply -f probe-test.yaml

# Monitor events
kubectl get events --watch

# Simulate Probe failure
kubectl exec probe-test -- rm /usr/share/nginx/html/index.html

# Check Pod status (restart occurs)
kubectl get pods -w

Next Steps#

Once you understand health checks, proceed to the next steps:

GoalRecommended Doc
Troubleshoot PodsPod Troubleshooting
Actual deployment practiceSpring Boot Deployment
Auto-scalingScaling