Skip to main content
RunBook Academy

KubernetesVI · kubectl for Administratorskubectl for administrators

kubectl get, describe, and explain — read-only triage

Intermediate⏱ ~16 minkubectl

What you'll learn

  • Use kubectl get to list and inspect objects with the right output format
  • Use kubectl describe to read object details and recent events
  • Use kubectl explain to discover schema fields without documentation
  • Combine label and field selectors to find specific objects in a cluster

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

Read-only kubectl commands are the operator’s stethoscope. get lists or reads, describe shows details and recent events, explain walks the schema. They make no API server writes, so they are always safe to run — even against production, even during an incident, even with the wrong context. This lesson is the production triage workflow built from these three commands.

kubectl get — list and inspect

get reads one or more objects and prints them. The verb maps to GET on the API server; nothing is written.

kubectl get pods                              # all Pods in current namespace
kubectl get pods -A                           # all Pods in all namespaces
kubectl get pods -n kube-system               # specific namespace
kubectl get pod web-7c8                       # one Pod (kind is singular)
kubectl get deploy,svc                        # multiple kinds, comma-separated
kubectl get all                               # common kinds (not all kinds)

The default output format is human-readable columns. Other formats:

kubectl get pods -o yaml                      # full object, YAML
kubectl get pods -o json                      # full object, JSON
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase
kubectl get pods -o wide                      # add extra columns (IP, node)
kubectl get pods -o name                      # just names, one per line

kubectl get all is a common shortcut but it is not all kinds. It covers Pods, Services, Deployments, ReplicaSets, StatefulSets, DaemonSets, Jobs, CronJobs, and a few others. It does not include ConfigMap, Secret, PersistentVolumeClaim, ServiceAccount, NetworkPolicy, Ingress, ResourceQuota, etc. For those, name the kind explicitly.

Label and field selectors

The two most useful flags on get are -l (label selector) and --field-selector. They cut through noise and make scripts possible.

kubectl get pods -l app=web                   # label selector
kubectl get pods -l 'app in (web,api)'        # set-based selector
kubectl get pods -l '!app'                    # pods with no app label
kubectl get pods --field-selector=status.phase=Running
kubectl get pods --field-selector=spec.nodeName=node-3
kubectl get pods -l app=web --field-selector=status.phase=Pending

Label selectors require labels to exist on the objects. Field selectors are limited to a small set of indexed fields per kind (metadata.name, metadata.namespace, status.phase for Pods; spec.nodeName for Pods; status.phase for PVCs). Attempting a field selector that is not indexed returns an error.

Names with -o name

For shell composition, -o name (or -o jsonpath='{.items[*].metadata.name}') prints object names, one per line, no header. This is what makes kubectl delete, kubectl logs, and kubectl exec composable:

kubectl get pods -l app=web -o name | xargs -I {} kubectl logs {}

kubectl describe — events and details

describe reads an object (singular) and prints its spec, status, and recent events. It does not have a list mode.

kubectl describe pod web-7c8
kubectl describe node node-3
kubectl describe svc web
kubectl describe deployment web -n team-a-prod

describe is the right command for why is this not working. It surfaces:

  • The full spec (what the operator asked for)
  • The full status (what the controller sees)
  • Conditions (Ready, Initialized, ContainersReady, etc.)
  • Recent Events for this object — the controller’s log of what it tried, in what order, and what failed.
flowchart LR
    Spec[spec] --> D[describe output]
    Status[status] --> D
    Conditions[conditions] --> D
    Events[events] --> D
    Events --> E[Warning: BackOff, FailedScheduling, ...]

The events section is the heart of triage. The most useful event types:

EventMeaning
ScheduledScheduler bound Pod to a node
Pullingkubelet started pulling the image
PulledImage pull succeeded
CreatedContainer created in the runtime
StartedContainer entered Running
KillingContainer is being terminated
BackOffContainer crashed; backoff timer running
FailedSynckubelet failed to sync Pod state
FailedSchedulingNo node could fit the Pod
FailedMountVolume mount failed
UnhealthyLiveness/readiness probe failed

