# Pod Failures & Application Issues ## Target-Bound Pod Evidence Use the shipped collector instead of streaming raw logs into model context. It verifies the kube context against the named AKS resource before any Kubernetes API read, captures current and previous logs across all containers, and keeps the raw log files in a caller-selected artifact directory. ```bash AKS_SUBSCRIPTION_ID= \ scripts/pod-deep-dive.sh \ \ ``` The model-visible projection redacts credential-shaped values and is capped at 50 lines per current/previous log stream. Inspect expanded raw evidence only outside model context. --- ## CrashLoopBackOff Pod starts, crashes, restarts with exponential backoff (10s, 20s, 40s... up to 5m). **Diagnostics:** ```bash kubectl describe pod -n # Check: Exit Code, Reason, Last State, Events ``` Use the `Previous Logs` section from `pod-deep-dive.sh`; it preserves the last crashed container output without exposing the raw stream. **Decision tree:** | Exit Code | Meaning | Fix Path | | --------- | ----------------------------------------------------- | ------------------------------------------------------------- | | `0` | App exited successfully (unexpected for long-running) | Check if entrypoint/command is correct; app may be a one-shot | | `1` | Application error | Read logs - unhandled exception, missing config, bad startup | | `137` | OOMKilled (SIGKILL) | Increase `resources.limits.memory`; check for memory leaks | | `139` | Segfault (SIGSEGV) | Binary compatibility issue or native code bug | | `143` | SIGTERM - graceful shutdown | Pod was terminated; check if liveness probe killed it | **OOMKilled specifically:** ```bash kubectl describe pod -n | grep -A2 "Last State" # Reason: OOMKilled -> container exceeded memory limit ``` Fix: increase `resources.limits.memory` or optimize application memory usage. Check `kubectl top pod -n ` for actual usage. **OOM kill tracing with Inspektor Gadget:** Use `trace_oomkill` (timeout 30) with `--k8s-namespace --k8s-podname ` to see which process was killed and memory at kill time. See [references/inspektor-gadget.md](references/inspektor-gadget.md). **Deep diagnostics with Inspektor Gadget** (when logs and describe are inconclusive): Use the [IG base command pattern](references/inspektor-gadget.md) with `--k8s-namespace --k8s-podname ` and these gadgets: - `trace_exec` (timeout 30) — see what the container executes at startup - `trace_open` (timeout 30) — find missing configs/secrets (retval -2 = ENOENT, -13 = EACCES) - `snapshot_process` (timeout 5) — list running processes in the pod See [references/inspektor-gadget.md](references/inspektor-gadget.md). --- ## ImagePullBackOff Pod can't pull the container image. **Diagnostics:** ```bash kubectl describe pod -n # Events section shows the exact pull error ``` | Error Message | Cause | Fix | | --------------------------------------- | ---------------------------- | -------------------------------------------------------------- | | `ErrImagePull` / `ImagePullBackOff` | Image name or tag is wrong | Verify image name and tag exist in the registry | | `unauthorized: authentication required` | Missing or wrong pull secret | Create/update `imagePullSecrets` on the pod or service account | | `manifest unknown` | Tag doesn't exist | Check available tags in the registry | | `context deadline exceeded` | Registry unreachable | Check network/firewall; for ACR, verify AKS -> ACR integration | **ACR integration check:** ```bash # Verify AKS is attached to ACR az aks check-acr -g -n --acr .azurecr.io ``` --- ## Pending Pods Pod stays in `Pending` - scheduler can't place it. **Diagnostics:** ```bash kubectl describe pod -n # Events section shows why scheduling failed ``` | Event Message | Cause | Fix | | ---------------------------------------------------------------------- | ----------------------------------- | --------------------------------------------------------------- | | `Insufficient cpu` / `Insufficient memory` | No node has enough resources | Scale node pool; reduce resource requests; check for overcommit | | `node(s) had taint ... that the pod didn't tolerate` | Taint/toleration mismatch | Add matching toleration or use a different node pool | | `node(s) didn't match Pod's node affinity/selector` | Affinity rule unsatisfiable | Check `nodeSelector` or `nodeAffinity` rules | | `persistentvolumeclaim ... not found` / `unbound` | PVC not ready | Check PVC status; verify storage class exists | | `0/N nodes are available: N node(s) had volume node affinity conflict` | Zonal disk vs pod in different zone | Use ZRS storage class or ensure same zone | --- ## Readiness & Liveness Probe Failures **Readiness probe failure** -> pod removed from Service endpoints (no traffic). **Liveness probe failure** -> pod killed and restarted. **Diagnostics:** ```bash kubectl describe pod -n # Look for: "Readiness probe failed" or "Liveness probe failed" in Events # Check the pod's READY column - must show n/n kubectl get pod -n ``` | Symptom | Cause | Fix | | ------------------------------------ | ----------------------- | ---------------------------------------------------------- | | READY shows `0/1` but pod is Running | Readiness probe failing | Check probe path, port, and app health endpoint | | Pod restarts repeatedly | Liveness probe failing | Increase `initialDelaySeconds`; check if app starts slowly | | Probe timeout errors | App responds too slowly | Increase `timeoutSeconds`; check app performance | > 💡 **Tip:** Set `initialDelaySeconds` on liveness probes to be longer than your app's startup time. A common mistake is killing pods before they finish initializing. --- ## Resource Constraints (CPU/Memory) **Check actual usage vs limits:** ```bash kubectl top pod -n kubectl top pod -n --sort-by=memory # Compare with requests/limits kubectl get pod -n -o jsonpath='{.spec.containers[*].resources}' ``` | Symptom | Cause | Fix | | -------------------------------- | --------------------------------------- | --------------------------------------------------- | | OOMKilled (exit code 137) | Container exceeded memory limit | Increase `limits.memory` or fix memory leak | | CPU throttling (slow responses) | Container hitting CPU limit | Increase `limits.cpu` or remove CPU limits | | Pending - insufficient resources | Requests exceed available node capacity | Lower requests, scale nodes, or use larger VM sizes | > ⚠️ **Warning:** Setting CPU limits can cause unnecessary throttling even when the node has spare capacity. Many teams set CPU requests but not limits. Memory limits should always be set.