Overview
The kubectl describe command is used to inspect K8s resources in detail, describe command provides detailed information while get commands provides a summarized output. It aggregates information from multiple source to give a comprehensive snapshot of a resource’s lifecycle including resource configuration, status, events, dependencies and more. This command is particularly useful for debugging and troubleshooting as it highlights why a resource may not be functioning as expected.
Main Sources for Aggregating Information
When you kubectl describe, Kubernetes API server dynamically queries 3 distinct data sources to build your output:
Sources:
etcddatabase via API server.kubeletprocess running on the active worker node.- The Kubernetesd
Eventresource database.
- The Desired State (
etcd)
- Pulls the information about the container images, environment variables, storage volume, definitions, resource requests/limits, and node selectors.
- The Current Live Status
- Pulls the information about real-time diagnostics straight from the container runtime engine such as
containerd. - Outputs
- Current status such
running,waiting,terminated,pending… - IP address allocated to the pod
- Last State & Exit Code
- Total Restart Counts
- Current status such
- The Cluster Event Log
- Pulls information on a completely separate stream of time-stamped cluster actions related to that specific pod.
- The Events section at the very bottom, it tells chronological story of the resource. Example: Successfully Pulling Image -> Created Container -> Started Container -> Unhealthy -> Killing Container
Output Details
The output of kubectl describe typically includes:
Metadata: name, namespace, labels, annotationsSpec: resource config, container images, ports, and environment variablesStatus and Conditions: readiness, phase, and QoS classVolumes: mounted storage and persistent volume claimsEvents: lifecycle events such scheduling, image pulling, and error likeImagePullBackOfforErrImagePull
How to Use
Print a detailed description of the resource, you may select a singly object by
- name,
- type,
- name prefix,
- label selector, and more.
kubectl describe TYPE NAME_PREFIX
Common Usage
# describe a pod
kubectl describe pod uptime-kuma-deployment-7c78854f7d-vbfm5
# describe a node
kubectl describe node k3s-agent
# describe all nodes
kubectl describe nodes
# descibe all pods
kubectl describe pods
# describe pods by label
kubectl describe pods -l name=LABEL_NAME
Best Practices
- Use
kubectl describeas first step in troubleshooting before diving into logs. - Combine with label selectors to filter efficiently.
- For large clusters, consider chunked output to avoid overwhelming the terminal.
--chunk-size int(default: 500) - Remember that namespace context is ignored if listing across all namespaces with
-Aor--all-namespaces.
Example
kubectl get pods -o wide
Sample Pods List:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
bazarr-deployment-76b9585465-29jp2 1/1 Running 0 15h 10.42.3.20 k3s-agent-debian-laptop <none> <none>
filebrowser-deployment-6cb698b868-vrphs 1/1 Running 0 15h 10.42.3.16 k3s-agent-debian-laptop <none> <none>
forgejo-deployment-5f585676d-h5snf 1/1 Running 2 (155m ago) 4d20h 10.42.2.18 k3s-server <none> <none>
grafana-deployment-699fdbc48d-2kcv6 1/1 Running 2 (155m ago) 7d18h 10.42.2.7 k3s-server <none> <none>
jellyfin-deployment-64f97df8cb-b68k4 1/1 Running 1 (155m ago) 3d22h 10.42.2.19 k3s-server <none> <none>
prowlarr-deployment-7c5f76dd7f-2kqhp 1/1 Running 0 15h 10.42.3.19 k3s-agent-debian-laptop <none> <none>
radarr-deployment-8566c6c7b6-m5w97 1/1 Running 0 15h 10.42.3.21 k3s-agent-debian-laptop <none> <none>
semaphore-deployment-97cc8965f-c7pn8 1/1 Running 2 (155m ago) 7d19h 10.42.2.3 k3s-server <none> <none>
sonarr-deployment-769bb45458-8bvwz 1/1 Running 0 15h 10.42.3.18 k3s-agent-debian-laptop <none> <none>
transmission-deployment-554fdbcf5d-hr222 1/1 Running 0 15h 10.42.3.17 k3s-agent-debian-laptop <none> <none>
trilium-deployment-75c7ff4655-dhd42 1/1 Running 2 (155m ago) 7d19h 10.42.2.9 k3s-server <none> <none>
uptime-kuma-deployment-7c78854f7d-vbfm5 1/1 Running 2 (155m ago) 7d19h 10.42.2.4 k3s-server <none> <none>
Looking closely at pods list, there is a very obvious clue here:
- Forgejo,
- Grafana,
- Trilinium,
- Uptime Kuma,
all restarted exactly 153 minutes ago. Because they all restarted at the exact same time while your other pods stayed online. This is the absolute perfect scenario to use kubectl describe.
To inspect the pods that recently restarted, you provide the resource type pod followed by the exact name:
# Investigate the Grafana restart
kubectl describe pod grafana-deployment-699fdbc48d-2kcv6
Output:
kubectl describe pod grafana-deployment-699fdbc48d-2kcv6
Name: grafana-deployment-699fdbc48d-2kcv6
Namespace: default
Priority: 0
Service Account: default
Node: k3s-server/192.168.31.11
Start Time: Wed, 01 Jul 2026 18:57:19 +0530
Labels: app=grafana
pod-template-hash=699fdbc48d
Annotations: kubectl.kubernetes.io/restartedAt: 2026-07-01T18:47:44+05:30
Status: Running
IP: 10.42.2.7
IPs:
IP: 10.42.2.7
Controlled By: ReplicaSet/grafana-deployment-699fdbc48d
Containers:
grafana:
Container ID: containerd://27bb751597488860d091f054053059351f53d29e0442006ee421d2d9cdfe3bfa
Image: grafana/grafana-enterprise:latest
Image ID: docker.io/grafana/grafana-enterprise@sha256:68a7ee3dc2c726e54b2be3533a9e1ac6baaed0893334947a6378520de28a6a76
Port: 3000/TCP (grafana-port)
Host Port: 0/TCP (grafana-port)
State: Running
Started: Thu, 09 Jul 2026 11:09:26 +0530
Last State: Terminated
Reason: Unknown
Exit Code: 255
Started: Sun, 05 Jul 2026 14:55:37 +0530
Finished: Thu, 09 Jul 2026 11:08:48 +0530
Ready: True
Restart Count: 2
Environment: <none>
Mounts:
/var/lib/grafana from grafana-storage (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-bb9w6 (ro)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
grafana-storage:
Type: HostPath (bare host directory volume)
Path: /grafana/data
HostPathType: Directory
kube-api-access-bb9w6:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
Optional: false
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: hardware-type=heavy-compute
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
- Exit Code 255:
Look closely at the
Containers:block underLast State::
Last State: Terminated
Reason: Unknown
Exit Code: 255
Started: Sun, 05 Jul 2026 14:55:37 +0530
Finished: Thu, 09 Jul 2026 11:08:48 +0530
- The Timeline: The container ran smoothly for 4 days straight (from July 5th to July 9th) until it abruptly died at exactly 11:08:48 AM today. It was successfully brought back up by K3s less than a minute later at 11:09:26 AM.
- What this means:
Exit Code 255is a catch-all meaning the main process inside the container abruptly stopped with an exit status out of range or the underlying service runtime cut it off without a specific signal.
- The Empty Event Log
Why is it empty? Kubernetes event logs only live in memory for 1 hour by default before they are wiped. Because the crash happened roughly 2.5 hours ago, the cluster-level event history for that exact crash window has already aged out.
Events have a limited retention time and triggers and messages may evolve with time. Event consumers should not rely on the timing of an event with a given Reason reflecting a consistent underlying trigger, or the continued existence of events with that Reason. Events should be treated as informative, best-effort, supplemental data.
What’s the Problem?: Well, in my case there has been power outage and it came back within a minute. I guess it explain why it stopped abruptly. When a container is gracefully stopped by Kubernetes, its receives a signal to shutdown cleanly and leaves an exit code like 0. Why my control plane lost power it didn’t have the time to clean up. That’s why the container lost its connection to the processes mid-execution. When the node booted back up, containerd looked at what happened right before the blackout, couldn’t find a clean exit signature, and flagged it as Exit Code: 255 with Reason: Unknown.
