Back to blog
DevOps & Kubernetes September 10, 2026

Kubernetes Ingress & Pod Health Monitoring: Liveness, Readiness, and CrashLoopBackOff Runbooks

Automate WhatsApp Alerts
Start Free ➔

In Kubernetes production clusters, workload availability is frequently misunderstood. A pod reporting a Running phase does not mean it is capable of serving user traffic. Conversely, an aggressively configured liveness probe can trigger cascading container restart storms, while a misconfigured readiness probe can silently remove all healthy endpoints from an Ingress controller, returning HTTP 502 Bad Gateway and 503 Service Unavailable errors to end users.

Mastering Kubernetes traffic routing and pod reliability requires understanding the discrete boundaries between Ingress controllers, Service EndpointSlices, and container lifecycle probes (Startup, Liveness, and Readiness), alongside structured runbooks for triaging CrashLoopBackOff states and OOMKilled events.

This guide details the complete Kubernetes dataplane request lifecycle, provides mathematical models for probe detection latencies and exponential backoff timings, establishes an SRE probe configuration matrix, and delivers production debugging runbooks.


1. Kubernetes Traffic & Dataplane Request Flow

The path from an external user request to an application container inside a pod traverses multiple abstraction layers:

External Client / Browser
         │
         ▼ (DNS Resolution & Public IP)
[ Cloud Load Balancer (AWS NLB / GCP GLB) ]
         │
         ▼ (TCP :443 / TLS Termination)
[ Ingress Controller (Nginx / Envoy / Traefik) ]
         │
         ├── Path & Host Matching Rules (Prefix / Exact)
         └── EndpointSlice Discovery (Kube-API Watcher)
         │
         ▼ (ClusterIP / Direct Pod IP Routing)
[ Target Pod IP :targetPort ]
         │
         ├─► [ Startup Probe ]   (Suppresses Liveness/Readiness during boot)
         ├─► [ Liveness Probe ]  (Restarts container on process deadlock)
         └─► [ Readiness Probe ] (Toggles EndpointSlice traffic routing)

1.1 Why a "Running" Pod Still Fails Traffic

In Kubernetes, a pod's status reflects its container runtime state, not its network readiness:

  • A container with an active PID is marked Running by the kubelet even if it is stuck in a database connection deadlock.
  • If the pod's Readiness Probe fails, the EndpointSlice controller unlinks the pod's IP from the upstream Service.
  • The Ingress controller receives zero healthy backends and immediately returns HTTP 503 Service Temporarily Unavailable to clients, despite all pods showing green in basic dashboard views.

2. Startup vs Liveness vs Readiness Probes

Understanding the distinct responsibilities of the three probe types prevents self-inflicted production outages.

Probe TypePrimary QuestionFailure ConsequenceIdeal Use CaseAnti-Pattern to Avoid
StartupHas the application finished bootstrapping?Blocks liveness/readiness evaluation until success or timeoutHeavy JVM, Django, or Rails apps with long warmup timesOmitting startup probes and artificially inflating liveness delay
LivenessIs the container process deadlocked or unrecoverable?Kubelet terminates and restarts the container (SIGKILL)Catching fatal thread deadlocks or infinite loopsChecking external databases or downstream microservices
ReadinessIs the pod currently able to accept network requests?Kubelet removes pod IP from Service EndpointSlicesWarmup caching, temporary overload, DB reconnectsTriggering restarts on temporary downstream outages

3. Mathematical Models for Kubernetes Health Probes

3.1 Failure Detection Latency Model

The time required for Kubernetes to detect a failing pod and initiate remediation is calculated as:

[ T_{\text{detect}} \approx D_{\text{initial}} + \left( F_{\text{threshold}} \times P_{\text{period}} \right) + T_{\text{timeout}} ]

Where:

  • ( D_{\text{initial}} ): initialDelaySeconds before the first probe executes.
  • ( F_{\text{threshold}} ): failureThreshold (number of consecutive failures before taking action).
  • ( P_{\text{period}} ): periodSeconds between successive probe executions.
  • ( T_{\text{timeout}} ): timeoutSeconds allocated per probe attempt.

If a readiness probe has ( F = 3 ) and ( P = 10,\text{s} ), a failed pod remains in the EndpointSlice pool for up to 30 seconds, continuing to receive and drop live customer traffic during an incident.

3.2 CrashLoopBackOff Exponential Backoff Equation

When a container crashes repeatedly, the kubelet delays subsequent restarts according to an exponential backoff formula:

