WIUNIX ACADEMY
CrashLoopBackOff or OOMKilled? Diagnose the failed container before restarting it
Correlate previous logs, termination state, probes, resource limits and rollout history; choose a bounded recovery and prove it remains healthy.
Make this guide yoursYOUR SYSTEM. YOUR STEPS.
Where are you working?
Choose your OS and version. The prerequisites, commands and troubleshooting follow your environment.
USE YOUR OWN VALUES
Configure this tutorial
Set the example values for your environment; related explanations and copy panels update together. Never enter passwords, private keys or tokens. Values stay in this tab and are not sent to the server or share links. Check actual DNS, certificates and network policy before running commands.
Different IP addresses, domains or ports? Open the settings below, change the values and select “Apply to tutorial”, then copy the updated commands.
Set values for my environment7 editable values
THE OUTCOME
What will you have at the end?
Distinguish application exit, memory kill, failed probes and node pressure, then recover one owned Deployment with evidence.
Supported operating systems and versions
Documented Linux kubectl workflow for an existing Kubernetes cluster. No local crash, memory stress or production command execution is claimed. The current tutorial form accepts simple identifiers of at most32characters. This is a form limitation, not the Kubernetes resource-name limit. Never truncate or rename a live object to fit. For a longer existing resource/context name, follow this same diagnostic sequence in the operator-owned direct CLI/editor workflow with its exact original name; no silent default substitution.
Before you begin
- Authorized Kubernetes context and a noncritical owned Deployment
- kubectl supported for the server version; read access to Pod state/logs/events
- Metrics access and historical application telemetry if available
- The current tutorial form accepts simple identifiers of at most32characters. This is a form limitation, not the Kubernetes resource-name limit. Never truncate or rename a live object to fit. For a longer existing resource/context name, follow this same diagnostic sequence in the operator-owned direct CLI/editor workflow with its exact original name; no silent default substitution.
LET’S BUILD
Prepare the selected operator host
These are operator-host packages only. Review the transaction before approving; do not install tools inside application containers. The cluster, server and application binaries must already exist with owner-approved versions. Use Bash for the following panels. Package installation changes this selected host but starts no new application server.
Use an existing Linux kubectl within one minor version of every API-server version; inspect the actual server version in the authorized context before proceeding. Do not install kubelet/kubeadm or overwrite cluster client repositories for this diagnosis.
Selected operator host; approved package transaction
sudo dnf install ca-certificates bash coreutils
if ! command -v curl >/dev/null 2>&1; then sudo dnf install curl; fi
cat /etc/os-release
command -v bash curl timeout
command -v kubectl
kubectl version --client --output=yamlThe OS/version matches the selection, required tools resolve, and existing application/client versions satisfy the stated compatibility boundary. Stop if a binary is missing or incompatible.
Preserve host security and existing paths
Keep SELinux enforcing and firewalld rules in place. These client-side diagnostics require outbound access to the approved API/TLS/SFTP destination; they need no new inbound host port. A failure in a confined systemd service may differ from an interactive shell. Review AVC denials, file labels and service permissions with the policy owner rather than disabling SELinux, broad allow rules or disabling the firewall. Trust-chain/crypto-policy failures require a compatible endpoint, not weakened system crypto. Existing custom data/config paths need their established labels; never run a recursive relabel blindly.
Selected operator host; read-only security inspection
if command -v getenforce >/dev/null 2>&1; then getenforce; fi
if command -v firewall-cmd >/dev/null 2>&1; then firewall-cmd --state; fiDefine what the status does and does not mean
CrashLoopBackOff is a waiting/backoff condition following repeated container failures; it is not the root cause or a Pod phase. OOMKilled is a termination reason. A Pod may remain Running while a container restarts. Inspect the correct container, including init containers and sidecars, before drawing conclusions.
Use an existing noncritical Deployment whose owner can approve a rollout. This guide does not create crashes, raise limits automatically or delete a Pod to make a counter disappear. Keep timestamps, revision, container name and a short private incident record. Logs may contain user data or secrets: review locally and redact before sharing.
LET’S BUILD
Confirm context, namespace and permission
Every panel pins the configured context explicitly. Check the server and namespace against your change record; a familiar Pod name is not sufficient. The public fields stay only in this browser tab and must never contain credentials.
Operator terminal; authorized lab context
kubectl config get-contexts 'lab'
kubectl --context='lab' get namespace 'academy-lab'
kubectl --context='lab' auth can-i get pods -n 'academy-lab'
kubectl --context='lab' -n 'academy-lab' get pod 'api-example' -o wideThe intended server/context and Pod appear; permission is yes. Stop on any mismatch.
LET’S BUILD
Capture container state before another restart
Read state and lastState for the selected name, not just the STATUS column. An exit code of 137 can arise from SIGKILL and alone does not prove the container limit caused an OOM. Look for OOMKilled plus limits, node evidence and the timeline. A restart can overwrite the single previous instance available through the log API.
Operator terminal; authorized lab context
kubectl --context='lab' -n 'academy-lab' get pod 'api-example' -o jsonpath='{range .status.containerStatuses[*]}{.name}{"\nstate="}{.state}{"\nlastState="}{.lastState}{"\nrestarts="}{.restartCount}{"\n\n"}{end}'
kubectl --context='lab' -n 'academy-lab' describe pod 'api-example'
kubectl --context='lab' -n 'academy-lab' get pod 'api-example' -o jsonpath='{range .status.initContainerStatuses[*]}{.name}{"\nstate="}{.state}{"\nlastState="}{.lastState}{"\nrestarts="}{.restartCount}{"\n"}{end}'Identify the selected container, reason, exit code, started/finished times and relevant events.
LET’S BUILD
Compare current and previous logs
Retrieve a bounded timestamped tail. --previous requests the previous terminated container instance, not all historical logs. If it is unavailable, use the authorized central log store; do not infer that no error occurred. Correlate the final error with termination time and rollout timing.
Operator terminal; authorized lab context
kubectl --context='lab' -n 'academy-lab' logs 'api-example' -c 'app' --previous --timestamps --tail=200
kubectl --context='lab' -n 'academy-lab' logs 'api-example' -c 'app' --timestamps --tail=200Separate an application startup/exception failure from a process killed without its own shutdown message.