kubectl explain — discover the schema

explain walks the OpenAPI schema. It is the fastest way to discover a field you don’t know:

kubectl explain pod
kubectl explain pod.spec
kubectl explain pod.spec.containers
kubectl explain pod.spec.containers.resources

Output:

RESOURCE: resources <Object>
DESCRIPTION:
    Resources defines the compute resource requirements and limits.
    More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

FIELDS:
  claims    <[]Object>
    Claims lists the names of resources, defined in spec.resourceClaims,
    that are used by this container.
    ...
  limits    <map[string]Quantity>
    Limits describes the maximum amount of compute resources allowed.
    More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
  requests  <map[string]Quantity>
    Requests describes the minimum amount of compute resources required.

explain walks fields by name with a dot. To see ALL subfields recursively, use --recursive:

kubectl explain pod.spec --recursive | less

This is the offline equivalent of grepping the OpenAPI schema at /openapi/v2 or /openapi/v3. Production discipline says “check the schema before guessing” — explain is faster than the docs.

A triage workflow

The three commands together answer the four triage questions every incident produces:

  1. What is the system doing right now?kubectl get pods -A -o wide. List every Pod, its phase, its node, its IP.
  2. What does the controller see on this object?kubectl describe pod web-7c8. Conditions, recent events.
  3. What does the spec actually say?kubectl get pod web-7c8 -o yaml. The full object as stored.
  4. What is the field name I forgot?kubectl explain pod.spec.containers.resources.
flowchart TD
    Q1{What is happening?} --> A1[kubectl get -A -o wide]
    Q2{Why is this Pod broken?} --> A2[kubectl describe]
    Q3{What does the object actually look like?} --> A3[kubectl get -o yaml]
    Q4{What is the field name?} --> A4[kubectl explain]

The four commands map directly to the questions. They are all read-only and safe to chain.

Cross-course references

  • The Linux course part XXII-Linux-NetTroubleshoot covers read-only triage commands (ss, ip, tcpdump); the kubectl read commands are the cluster-level equivalent.
  • The Observability course part LXIX-Observability-LongTermStorage covers exporter triage; kubectl describe events is a built-in equivalent for cluster-internal signals.
  • The Docker course part XXIX-Docker-Build covers docker inspect; kubectl describe is the same idea for Kubernetes objects, with the addition of an events section.

Quiz

Knowledge check · 4 questions

  1. Q1. Which command lists every resource type in a namespace, including ConfigMap and Secret?

  2. Q2. `kubectl describe pod web-7c8` includes a section called Events that lists only events for which this specific Pod is the involvedObject.

  3. Q3. A Pod is stuck in `Pending` for ten minutes. Walk through the read-only triage commands and what each one tells you.

    Pod `web-7c8` was applied by `kubectl apply -f deployment.yaml`. It has been Pending for 10 minutes. The Deployment is a 3-replica Deployment; the other two replicas are Running. The image referenced in the Pod spec is `registry.example.com/web:v1.2.3`. The cluster has three worker nodes.

  4. Q4. Name three output formats for `kubectl get` and one situation where each is the right choice.

Passing score: 75%. Answers are checked in this browser.

Production discipline

  • Start triage with get, not describe. get -A -o wide shows the system state immediately; describe is per-object and slower when there is no hypothesis yet.
  • Use -l and --field-selector early. They cut the LIST request to what you need and reduce cache pressure on the client.
  • Trust describe events over stdout reasoning. When something is not working, the events section is what the controller logged about it. Do not guess.
  • Use explain instead of the docs when the field name is the question. kubectl explain pod.spec.containers.resources is faster than searching documentation, and the description is the same text the OpenAPI schema returns.
  • Save triage output. kubectl get pod web-7c8 -o yaml > /tmp/web-7c8.yaml is the difference between a postmortem with evidence and one with memory.