[ T_{\text{backoff}} = \min\left(T_{\text{max}},, T_{\text{base}} \times 2^{r - 1}\right) ]

Where:

  • ( T_{\text{base}} = 10,\text{seconds} )
  • ( T_{\text{max}} = 300,\text{seconds} ) (5 minutes)
  • ( r ): Number of consecutive container restarts.
Restart Timeline:
Crash 1 ──► Wait 10s ──► Crash 2 ──► Wait 20s ──► Crash 3 ──► Wait 40s ──► Crash 4 ──► Wait 80s ──► Max 300s

To evaluate allowed downtime windows and quantify how probe delays consume your monthly error budget, use the SLA Calculator and Downtime Calculator.


4. Production Kubernetes Probe Configuration Pattern

Below is a battle-tested Kubernetes deployment manifest separating startup, liveness, and readiness responsibilities:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: payment-orchestrator
  namespace: production
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: payment-orchestrator
    spec:
      terminationGracePeriodSeconds: 45
      containers:
        - name: app
          image: payment-orchestrator:v3.2.1
          ports:
            - name: http
              containerPort: 8080
          resources:
            requests:
              cpu: "500m"
              memory: "512Mi"
            limits:
              cpu: "2000m"
              memory: "1024Mi"
          # Startup Probe: Grants up to 150s for DB migration and JIT warmup
          startupProbe:
            httpGet:
              path: /health/startup
              port: http
            periodSeconds: 5
            failureThreshold: 30
            timeoutSeconds: 3
          # Liveness Probe: Strictly evaluates internal thread responsiveness
          livenessProbe:
            httpGet:
              path: /health/liveness
              port: http
            periodSeconds: 10
            timeoutSeconds: 2
            failureThreshold: 3
          # Readiness Probe: Checks local connection pools and cache warmup
          readinessProbe:
            httpGet:
              path: /health/readiness
              port: http
            periodSeconds: 5
            timeoutSeconds: 2
            failureThreshold: 2
            successThreshold: 1

5. Ten-Step Troubleshooting Runbook: CrashLoopBackOff

When a pod enters CrashLoopBackOff, execute this step-by-step diagnostic workflow:

  1. Inspect container state and exit metadata to extract the exact exit code and termination reason:
    kubectl get pod <pod-name> -n <namespace> -o jsonpath='{range .status.containerStatuses[*]}{"Container: "}{.name}{"\nRestart Count: "}{.restartCount}{"\nExit Code: "}{.lastState.terminated.exitCode}{"\nReason: "}{.lastState.terminated.reason}{"\nMessage: "}{.lastState.terminated.message}{"\n"}{end}'
    
  2. Review the previous container execution logs before the crash occurred:
    kubectl logs <pod-name> -n <namespace> -c <container-name> --previous --tail=100
    
  3. Check for OOMKilled events (Exit Code 137): If the exit reason is OOMKilled, the container exceeded its configured resources.limits.memory. Increase memory allocation or optimize heap limits.
  4. Check for Graceful Shutdown Timeouts (Exit Code 143): Indicates a SIGTERM timed out and was killed by SIGKILL. Review terminationGracePeriodSeconds.
  5. Inspect Kubernetes cluster events sorted chronologically to detect missing ConfigMaps, failed Secrets, or storage volume mount failures:
    kubectl get events -n <namespace> --sort-by='.metadata.creationTimestamp' | tail -n 25
    
  6. Verify entrypoint syntax and binary permissions: Exit Code 127 indicates a missing executable command in the container image.
  7. Evaluate liveness probe timing: Check if the container was killed by kubelet due to an unhandled timeout on /healthz.
  8. Inspect CPU throttling metrics: Check if CPU limits are throttling the application event loop, causing health probes to time out.
  9. Launch an ephemeral debug container to inspect environment variables and network reachability from inside the pod namespace:
    kubectl debug -it <pod-name> -n <namespace> --image=curlimages/curl -- /bin/sh
    
  10. Initiate deployment rollback if the crash correlates with a recent container image release or environment variable change:
    kubectl rollout undo deployment/<deployment-name> -n <namespace>
    

6. Ten-Step Troubleshooting Runbook: Ingress & Endpoint Failures

