Skip to content
Commitpedia
Log in Join & edit

Collect describe, events and logs of a failing Kubernetes pod

A bash script that saves a pod's status, describe output, events, YAML, current and previous logs of every container and its node details into one folder for troubleshooting.

Not checked by a trusted editor yet Last edited Outdated?

Edit history of Collect describe, events and logs of a failing Kubernetes pod: 1 recorded edit
Edit history · 1 edit
Type
Script
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Language
bash
Licence
CC0-1.0

What this changes

Creates a local folder (default debug-NAMESPACE-POD-TIMESTAMP, or -o DIR) with text files of the pod status, describe, events, YAML, logs and node details. It only reads from the cluster; nothing in Kubernetes is changed.

How to undo it

Delete the folder, e.g. rm -rf debug-shop-web-*. pod.yaml can hold plain environment values, so remove or redact it before sharing.

When a pod crashes, gets stuck or restarts, the evidence is spread over several commands, and some of it (events, previous logs) disappears after a while. This script grabs all of it in one go and writes each piece to its own file. It only reads from the cluster; it never changes or deletes anything.

The script

#!/usr/bin/env bash
set -euo pipefail

usage() {
  echo "Usage: $(basename "$0") POD [-n NAMESPACE] [-o OUTPUT_DIR] [-t TAIL_LINES]" >&2
  exit 2
}

[[ $# -ge 1 && $1 != -* ]] || usage
POD=$1
shift
NAMESPACE=$(kubectl config view --minify -o jsonpath='{..namespace}' 2>/dev/null || true)
NAMESPACE=${NAMESPACE:-default}
OUT=""
TAIL=500

while getopts ":n:o:t:" opt; do
  case $opt in
    n) NAMESPACE=$OPTARG ;;
    o) OUT=$OPTARG ;;
    t) TAIL=$OPTARG ;;
    *) usage ;;
  esac
done

command -v kubectl >/dev/null || { echo "kubectl not found" >&2; exit 1; }
kubectl get pod "$POD" -n "$NAMESPACE" >/dev/null || exit 1

OUT=${OUT:-"debug-${NAMESPACE}-${POD}-$(date +%Y%m%d-%H%M%S)"}
mkdir -p "$OUT"
echo "Collecting pod $NAMESPACE/$POD into $OUT"

run() {
  local file=$1
  shift
  if "$@" >"$OUT/$file" 2>&1; then
    echo "  ok    $file"
  else
    echo "  empty $file (command failed, see file)"
  fi
}

run status.txt kubectl get pod "$POD" -n "$NAMESPACE" -o wide
run describe.txt kubectl describe pod "$POD" -n "$NAMESPACE"
run events.txt kubectl events -n "$NAMESPACE" --for "pod/$POD"
run pod.yaml kubectl get pod "$POD" -n "$NAMESPACE" -o yaml

CONTAINERS=$(kubectl get pod "$POD" -n "$NAMESPACE" \
  -o jsonpath='{.spec.initContainers[*].name} {.spec.containers[*].name}')

for c in $CONTAINERS; do
  run "logs-$c.txt" kubectl logs "$POD" -n "$NAMESPACE" -c "$c" --tail="$TAIL" --timestamps
  run "logs-$c-previous.txt" kubectl logs "$POD" -n "$NAMESPACE" -c "$c" --tail="$TAIL" --timestamps --previous
done

NODE=$(kubectl get pod "$POD" -n "$NAMESPACE" -o jsonpath='{.spec.nodeName}')
if [[ -n "$NODE" ]]; then
  run node-describe.txt kubectl describe node "$NODE"
else
  echo "  note  pod has no node yet (Pending); check events.txt for scheduler messages"
fi

echo
echo "Container states:"
kubectl get pod "$POD" -n "$NAMESPACE" -o jsonpath='{range .status.containerStatuses[*]}{.name}{"\t"}{.state}{"\tlastState="}{.lastState}{"\trestarts="}{.restartCount}{"\n"}{end}'
echo
echo "Done. Review the files in $OUT before sharing them: pod.yaml can contain plain environment values."

Usage

chmod +x k8s-pod-debug.sh
./k8s-pod-debug.sh web-7d9c5b8f6-x2kqp -n shop
./k8s-pod-debug.sh web-7d9c5b8f6-x2kqp -n shop -o /tmp/case-123 -t 2000

What you get

  • describe.txt: container states, last termination reason and exit code, probe settings, and recent events. Usually the fastest way to the cause.
  • events.txt: events for this pod only. The API server keeps events only for a limited time, so collect them early.
  • logs-<container>-previous.txt: output of the last crashed instance. For CrashLoopBackOff this is the file that matters, because the current container may not have printed anything yet.
  • node-describe.txt: node conditions (MemoryPressure, DiskPressure) and allocated resources, useful for evictions and OOM kills.

Notes

  • It needs kubectl events, which recent kubectl versions include. On an old client, replace that line with kubectl get events -n NS --field-selector involvedObject.name=POD.
  • A missing -previous log is normal for a container that has not restarted.
  • You need RBAC permission to get pods, pods/log, events and nodes. Without node access, that one file will contain a Forbidden error and the rest still works.
  • Review the output before attaching it to a ticket: pod.yaml shows environment values written directly in the spec, and logs may contain personal data.

Official documentation

See also

  • 0140 kubectl cheat sheet: the commands you use every day A compact reference of everyday kubectl commands: contexts and namespaces, listing and inspecting objects, logs and exec, applying changes, rollouts, scaling and… Beginner · Reference · Any system Article Concepts · Troubleshooting 15 Oct 2026
  • 0141 List Kubernetes pods that are not Running and Ready A bash script that lists every pod across namespaces that is Pending, failing or running but not ready, with the waiting reason,… Intermediate · Reference · Linux, macOS Script Troubleshooting 15 Oct 2026
  • 0142 Fix: ImagePullBackOff and ErrImagePull in Kubernetes The pod cannot start because the node failed to pull the container image. Read the "Failed to pull image" event to see… Intermediate · Fix · Linux Article Troubleshooting 15 Oct 2026
  • 0143 Fix: CrashLoopBackOff in Kubernetes The container starts, exits, and Kubernetes waits longer before each restart. Read the previous container's logs and its exit code to find… Intermediate · Fix · Linux Article Troubleshooting 15 Oct 2026
  • 0144 Fix: Pod stuck in Pending with “0/3 nodes are available: Insufficient cpu” The scheduler cannot find a node with enough unreserved CPU for the pod's request. Compare the request with node allocatable resources, then… Advanced · Fix · Linux Article Troubleshooting · Workloads & services 15 Oct 2026
  • 0145 Fix: OOMKilled (exit code 137) in Kubernetes A container used more memory than its limit and the kernel killed it. Confirm the reason, measure real usage, then raise the… Advanced · Fix · Linux Article Troubleshooting · Workloads & services 15 Oct 2026

Repos in the wild

  • derailed/k9s derailed/k9s K9s is a terminal UI for Kubernetes that lets you browse resources, read logs, open shells and follow cluster changes from the keyboard. GitHub

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. Commitpedia +4,377 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?