When external clients receive HTTP 502, 503, or 504 errors at the Ingress boundary:

  1. Verify public DNS resolution for the target hostname using independent recursive and authoritative lookups:
    dig +short api.pingzoapp.com
    
    (Use our free DNS Lookup tool to verify global propagation).
  2. Inspect TLS certificate validity and SNI handshake:
    openssl s_client -connect api.pingzoapp.com:443 -servername api.pingzoapp.com -alpn h2,http/1.1 </dev/null
    
    (Use our SSL Inspector to verify intermediate certificate chains).
  3. Check Ingress resource rules and backend service definitions:
    kubectl describe ingress <ingress-name> -n <namespace>
    
  4. Verify EndpointSlice status: Ensure target pods have ready=true conditions:
    kubectl get endpointslices -n <namespace> -l kubernetes.io/service-name=<service-name>
    
  5. Inspect Ingress Controller error logs to identify upstream connection timeouts or protocol negotiation errors:
    kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=200 | grep -E "502|503|504"
    
  6. Validate Service selector labels: Ensure spec.selector in the Service exactly matches spec.template.metadata.labels in the Deployment.
  7. Test pod reachability directly inside the cluster using port forwarding:
    kubectl port-forward pod/<pod-name> -n <namespace> 8080:8080
    curl -sv http://localhost:8080/health/readiness
    
  8. Check for connection reuse and keep-alive mismatches: Ensure upstream proxy keep-alive timeouts exceed application idle timeouts to avoid race-condition TCP resets.
  9. Inspect container network interface (CNI) health across nodes to confirm kube-proxy or Cilium/Calico eBPF routing rules are synchronizing correctly.
  10. Execute synthetic end-to-end multi-region checks to confirm traffic restoration after fixing ingress routing.

7. Prometheus Alerting Rules for Kubernetes Reliability

Implement production PromQL alerts to detect pod instability before customer error budgets are exhausted:

groups:
  - name: kubernetes_workload_alerts
    rules:
      # Alert on Container CrashLoopBackOff or high restart rates
      - alert: PodCrashLooping
        expr: |
          rate(kube_pod_container_status_restarts_total{job="kube-state-metrics"}[5m]) * 60 > 0.5
        for: 3m
        labels:
          severity: critical
          tier: kubernetes
        annotations:
          summary: "Pod {{ $labels.pod }} is restarting rapidly in namespace {{ $labels.namespace }}"
          description: "Container {{ $labels.container }} restart rate is {{ $value | humanize }} restarts/min."

      # Alert when Service has 0 ready endpoints
      - alert: ServiceEndpointsUnavailable
        expr: |
          kube_endpoint_address_available{job="kube-state-metrics"} == 0
        for: 1m
        labels:
          severity: critical
          tier: traffic-routing
        annotations:
          summary: "Service {{ $labels.endpoint }} has 0 ready endpoints"
          description: "Ingress cannot route traffic. All pods are failing readiness or terminating."

      # Alert on Container Memory Working Set approaching Limit (OOM risk)
      - alert: ContainerMemoryNearLimit
        expr: |
          (
            container_memory_working_set_bytes{container!=""}
            /
            container_spec_memory_limit_bytes{container!=""}
          ) > 0.88
        for: 2m
        labels:
          severity: warning
          tier: resources
        annotations:
          summary: "Container {{ $labels.container }} in pod {{ $labels.pod }} near OOM limit"
          description: "Memory utilization is at {{ $value | humanizePercentage }} of configured limit."

8. SRE Kubernetes Hardening Checklist

  • Configure Startup Probes: Protect slow-booting containers from premature liveness termination.
  • Isolate Liveness Checks: Ensure liveness probes do not check external databases or message brokers.
  • Set Conservative Failure Thresholds: Require at least 2–3 consecutive probe failures before unrouting or restarting pods.
  • Set Realistic Resource Requests & Limits: Avoid overcommitting node memory to prevent Linux OOM Killer invocations.
  • Deploy Global External Probes: Complement internal Kubernetes health checks with external synthetic probes from Pingzo.

Related SRE Architecture & Incident Runbooks

When refining your Kubernetes reliability and ingress observability, cross-reference these engineering guides:

Zero-Code Uptime Alerts

Stop Finding Out About Outages from Angry Users

Get instant WhatsApp & Discord alerts the second your API, website, or server goes down. Setup in 30 seconds with 60-second checks.

WhatsApp & Discord 60-Second Checks Free Forever Plan
Try Pingzo Free

Know before your users do

Connect official WhatsApp notification channels, Discord webhooks, Telegram bots, and public status pages. Start in 30 seconds.

Create Free Monitor